DIRECTORY CD, CDCells, CDSimpleRules, CDSymbolicObjects, CMosB, CoreCreate, CoreOps, CoreProperties, EU2LeafUtils, EU2Regs, EU2Utils, LayoutCheckpoint, PW, PWCore, PWCoreRoute, Rope; EU2RegsImpl: CEDAR PROGRAM IMPORTS CD, CDCells, CDSimpleRules, CDSymbolicObjects, CMosB, CoreCreate, CoreOps, CoreProperties, EU2LeafUtils, EU2Utils, LayoutCheckpoint, PW, PWCore, PWCoreRoute, Rope EXPORTS EU2Regs = BEGIN OPEN CoreCreate, EU2LeafUtils, EU2Regs, EU2Utils; 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] ~ { leftWire: Wire; shortName: ROPE _ CoreOps.GetFullWireName[cellType.public, wire]; leftWire _ CoreCreate.FindWire[leftCT.public, shortName]; IF leftWire=NIL THEN { -- vertical through bus, no contact posX: INT _ FindBusPosX[shortName]; inst: CD.Instance _ PW.IncludeInCell[obj, CDSymbolicObjects.CreatePin[[4*CMosB.lambda, sizeY]], [posX, 0]]; CDSymbolicObjects.SetName[inst, shortName]; CDSymbolicObjects.SetLayer[inst, CMosB.met2]; [] _ PW.IncludeInCell[obj, CDSimpleRules.Rect[[4*CMosB.lambda, sizeY], CMosB.met2], [posX, 0]]; RETURN}; IF ~IsVBus[shortName, reg] THEN { -- control line DrawHoriz: PWCore.EachPinProc = { inst: CD.Instance; IF side#right THEN RETURN; IF layer#CMosB.met THEN RETURN; inst _ PW.IncludeInCell[obj, CDSymbolicObjects.CreatePin[[sizeX, max-min]], [0, min]]; CDSymbolicObjects.SetName[inst, shortName]; CDSymbolicObjects.SetLayer[inst, CMosB.met]; [] _ PW.IncludeInCell[obj, CDSimpleRules.Rect[[sizeX, max-min], CMosB.met], [0, min]]; }; [] _ PWCore.EnumeratePins[leftCT, leftWire, DrawHoriz]; RETURN; } ELSE { -- contact on this bus DrawContact: PWCore.EachPinProc = { inst: CD.Instance; IF side#right THEN RETURN; IF layer#CMosB.met THEN RETURN; inst _ PW.IncludeInCell[obj, CDSymbolicObjects.CreatePin[[posX, max-min]], [0, min]]; CDSymbolicObjects.SetName[inst, shortName]; CDSymbolicObjects.SetLayer[inst, CMosB.met]; [] _ PW.IncludeInCell[obj, CDSimpleRules.Rect[[posX, max-min], CMosB.met], [0, min]]; [] _ PW.IncludeInCell[obj, CDSimpleRules.Contact[CMosB.met, CMosB.met2], [posX, min]]; -- the contact y1 _ MIN[y1, min]; y2 _ MAX[y2, max]; }; y1, y2: INT; posX: INT _ FindBusPosX[shortName]; y1 _ IF IsTopBus[shortName, reg] THEN LAST[INT] ELSE 0; y2 _ IF IsBotBus[shortName, reg] THEN FIRST[INT] ELSE sizeY; [] _ PWCore.EnumeratePins[leftCT, leftWire, DrawContact]; [] _ PW.IncludeInCell[obj, CDSimpleRules.Rect[[4*CMosB.lambda, y2-y1], CMosB.met2], [posX, y1]]; }; }; leftCT: CellType _ NARROW[CoreProperties.GetCellTypeProp[cellType, $LeftCellType]]; leftSize: CD.Position _ CD.InterestSize[PWCore.Layout[leftCT]]; sizeX: INT _ 140*CMosB.lambda-leftSize.x; sizeY: INT _ leftSize.y; reg: NAT _ NARROW[CoreProperties.GetCellTypeProp[cellType, $Reg], REF NAT]^; obj _ PW.CreateEmptyCell[]; CoreOps.VisitAtomicWires[cellType.public, DrawNet]; CDCells.SetInterestRect[obj, [0, 0, sizeX, sizeY]]; PW.RepositionCell[obj]; }; 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.DecorateGet]; 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 May 12, 1986 0:47:30 am PDT -- 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 -- 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˜AKšœ9˜9šžœ žœžœ‘#˜:Kšœžœ˜#šœžœ žœ˜*Kšœ6˜6Kšœ ˜ —Kšœ+˜+Kšœ-˜-šœžœ˜Kšœ9˜9Kšœ ˜ —Kšžœ˜ —KšœS™Sšžœžœ‘˜1š  œ˜!Kšœžœ ˜Kšžœ žœžœ˜Kšžœžœžœ˜šœžœ˜Kšœ/˜/Kšœ ˜ —Kšœ+˜+Kšœ,˜,šœžœ˜Kšœ1˜1Kšœ ˜ —Kšœ˜—Kšœ7˜7Kšžœ˜Kšœ˜—šžœ‘˜š  œ˜#Kšœžœ ˜Kšžœ žœžœ˜Kšžœžœžœ˜šœžœ˜Kšœ.˜.Kšœ ˜ —Kšœ+˜+Kšœ,˜,šœžœ˜Kšœ0˜0Kšœ ˜ —šœžœ˜Kšœ.˜.Kšœ‘˜—Kšœžœ ˜Kšœžœ ˜Kšœ˜—Kšœžœ˜ Kšœžœ˜#Kš œžœžœžœžœžœ˜7Kš œžœžœžœžœžœ˜šœ˜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˜—šœZ˜ZK˜——šžœ˜K˜—K˜K˜K˜K˜K˜—…—%*3β