DIRECTORY CD, CDSimpleRules, CMosB, CoreCreate, CoreOps, CoreProperties, CoreGeometry, EU2LeafUtils, EU2Regs, EU2Utils, LayoutCheckpoint, PWCore, PWCoreRoute, PWObjects, Rope; EU2RegsImpl: CEDAR PROGRAM IMPORTS CD, CDSimpleRules, CMosB, CoreCreate, CoreOps, CoreProperties, CoreGeometry, EU2LeafUtils, EU2Utils, LayoutCheckpoint, PWCore, PWCoreRoute, PWObjects, Rope EXPORTS EU2Regs = BEGIN OPEN CoreCreate, EU2LeafUtils, EU2Regs, EU2Utils; l: INT = CMosB.cmosB.lambda; dpPitch: INT = 140*l; ConnectedBuses: PROC [reg: PipeRange] RETURNS [buses: Wire] ~ { dReadBusPresent: BOOL _ FALSE; names: LIST OF WR _ NIL; name: ROPE; FOR i: NAT IN [0..sources[reg].sizeSel) DO input: SourceRange _ sources[reg].inputs[i]; name _ sources[input].name; -- name of one input IF Rope.Equal[name, dReadBus] THEN dReadBusPresent _ TRUE; names _ CONS[sources[input].name, names]; ENDLOOP; name _ sources[reg].name; -- name of the output of the source names _ CONS[name, names]; IF Rope.Equal[name, dReadBus] THEN dReadBusPresent _ TRUE; IF ~dReadBusPresent THEN names _ CONS[dReadBus, names]; buses _ WireList[names]; }; CreateBuses: PROC [reg: PipeRange, leftCT: CellType, horizontalWire: Wire] RETURNS [cellType: CellType] ~ { public: Wire _ CoreOps.CopyWire[Union[AllBuses[reg], horizontalWire]]; -- do not forget the copy wire! (otherwise, wires are shared and that might result in 815!!!) cellType _ Cell[ name: "CreateBuses", public: public, instances: NIL ]; PWCore.SetLayout[cellType, $CreateBusesLayout, $LeftCellType, leftCT]; CoreProperties.PutCellTypeProp[cellType, $Reg, NEW[NAT _ reg]]; }; FindBusPosX: PROC [name: ROPE] RETURNS [INT] ~ { FOR i: SourceRange IN SourceRange DO IF sources[i].name=name THEN RETURN[(sources[i].trackPosX*8+2)*CMosB.lambda]; ENDLOOP; ERROR; -- who the hell is this bus??? }; IsTopBus: PROC [name: ROPE, reg: NAT] RETURNS [BOOL _ FALSE] ~ { FOR l: Buses _ sources[reg].topOnlyBuses, l.rest WHILE l#NIL DO IF Rope.Equal[sources[l.first].name, name] THEN RETURN [TRUE]; ENDLOOP; }; IsBotBus: PROC [name: ROPE, reg: NAT] RETURNS [BOOL _ FALSE] ~ { FOR l: Buses _ sources[reg].botOnlyBuses, l.rest WHILE l#NIL DO IF Rope.Equal[sources[l.first].name, name] THEN RETURN [TRUE]; ENDLOOP; }; IsVBus: PROC [name: ROPE, reg: NAT] RETURNS [BOOL _ FALSE] ~ { FOR l: Buses _ sources[reg].throughBuses, l.rest WHILE l#NIL DO IF Rope.Equal[sources[l.first].name, name] THEN RETURN [TRUE]; ENDLOOP; FOR l: Buses _ sources[reg].topOnlyBuses, l.rest WHILE l#NIL DO IF Rope.Equal[sources[l.first].name, name] THEN RETURN [TRUE]; ENDLOOP; FOR l: Buses _ sources[reg].botOnlyBuses, l.rest WHILE l#NIL DO IF Rope.Equal[sources[l.first].name, name] THEN RETURN [TRUE]; ENDLOOP; }; CreateBusesLayout: PWCore.LayoutProc = { DrawNet: PROC [wire: Wire] ~ { geometry: LIST OF PWObjects.PlacedObject _ NIL; name: ROPE _ CoreOps.GetFullWireName[cellType.public, wire]; leftWire: Wire _ CoreCreate.FindWire[leftCT.public, name]; SELECT TRUE FROM leftWire=NIL => geometry _ LIST [ [CDSimpleRules.Rect[[4*l, sizeY], CMosB.met2], [FindBusPosX[name], 0]]]; NOT IsVBus[name, reg] => { DrawHoriz: CoreGeometry.EachPinProc = { IF side=right AND layer=CMosB.met THEN geometry _ CONS [ [CDSimpleRules.Rect[[sizeX, max-min], CMosB.met], [0, min]], geometry]; }; [] _ CoreGeometry.EnumerateSides[PWCore.extractMode.decoration, leftCT, leftWire, DrawHoriz]; }; ENDCASE => { DrawContact: CoreGeometry.EachPinProc = { IF side#right THEN RETURN; IF layer#CMosB.met THEN RETURN; geometry _ CONS [ [CDSimpleRules.Rect[[posX, max-min], CMosB.met], [0, min]], geometry]; geometry _ CONS [ [CDSimpleRules.Contact[CMosB.met, CMosB.met2], [posX, min]], geometry]; y1 _ MIN [y1, min]; y2 _ MAX [y2, max]; }; posX: INT _ FindBusPosX[name]; y1: INT _ IF IsTopBus[name, reg] THEN LAST[INT] ELSE 0; y2: INT _ IF IsBotBus[name, reg] THEN FIRST[INT] ELSE sizeY; [] _ CoreGeometry.EnumerateSides[PWCore.extractMode.decoration, leftCT, leftWire, DrawContact]; geometry _ CONS [ [CDSimpleRules.Rect[[4*l, y2-y1], CMosB.met2], [posX, y1]], geometry]; }; nodes _ CONS [PWObjects.CreateNode[geometry, LIST [[key: $InstanceName, val: name]]], nodes]; }; leftCT: CellType _ NARROW [CoreProperties.GetCellTypeProp[cellType, $LeftCellType]]; leftSize: CD.Position _ CD.InterestSize[PWCore.Layout[leftCT]]; sizeX: INT _ dpPitch-leftSize.x; sizeY: INT _ leftSize.y; reg: NAT _ NARROW [CoreProperties.GetCellTypeProp[cellType, $Reg], REF NAT]^; nodes: LIST OF PWObjects.Node _ NIL; CoreOps.VisitRootAtomics[cellType.public, DrawNet]; obj _ PWObjects.CreateRouting[[0, 0, sizeX, sizeY], nodes]; }; CreateRegAndMuxOnly: PROC [reg: PipeRange] RETURNS [cellType: CellType] ~ { -- The select lines, i.e. selLeftSrc[0..3), and all public of reg, except "in" sel: Wire _ Seq["sel", sources[reg].sizeSel+2]; mux: CellType _ Extract["RegMux.sch"]; -- Vdd, Gnd, sel, muxIn, muxOut instances: LIST OF CellInstance _ NIL; muxOut: Wire _ CoreOps.CreateWire[name: "muxOut"]; FOR i: NAT IN [0..sources[reg].sizeSel) DO instances _ CONS[ Instance[mux, ["sel", Index[sel, i]], ["muxIn", sources[sources[reg].inputs[i]].name], ["muxOut", muxOut]], instances]; ENDLOOP; instances _ CONS[ -- sel[max] = write cBus Instance[mux, ["sel", sel[sources[reg].sizeSel]], ["muxIn", dReadBus], ["muxOut", muxOut]], instances]; instances _ CONS[ Instance[Extract["Register.sch"], -- Vdd, Gnd, in, out, dRead, dOut ["in", muxOut], ["out", sources[reg].name], ["dRead", Index[sel, sources[reg].sizeSel+1]], ["dOut", dReadBus] ], instances]; cellType _ Cell[ name: "RegAndMuxOnly", public: Union[ConnectedBuses[reg], Wires[sel, "Vdd", "Gnd"]], onlyInternal: Wires[muxOut], instances: instances ]; PWCore.SetAbutY[cellType]; }; CreateRegCell: PROC [reg: PipeRange] RETURNS [cellType: CellType] ~ { sel: Wire _ Seq["sel", sources[reg].sizeSel+2]; regAndMuxOnly: CellType _ CreateRegAndMuxOnly[reg]; cellType _ Cell[ name: "Reg", public: Union[AllBuses[reg], Wires[sel, "Vdd", "Gnd"]], instances: LIST[ Instance[regAndMuxOnly], Instance[CreateBuses[reg, regAndMuxOnly, Wires[sel]]]] ]; PWCore.SetAbutX[cellType]; }; CreateReg: PUBLIC PROC [reg: PipeRange] RETURNS [cellType: CellType] = { buses: Wire _ AllBuses[reg]; cellType _ SequenceCell[ name: "RegWithMux", baseCell: CreateRegCell[reg], count: wordSize, sequencePorts: buses]; PWCore.SetArrayX[cellType]; }; CreatePDriver: PUBLIC PROC RETURNS [cellType: CellType] = { cellType _ SequenceCell[ name: "PDriver", baseCell: Extract["PDriver.sch"], count: wordSize, sequencePorts: Wires["r2B", "st3A", "cBus", "pDriver"]]; PWCore.SetArrayX[cellType]; }; CreateCBusDriver: PUBLIC PROC RETURNS [cellType: CellType] = { cellType _ SequenceCell[ name: "CBusDriver", baseCell: Extract["cBusDriver.sch"], count: wordSize, sequencePorts: Wires["r3B", "dataIn", "cBus", "pDriver"]]; PWCore.SetArrayX[cellType]; }; CreateShRegDriver: PUBLIC PROC RETURNS [cellType: CellType] = { cellType _ SequenceCell[ name: "shRegDriver", baseCell: Extract["shReg.sch"], count: wordSize, sequencePorts: Wires["out", "ramA", "ramB", "in", "cBus", "ifuIn"]]; PWCore.SetArrayX[cellType]; }; CreatekRegAndRight: PUBLIC PROC RETURNS [cellType: CellType] = { In: PROC [i: NAT] RETURNS [Wire] ~ {RETURN[inOut[i+1]]}; Out: PROC [i: NAT] RETURNS [Wire] ~ {RETURN[inOut[i]]}; Vdd: Wire _ CoreOps.CreateWire[name: "Vdd"]; Gnd: Wire _ CoreOps.CreateWire[name: "Gnd"]; ramA: Wire _ Bus["ramA"]; ramB: Wire _ Bus["ramB"]; cBus: Wire _ Bus["cBus"]; ifuIn: Wire _ Bus["ifuIn"]; kReg: Wire _ Bus["kReg"]; selKReg: Wire _ GenRegSelWire[EU2Utils.kReg]; shiftA: Wire _ CoreOps.CreateWire[name: "shiftA"]; shiftB: Wire _ CoreOps.CreateWire[name: "shiftB"]; read: Wire _ CoreOps.CreateWire[name: "read"]; write: Wire _ CoreOps.CreateWire[name: "write"]; inOut: Wire _ Seq["inOut", 33]; shRegIn: Wire _ Seq["shRegIn", 32]; shRegOut: Wire _ Seq["shRegOut", 32]; public: Wire _ WireList[LIST[Vdd, Gnd, ramA, ramB, cBus, ifuIn, kReg, selKReg, shiftA, shiftB, read, write, In[31], Out[0]]]; -- notice the indexes !!! onlyInternal: Wire _ WireList[LIST[inOut, shRegIn, shRegOut]]; channelData: PWCoreRoute.ChannelData _ NEW[PWCoreRoute.ChannelDataRec _ [ inX: FALSE, bottomOrLeftWires: LIST[Vdd, Gnd, kReg], topOrRightWires: LIST[Vdd, Gnd, cBus, ifuIn, In[31], Out[0]], trunkLayer: "metal", branchLayer: "metal2", wireWidthProc: PWCoreRoute.GndAndVdd25Met2MinWidth ]]; [] _ CoreOps.SetShortWireName[In[31], "shIn"]; [] _ CoreOps.SetShortWireName[Out[0], "shOut"]; FOR i: NAT IN [0..32) DO shRegIn[i] _ In[i]; shRegOut[i] _ Out[i]; ENDLOOP; IF EU2Utils.usekRegAndRightCheckpoint THEN RETURN [LayoutCheckpoint.Retrieve["kRegAndRight"]]; cellType _ Cell[ name: "kRegAndRight", public: public, onlyInternal: onlyInternal, instances: LIST [ Instance[CreateShRegDriver[], ["in", shRegIn], ["out", shRegOut]], Instance[CreateReg[EU2Utils.kReg], ["sel", selKReg]] ] ]; PWCore.SetLayout[cellType, $Channel, $ChannelData, channelData]; }; [] _ PWCore.RegisterLayoutAtom[$CreateBusesLayout, CreateBusesLayout, PWCore.DecorateValue]; END. าEU2RegsImpl.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Louis Monier June 19, 1986 4:43:22 pm PDT Barth, April 22, 1986 12:27:26 pm PST Bertrand Serlet November 7, 1986 5:04:57 pm PST Should be changed whenever the pitch of the DataPath changes! -- All the buses used as input or output, including the bus for debugging (dReadBus) -- no bus is both an input and an output -- add the dReadBus if not yet present -- control line or contact on this bus, i.e. pins found on the right side of leftCT contact on this bus -- Assemble the reg, the muxes and the buses -- The inputs in EU2Utils.sources[reg].inputs are in the order, i.e. for left: sel[0]->ramA -- Instances: the register and all mux transistors -- Same as before, but with the routing on the right -- write from cBus (debugging only) is mapped onto sel[max+1] -- dRead is mapped onto sel[max+2] -- Just a replication of 32 register+mux -- Special guys -- To build the internal and public ส ฎ– "cedar" style˜codešœ™Kšœ ฯmœ1™Kšžœ˜—K˜—šกœžœžœžœžœžœžœ˜@šžœ.žœžœž˜?Kšžœ)žœžœžœ˜>Kšžœ˜—K˜—šกœžœžœžœžœžœžœ˜>šžœ.žœžœž˜?Kšžœ)žœžœžœ˜>Kšžœ˜—šžœ.žœžœž˜?Kšžœ)žœžœžœ˜>Kšžœ˜—šžœ.žœžœž˜?Kšžœ)žœžœžœ˜>Kšžœ˜—K˜—šกœ˜(šกœžœ˜Kšœ žœžœžœ˜/Kšœžœ2˜šœ˜Kšœ˜Kšœ$˜$Kšœ˜Kšœ:˜:—Jšœ˜Kšœ˜—šกœžœžœžœ˜?šœ˜Kšœ˜Kšœ˜Kšœ˜KšœD˜D—Jšœ˜Kšœ˜—K˜šกœžœžœžœ˜@Kš กœžœžœžœ žœ˜8Kš กœžœžœžœ žœ ˜7K™#Kšœ,˜,Kšœ,˜,Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ-˜-Kšœ2˜2Kšœ2˜2Kšœ.˜.Kšœ0˜0Kšœ˜Kšœ#˜#Kšœ%˜%K˜Kšœžœbข˜—Kšœžœ˜>šœ'žœ˜IKšœžœ˜ Jšœžœ˜(Jšœžœ(˜=Jšœ˜Jšœ˜Jšœ2˜2J˜—Kšœ.˜.Kšœ/˜/K˜Kš žœžœžœ žœ+žœ˜KK˜Kšžœ$žœžœ-˜^K˜šœ˜Kšœ˜Kšœ˜Kšœ˜šœ žœ˜KšœB˜BKšœ4˜4Kšœ˜—K˜—Kšœ@˜@Kšœ˜K˜—šœ\˜\K˜——šžœ˜K˜—K˜K˜K˜K˜K˜—…—#1