DIRECTORY CD, CDEvents, CDIO, CDViewer, CommandTool, Convert, CoreGeometry, CoreOps, GList, IO, Rope, Sinix, Sisyph, SCUtils, TerminalIO, TilingClass; SCUtilsImpl: CEDAR PROGRAM IMPORTS CDEvents, CDViewer, CommandTool, CDIO, Convert, CoreGeometry, CoreOps, GList, IO, Rope, Sinix, Sisyph, TerminalIO, TilingClass EXPORTS SCUtils ~ BEGIN OPEN SCUtils; myDesign: PUBLIC 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"]]; }; LayoutDesign: PUBLIC PROC [] RETURNS [design: CD.Design] = { name: ROPE _ "CacheCells"; design _ CDViewer.FindDesign[name]; IF design=NIL THEN design _ CDIO.ReadDesign[name, NIL, workingDirectory]; IF design = NIL THEN ERROR; }; 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[]; }; AfterInput: CDEvents.EventProc = { IF myDesign=NIL THEN myDesign _ design; }; CDEvents.RegisterEventProc[$AfterInput, AfterInput]; END. zSCUtilsImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Written by: Pradeep Sindhu, October 2, 1986 10:52:55 pm PDT Pradeep Sindhu, September 10, 1987 4:57:23 pm PDT 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 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. Κm˜codešœ™Kšœ Οmœ1™