DIRECTORY CD, CDDirectory, Convert, Core, CoreCreate, CoreOps, CoreGeometry, IO, Ports, PWCore, Rope, Rosemary, Sinix, Sisyph, Sch, TerminalIO, TilingClass; SchImpl: CEDAR PROGRAM IMPORTS CDDirectory, Convert, CoreCreate, CoreOps, CoreGeometry, IO, PWCore, Rope, Sinix, Sisyph, TerminalIO, TilingClass EXPORTS Sch = BEGIN OPEN Sch; iconRope: ROPE _ ".icon"; schRope: ROPE _ ".sch"; Sch: PUBLIC PROC [cx: Context, name: ROPE] = { CheckObjectName[cx, Rope.Cat[name, schRope]]; Sisyph.Eval[cx, "coreProps _ CoreProperties.PutProp[coreProps, $PWCoreSourceDesign, design]"]; }; Icon: PUBLIC PROC [cx: Context, name: ROPE] RETURNS [ct: CellType] = { CheckObjectName[cx, Rope.Cat[name, iconRope]]; ct _ Sisyph.ExtractSchematicByName[Rope.Cat[name, schRope], cx]; }; CheckObjectName: PUBLIC PROC [cx: Context, assertedName: ROPE] = { objectName: ROPE _ CDDirectory.Name[Sisyph.GetCDObj[cx]]; IF NOT Rope.Equal[objectName, assertedName] THEN TerminalIO.WriteF["Warning: ChipNDale directory name %g does not correspond to asserted name %g", IO.refAny[objectName], IO.refAny[assertedName]]; }; Orient: PUBLIC PROC [cx: Context, atom: ATOM] RETURNS [ct: CellType] = { objectName: ROPE _ CDDirectory.Name[Sisyph.GetCDObj[cx]]; baseCell: Core.CellType _ Sisyph.ExtractSchematicByName[objectName, cx]; ct _ PWCore.RotateCellType[baseCell, atom]; Sisyph.Eval[cx, "coreProps _ NIL"]; }; WireSide: PROC [wire: Core.Wire, baseCT: Core.CellType] RETURNS [sides: CoreGeometry.Sides _ CoreGeometry.noSide] ~ { EachPin: CoreGeometry.EachPinProc = { sides[side] _ TRUE; }; [] _ CoreGeometry.EnumerateSides[Sisyph.mode.decoration, baseCT, wire, EachPin]; }; WireSideProblem: PROC [wire: Core.Wire, msg: ROPE, baseCT: Core.CellType] ~ { TerminalIO.WriteF["\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[]; }; CSeq: PUBLIC PROC [cx: Sisyph.Context, count: NAT, dir: XorY] RETURNS [ct: Core.CellType] = { ct _ CSeqOb[CDDirectory.Name[Sisyph.GetCDObj[cx]], cx, count, dir]; }; CSeqOb: PUBLIC PROC [obName: ROPE, cx: Sisyph.Context, count: NAT, dir: XorY] RETURNS [ct: Core.CellType] = { sWires, fsWires: LIST OF CoreCreate.WR; EachWire: CoreOps.EachWireProc = { sides: CoreGeometry.Sides = WireSide[wire, baseCT]; vertical: BOOL = sides[top] OR sides[bottom]; horizontal: BOOL = sides[left] OR sides[right]; IF ~(vertical OR horizontal) THEN RETURN; -- This wire has no pins, try its sons IF vertical AND horizontal THEN WireSideProblem[wire, "touches adjacent sides", baseCT]; IF (vertical AND (dir=X OR dir=RX)) OR (horizontal AND (dir=Y OR dir=RY)) THEN IF wire.size=0 THEN sWires _ CONS[wire, sWires] ELSE fsWires _ CONS[wire, fsWires]; subWires _ FALSE; }; baseCT: Core.CellType _ Sisyph.ExtractSchematicByName[obName, cx]; [] _ CoreOps.VisitWireSeq[baseCT.public, EachWire]; ct _ CoreCreate.SequenceCell[ name: Rope.Cat[obName, "Seq", SELECT dir FROM X => "X", Y => "Y", RX => "RX", RY => "RY", ENDCASE => ERROR], baseCell: baseCT, count: count, sequencePorts: CoreCreate.WireList[sWires], flatSequencePorts: CoreCreate.WireList[fsWires] ]; SELECT dir FROM X => PWCore.SetArrayX[ct]; Y => PWCore.SetArrayY[ct]; RX => PWCore.SetLayout[ct, $ReverseArrayX]; RY => PWCore.SetLayout[ct, $ReverseArrayY]; ENDCASE => ERROR; Sisyph.Eval[cx, "coreProps _ NIL"]; -- Why is this necessary? JMF }; CStitch: PUBLIC PROC [cx: Context, count: NAT, dir: XorY] RETURNS [ct: CellType] = { ct _ CStitchOb[CDDirectory.Name[Sisyph.GetCDObj[cx]], cx, count, dir]; }; CStitchOb: PUBLIC PROC [obName: ROPE, cx: Context, count: NAT, dir: XorY] RETURNS [ct: CellType] = { SELECT dir FROM X => ct _ StitchX[obName, cx, count]; Y => ct _ StitchY[obName, cx, count]; ENDCASE => ERROR; }; StitchX: PROC [obName: ROPE, cx: Sisyph.Context, count: NAT] RETURNS [ct: CellType] ~ { public: Wire; tileRow: TilingClass.TileRow _ NEW [TilingClass.TileRowRec[count]]; tileArray: TilingClass.TileArray _ NEW [TilingClass.TileArrayRec[1]]; baseCT: CellType _ Sisyph.ExtractSchematicByName[obName, cx]; publicElements, arrayedWires, leftSideOnlyWires, rightSideOnlyWires, globalWires: Wires _ NIL; EachWire: CoreOps.EachWireProc = { sides: CoreGeometry.Sides = WireSide[wire, baseCT]; vertical: BOOL = sides[top] OR sides[bottom]; IF vertical AND (sides[right] OR sides[left]) THEN WireSideProblem[wire, "touches adjacent sides", baseCT]; 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] } } }; [] _ CoreOps.VisitWireSeq[baseCT.public, EachWire]; public _ CoreOps.CreateWire[publicElements]; FOR i: INT IN [0..count) DO tileRow[i] _ NEW [TilingClass.TileRec _ [type: baseCT]] 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[public, tileArray, TilingClass.SchematicsNeighborX, TilingClass.SchematicsNeighborY, Rope.Cat[obName, ".StitchX"]]; }; StitchY: PROC [obName: ROPE, cx: Sisyph.Context, count: NAT] RETURNS [ct: CellType] ~ { public: Wire; tileArray: TilingClass.TileArray _ NEW [TilingClass.TileArrayRec[count]]; baseCT: CellType _ Sisyph.ExtractSchematicByName[obName, cx]; publicElements, arrayedWires, botSideOnlyWires, topSideOnlyWires, globalWires: Wires _ NIL; EachWire: CoreOps.EachWireProc = { sides: CoreGeometry.Sides = WireSide[wire, baseCT]; horizontal: BOOL = sides[left] OR sides[right]; IF horizontal AND (sides[top] OR sides[bottom]) THEN WireSideProblem[wire, "touches adjacent sides", baseCT]; IF horizontal 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[bottom] THEN botSideOnlyWires _ CONS[wire, botSideOnlyWires]; IF sides[top] THEN topSideOnlyWires _ CONS[wire, topSideOnlyWires]; publicElements _ CONS [wire, publicElements] } } }; [] _ CoreOps.VisitWireSeq[baseCT.public, EachWire]; public _ CoreOps.CreateWire[publicElements]; FOR i: INT IN [0..count) DO tileArray[i] _ NEW [TilingClass.TileRowRec[1]]; tileArray[i][0] _ NEW [TilingClass.TileRec _ [type: baseCT]] ENDLOOP; FOR wl: Wires _ botSideOnlyWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; tileArray[0][0].renaming _ CONS[[wireName, wireName], tileArray[0][0].renaming]; ENDLOOP; FOR wl: Wires _ topSideOnlyWires, wl.rest WHILE wl#NIL DO wireName: ROPE _ CoreOps.GetShortWireName[wl.first]; tileArray[count-1][0].renaming _ CONS[[wireName, wireName], tileArray[count-1][0].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 tileArray[i][0].renaming _ CONS[[wireName, wireName], tileArray[i][0].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 tileArray[i][0].renaming _ CONS[[wireName, Rope.Cat[wireName, "[", Convert.RopeFromInt[i], "]"]], tileArray[i][0].renaming]; ENDLOOP; ENDLOOP; ct _ TilingClass.CreateTiling[public, tileArray, TilingClass.SchematicsNeighborX, TilingClass.SchematicsNeighborY, Rope.Cat[obName, ".StitchY"]]; }; WSeq: PUBLIC PROC [name: ROPE _ NIL, size: NAT] RETURNS [wire: Wire] = { wire _ CoreCreate.Seq[name, size]; }; WRange: PUBLIC PROC [name: ROPE, start: NAT, size: NAT] RETURNS [wire: Core.Wire] = { wire _ CoreCreate.Seq[size: size]; FOR i: NAT IN [0..size) DO [] _ CoreOps.SetShortWireName[wire[i], IO.PutFR["%g[%g]", IO.rope[name], IO.int[start+i]]]; ENDLOOP; }; WIndex: PUBLIC PROC [name: ROPE, index: NAT] RETURNS [wire: Core.Wire] = { wire _ CoreOps.CreateWire[name: name]; [] _ CoreOps.SetShortWireName[wire, IO.PutFR["%g[%g]", IO.rope[name], IO.int[index]]]; }; InitPort: PUBLIC PROC [cx: Context, initType: Ports.LevelType _ b, initDrive: Ports.Drive _ none] = { Sisyph.Eval[cx, "coreInstProps _ CoreProperties.PutProp[coreInstProps, $PortData, NEW[Ports.PortDataRec _ [ levelType: initType, driveType: aggregate, drive: initDrive, drives: NIL]]]"]; }; TSize: PUBLIC PROC [cx: Context, size: Rosemary.TransistorSize] = { Sisyph.Eval[cx, "coreInstProps _ CoreProperties.PutProp[coreInstProps, $RoseTransistorSize, NEW[Ports.Drive _ size]]"]; }; SetWire: PUBLIC PROC [cx: Context, level: Ports.Level _ L, size: Rosemary.WireSize _ charge] = { Sisyph.Eval[cx, "coreInstProps _ CoreProperties.PutProp[coreInstProps, $RoseWireData, NEW[Rosemary.RoseWireDataRec _ [level, size]]]"]; }; 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; }; END. 4SchImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Louis Monier February 13, 1986 3:46:07 pm PST Barth, August 21, 1986 3:55:10 pm PDT Last Edited by: Louis Monier August 7, 1986 7:53:12 pm PDT Jean-Marc Frailong December 17, 1986 6:20:02 pm PST Pradeep Sindhu November 16, 1986 0:06:21 am PST Bertrand Serlet September 6, 1986 0:31:15 am PDT 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. Internal Utilities Κ Γ– "cedar" style˜codešœ ™ Kšœ Οmœ1™