DIRECTORY CD, CDIO, CDViewer, CommandTool, Convert, Core, CoreCreate, CoreGeometry, CoreOps, GList, IO, PWCore, Rope, SCParms, Sinix, Sisyph, SCUtils, TerminalIO, TilingClass; SCUtilsImpl: CEDAR PROGRAM IMPORTS CDViewer, CommandTool, CDIO, Convert, CoreCreate, CoreGeometry, CoreOps, GList, IO, PWCore, Rope, SCParms, Sinix, Sisyph, TerminalIO, TilingClass EXPORTS SCUtils ~ BEGIN OPEN SCUtils; myLogicDesign: CD.Design _ NIL; myLayoutDesign: CD.Design _ NIL; workingDirectory: ROPE _ CommandTool.CurrentWorkingDirectory[]; Log2: PUBLIC PROC [n: INT] RETURNS [log: INT _ 0] ~ { WHILE n > 1 DO n _ n/2; log _ log+1 ENDLOOP }; ComRecord: PUBLIC PROC [pattern: ROPE, cx: Sisyph.Context, ctName: ROPE] RETURNS [ct: CellType] ~ { n: Names _ NIL; FOR i: INT DECREASING IN [0..Rope.Length[pattern]) DO SELECT Rope.Fetch[pattern, i] FROM '0 => n _ CONS["ComCell0.icon", n]; '1 => n _ CONS["ComCell1.icon", n]; 'X => n _ CONS["ComCellX.icon", n]; 'N => n _ CONS["ComCellN.icon", n]; 'E => n _ CONS["ComCellE.icon", n]; ENDCASE => ERROR; ENDLOOP; ct _ RecordX[n, cx, Rope.Cat[ctName, pattern]]; }; RecordX: PUBLIC PROC [obNames: Names, cx: Sisyph.Context, ctName: ROPE] RETURNS [ct: CellType] ~ { count: NAT _ GList.Length[obNames]; Index: TYPE = {ComCell0, ComCell1, ComCellX, ComCellN, ComCellE}; baseCTs: CellTypes _ NIL; public: Wire; -- public of cellType to be returned tileRow: TilingClass.TileRow _ NEW [TilingClass.TileRowRec[count]]; tileArray: TilingClass.TileArray _ NEW [TilingClass.TileArrayRec[1]]; publicElements, arrayedWires, leftSideOnlyWires, rightSideOnlyWires, globalWires: Wires _ NIL; EachWire: CoreOps.EachWireProc = { sides: CoreGeometry.Sides = WireSide[wire, baseCTs.first]; vertical: BOOL = sides[top] OR sides[bottom]; IF vertical AND (sides[right] OR sides[left]) THEN WireSideProblem[wire, "touches adjacent sides", baseCTs.first]; IF vertical THEN { newPublic: Wire _ CoreOps.CreateWires[count, CoreOps.GetShortWireName[wire]]; arrayedWires _ CONS[wire, arrayedWires]; FOR i: INT IN [0..count) DO newPublic[i] _ CoreOps.SetShortWireName[CoreOps.CopyWire[wire], NIL]; ENDLOOP; publicElements _ CONS[newPublic, publicElements]; } ELSE { IF sides=CoreGeometry.noSide THEN { IF IsGlobal[wire, cx] THEN { globalWires _ CONS [wire, globalWires]; publicElements _ CONS [wire, publicElements] } } ELSE { IF sides[left] THEN leftSideOnlyWires _ CONS[wire, leftSideOnlyWires]; IF sides[right] THEN rightSideOnlyWires _ CONS[wire, rightSideOnlyWires]; publicElements _ CONS [wire, publicElements] } } }; FOR l: Names _ obNames, l.rest WHILE l#NIL DO baseCTs _ CONS[Sisyph.ExtractSchematicByName[l.first, cx], baseCTs]; ENDLOOP; baseCTs _ NARROW[GList.Reverse[baseCTs]]; [] _ CoreOps.VisitWireSeq[baseCTs.first.public, EachWire]; public _ CoreOps.CreateWire[publicElements]; FOR i: INT IN [0..count) DO tileRow[i] _ NEW [TilingClass.TileRec _ [type: baseCTs.first]]; baseCTs _ baseCTs.rest; ENDLOOP; FOR wl: Wires _ leftSideOnlyWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; tileRow[0].renaming _ CONS[[wireName, wireName], tileRow[0].renaming]; ENDLOOP; FOR wl: Wires _ rightSideOnlyWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; tileRow[count-1].renaming _ CONS[[wireName, wireName], tileRow[count-1].renaming]; ENDLOOP; FOR wl: Wires _ globalWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; FOR i: NAT IN [0..count) DO tileRow[i].renaming _ CONS[[wireName, wireName], tileRow[i].renaming]; ENDLOOP; ENDLOOP; FOR wl: Wires _ arrayedWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; FOR i: NAT IN [0..count) DO tileRow[i].renaming _ CONS[[wireName, Rope.Cat[wireName, "[", Convert.RopeFromInt[i], "]"]], tileRow[i].renaming]; ENDLOOP; ENDLOOP; tileArray[0] _ tileRow; ct _ TilingClass.CreateTiling[CoreOps.CopyWire[public], tileArray, TilingClass.SchematicsNeighborX, TilingClass.SchematicsNeighborY, Rope.Cat[ctName, ".RecordX"]]; }; RamInterfaceRout: PUBLIC PROC [cx: Sisyph.Context] RETURNS [ct: CellType] ~ { Flip: TYPE ~ {normal, flipped}; BaseCells: TYPE ~ REF BaseCellsRep; BaseCellsRep: TYPE ~ RECORD [v: SEQUENCE size: NAT OF ARRAY Flip OF RECORD [ct: CellType, w: Wire]]; index, selIndex, spareIndex: INT; baseB: BaseCells _ NEW [BaseCellsRep[SCParms.numBytesPerWord]]; baseW: BaseCells _ NEW [BaseCellsRep[SCParms.numWordsPerLine]]; spacerB, spacerW: CellType; spare: Wire _ CoreCreate.Seq[size: SCParms.numBitsPerCycle, name: "Spare"]; byteSel: Wire _ CoreCreate.Seq[size: SCParms.numBytesPerWord, name: "ByteSel"]; bS: Wire _ CoreCreate.Seq[size: SCParms.numBitsPerLine, name: "BS"]; wordSel: Wire _ CoreCreate.Seq[size: SCParms.numWordsPerLine, name: "WdSel"]; wS: Wire _ CoreCreate.Seq[size: SCParms.numBitsPerLine, name: "WS"]; count: INT ~ SCParms.numBitsPerLine+SCParms.numBitsPerCycle; -- Including the spare lines tileRowB: TilingClass.TileRow _ NEW [TilingClass.TileRowRec[count]]; tileRowW: TilingClass.TileRow _ NEW [TilingClass.TileRowRec[count]]; tileArray: TilingClass.TileArray _ NEW [TilingClass.TileArrayRec[2]]; FOR i: NAT IN [0..SCParms.numBytesPerWord) DO name: ROPE = IO.PutFR["RamInterfaceBitRout2%g.sch", IO.int[i]]; bSName: ROPE = IO.PutFR["ByteSel[%g]", IO.int[i]]; baseB[i][normal].ct _ Sisyph.ExtractSchematicByName[name, Sisyph.Copy[cx]]; baseB[i][flipped].ct _ PWCore.RotateCellType[baseB[i][normal].ct, $FlipX]; FOR m: Flip IN Flip DO baseB[i][m].w _ CoreOps.FindWire[baseB[i][m].ct.public, bSName]; ENDLOOP; ENDLOOP; FOR word: NAT IN [0..SCParms.numWordsPerLine) DO name: ROPE = IO.PutFR["RamInterfaceBitRout1%g.sch", IO.int[word]]; wSName: ROPE = IO.PutFR["WdSel[%g]", IO.int[word]]; baseW[word][normal].ct _ Sisyph.ExtractSchematicByName[name, Sisyph.Copy[cx]]; baseW[word][flipped].ct _ PWCore.RotateCellType[baseW[word][normal].ct, $FlipX]; FOR m: Flip IN Flip DO baseW[word][m].w _ CoreOps.FindWire[baseW[word][m].ct.public, wSName]; ENDLOOP; ENDLOOP; spacerB _ Sisyph.ExtractSchematicByName["RamInterfaceSpacerRout2.sch", cx]; spacerW _ Sisyph.ExtractSchematicByName["RamInterfaceSpacerRout1.sch", cx]; index _ 0; -- index in the tilling class selIndex _ 0; -- index in the BS wire spareIndex _ 0; -- index in the Spare wire FOR i: INT IN [0..SCParms.numBytesPerWord) DO FOR j: INT IN [0..SCParms.numBitsPerByte) DO word: INT _ 0; FOR k: INT IN [0..SCParms.numWordsPerCycle) DO FOR l: INT IN [0..SCParms.numCyclesPerLine/2) DO FOR m: Flip IN Flip DO bS[selIndex] _ byteSel[i]; wS[selIndex] _ wordSel[word]; tileRowB[index] _ NEW [TilingClass.TileRec _ [ type: baseB[i][m].ct, renaming: LIST[ [public: "ByteSel", actual: byteSel], [public: baseB[i][m].w, actual: bS[selIndex]] ]]]; tileRowW[index] _ NEW [TilingClass.TileRec _ [ type: baseW[word][m].ct, renaming: LIST[ [public: "WdSel", actual: wordSel], [public: baseW[word][m].w, actual: wS[selIndex]] ]]]; selIndex _ selIndex+1; index _ index+1; word _ word+1; ENDLOOP; ENDLOOP; tileRowB[index] _ NEW [TilingClass.TileRec _ [ type: spacerB, renaming: LIST[ [public: "ByteSel", actual: byteSel], [public: "Spare", actual: spare[spareIndex]] ]]]; tileRowW[index] _ NEW [TilingClass.TileRec _ [ type: spacerW, renaming: LIST[ [public: "WdSel", actual: wordSel], [public: "Spare", actual: spare[spareIndex]] ]]]; spareIndex _ spareIndex +1; index _ index+1; ENDLOOP; IF word # SCParms.numWordsPerLine THEN ERROR; ENDLOOP; ENDLOOP; IF index # count THEN ERROR; IF selIndex # SCParms.numBitsPerLine THEN ERROR; IF spareIndex # SCParms.numBitsPerCycle THEN ERROR; tileArray[1] _ tileRowW; tileArray[0] _ tileRowB; ct _ TilingClass.CreateTiling[ public: CoreCreate.Wires[spare, byteSel, bS, wordSel, wS], tileArray: tileArray, neighborX: TilingClass.LayoutNeighborX, neighborY: TilingClass.LayoutNeighborY, name: "RamInterfaceRout"]; }; Interleave: PUBLIC PROC [b: NAT] RETURNS [public: Core.Wires] = { wire: Wire _ CoreCreate.Seq["Wire", b]; interleavedWire: Wire _ CoreCreate.Seq["InterleavedWire", b]; IF b MOD 2 = 1 THEN ERROR; IF b=0 THEN ERROR; FOR i: NAT IN [0..b/2) DO interleavedWire[2*i] _ wire[i]; interleavedWire[2*i+1] _ wire[b/2+i]; ENDLOOP; public _ LIST [wire, interleavedWire]; }; Interleave2: PUBLIC PROC [b: NAT] RETURNS [public: Core.Wires] = { wire0: Wire _ CoreCreate.Seq["Wire0", b/2]; wire1: Wire _ CoreCreate.Seq["Wire1", b/2]; interleavedWire: Wire _ CoreCreate.Seq["InterleavedWire", b]; IF b MOD 2 = 1 THEN ERROR; IF b=0 THEN ERROR; FOR i: NAT IN [0..b/2) DO interleavedWire[2*i] _ wire0[i]; interleavedWire[2*i+1] _ wire1[i]; ENDLOOP; public _ LIST [wire0, wire1, interleavedWire]; }; LogicDesign: PUBLIC PROC [] RETURNS [design: CD.Design] = { name: ROPE _ "SCLogic"; -- must declare it as a rope! IF myLogicDesign=NIL THEN { myLogicDesign _ CDViewer.FindDesign[name]; IF myLogicDesign=NIL THEN myLogicDesign _ CDIO.ReadDesign[name, NIL, workingDirectory]; IF myLogicDesign = NIL THEN ERROR; }; design _ myLogicDesign }; LayoutDesign: PUBLIC PROC [] RETURNS [design: CD.Design] = { name: ROPE _ "CacheCells"; -- must declare it as a rope! IF myLayoutDesign=NIL THEN { myLayoutDesign _ CDViewer.FindDesign[name]; IF myLayoutDesign=NIL THEN myLayoutDesign _ CDIO.ReadDesign[name, NIL, workingDirectory]; IF myLayoutDesign = NIL THEN ERROR; }; design _ myLayoutDesign }; IsGlobal: PROC [w: Wire, cx: Sisyph.Context] RETURNS [BOOL _ FALSE] = { name: ROPE _ CoreOps.GetShortWireName[w]; FOR lr: LIST OF ROPE _ Sisyph.GetGlobalNames[cx], lr.rest WHILE lr#NIL DO IF Rope.Equal[name, lr.first] THEN RETURN [TRUE] ENDLOOP; }; WireSide: PROC [wire: Wire, baseCT: CellType] RETURNS [sides: CoreGeometry.Sides _ CoreGeometry.noSide] ~ { EachPin: CoreGeometry.EachPinProc = { sides[side] _ TRUE; }; [] _ CoreGeometry.EnumerateSides[Sisyph.mode.decoration, baseCT, wire, EachPin]; }; WireSideProblem: PROC [wire: Wire, msg: ROPE, baseCT: CellType] ~ { TerminalIO.PutF["\n*** Wire %g %g in cell %g\n", IO.rope[CoreOps.GetFullWireName[baseCT.public, wire]], IO.rope[msg], IO.rope[CoreOps.GetCellTypeName[baseCT]]]; SIGNAL Sinix.CallerBug[]; }; CatIndex: PROC[name: ROPE, index: INT] RETURNS [ROPE] ~ { RETURN [Rope.Cat[name, "[", Convert.RopeFromInt[index], "]"]] }; END. PSCUtilsImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Written by: Pradeep Sindhu, October 2, 1986 10:52:55 pm PDT Pradeep Sindhu, January 21, 1988 3:53:31 pm PST Cesar Douady January 12, 1988 8:18:59 pm PST Exported Procs This procedure constructs a tiling row from a list of object names. It is assumed that the publics of each of the objects are the same. Make the baseCellTypes Compute the public of the cellType to be returned Fill in the cellTypes Define the renaming for wires that touch the left side Define the renaming for wires that touch the right side Define the renaming for global wires Define the renaming for arrayed wires Copying the public is necessary to avoid sharing of wires between cellTypes Make the baseCellTypes Compute the public of the cellType to be returned Fill in the cellTypes Copying the public is necessary to avoid sharing of wires between cellTypes Internal Utilities Finds the sides on which wire touches baseCT (of which it is a public). CoreGeometry.noSide will be returned if the wire has no pins. This should be in CoreGeometry. Κ 0˜codešœ™Kšœ Οmœ1™