<> <> <> <> <> <> DIRECTORY CD, CDBasics, CDCells, CDSymbolicObjects, Core, CoreClasses, CoreDirectory, CoreGeometry, CoreOps, CoreProperties, IO, PWCore, Rope, Route, RouteUtil, RTBasic, RTCoreUtil, SC, SCInstUtil, SCObjUtil, SCNetUtil, SCPrivate, SCUtil, Sinix, SinixOps, TerminalIO; SCGetStructureImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDSymbolicObjects, CoreDirectory, CoreGeometry, CoreOps, CoreProperties, IO, PWCore, Rope, RouteUtil, RTBasic, RTCoreUtil, SC, SCInstUtil, SCObjUtil, SCNetUtil, SCUtil, Sinix, SinixOps, TerminalIO EXPORTS SCPrivate SHARES SC = BEGIN debug: BOOLEAN _ FALSE; GetStructure: PUBLIC PROCEDURE [handle: SC.Handle, cellType: Core.CellType, flattenCellType: RTCoreUtil.FlattenCellTypeProc, decoration: CoreGeometry.Decoration] RETURNS [done: BOOLEAN _ TRUE] = { InternalWireProc: RTCoreUtil.FlatWireProc = { net: SCPrivate.Net _ SCUtil.FindNetByWire[handle, wire]; IF net # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate net name: ", pathName]] ELSE net _ SCNetUtil.DefineNet[handle, wire, pathName]}; ExternalWireProc: RTCoreUtil.FlatWireProc = { instance: SCPrivate.Instance _ SCUtil.FindInstance[handle, pathName]; net: SCPrivate.Net _ SCUtil.FindNetByWire[handle, wire]; IF net = NIL THEN SC.Signal[callingError, Rope.Cat["Missing net name: ", pathName]]; IF instance # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate port name: ", pathName, ", object: ", parms.portObject.name]]; IF instance = NIL AND net # NIL AND ~SCUtil.IsPowerName[handle, pathName] THEN {instance _ SCInstUtil.DefineInstance[handle, pathName, parms.portObject, NIL, CoreOps.GetShortWireName[wire]]; SCNetUtil.AddConnection[handle, net, instance, parms.portObject.pins.p[0], 0, externalPin]; net.externNet _ externalNet; GetIOProperties[handle, instance, net, wire, usePositions]}}; InstanceProc: RTCoreUtil.FlatInstanceProc = { -- PROC [cellInstance: CoreClasses.CellInstance, pathName: Rope.ROPE] RETURNS [quit: BOOL _ FALSE]; EachInstancePin: RTCoreUtil.EachInstancePinProc = { IF ~SCUtil.IsPowerName[handle, CoreOps.GetShortWireName[publicWire]] THEN <> {net: SCPrivate.Net _ SCUtil.FindNetByWire[handle, actualWire]; thisPin: SCPrivate.ObjectPin _ SCUtil.FindPinByWire[object, publicWire]; -- get the pin IF net = NIL THEN {SC.Signal[callingError, Rope.Cat[Rope.Cat["Net not defined: ", CoreOps.GetShortWireName[actualWire], " on component: ", instance.name], Rope.Cat[", type: ", object.name]]]}; IF thisPin = NIL THEN {SC.Signal[callingError, Rope.Cat[Rope.Cat["not enough pins on component: ", instance.name], Rope.Cat[", type: ", object.name]]]}; IF thisPin # NIL AND net # NIL THEN { <> IF Rope.Equal["Vdd", net.name] THEN hasVddConnection _ TRUE; IF Rope.Equal["Gnd", net.name] THEN hasGndConnection _ TRUE; FOR pinIndex: NAT IN [0 .. object.numPins) DO objPin: SCPrivate.ObjectPin _ object.pins.p[pinIndex]; IF objPin # NIL THEN IF objPin.publicWire = thisPin.publicWire THEN { SCNetUtil.AddConnection[handle, net, instance, objPin, pinIndex, compPin]; }; ENDLOOP}}}; instance: SCPrivate.Instance; object: SCPrivate.Object _ SCUtil.FindObjectByCell[handle, cellInstance.type]; IF object = NIL THEN { object _ DefineObject[handle, CoreOps.GetCellTypeName[cellInstance.type], logic, cellInstance.type]; object.pins _ DefinePinsFromDecoration[handle, object, cellInstance.type, decoration]}; instance _ SCInstUtil.DefineInstance[handle, pathName, object, cellInstance, NIL]; [] _ RTCoreUtil.EnumFlatInstancePins[cellInstance, EachInstancePin]; GetLogicProperties[handle, instance, cellInstance]}; hasVddConnection, hasGndConnection: BOOLEAN _ FALSE; usePositions: BOOL _ RTCoreUtil.GetCoreBoolProp[cellType, SC.usePublicPositionsProp, FALSE]; <> parms: SCPrivate.Parms _ NARROW[handle.parms]; structureData: SCPrivate.StructureData _ NARROW[NEW[SCPrivate.StructureDataRec], SCPrivate.StructureData]; structureData.objects _ NEW[SCPrivate.ObjectsRec]; structureData.instances _ NEW[SCPrivate.InstancesRec]; structureData.instances.inst _ NEW[SCPrivate.InstsOb]; structureData.nets _ NEW[SCPrivate.NetsRec]; structureData.nets.nets _ NEW[SCPrivate.NetArray]; handle.structureData _ structureData; <<>> <> parms.portObject _ DefineIOType[handle, decoration]; parms.ftObject _ DefineFtType[handle, "feedthru", decoration]; parms.vddObject _ DefinePowerType[handle, "vdd", decoration]; parms.gndObject _ DefinePowerType[handle, "gnd", decoration]; TerminalIO.PutRope["Getting structure description . . .\n"]; RTCoreUtil.Flatten[cellType, flattenCellType, ExternalWireProc, InternalWireProc, InstanceProc, SC.interestingProperties]; <<>> <<-- connect to power cells>> IF hasVddConnection THEN DoPower[handle, "Vdd", parms.vddObject, cellType.public, "Vdd"]; IF hasGndConnection THEN DoPower[handle, "Gnd", parms.gndObject, cellType.public, "Gnd"]; <<>> <> DoBuses[handle, left]; DoBuses[handle, right]; TerminalIO.PutF["Statistics: \n instances: %g, wires: %g, public wires: %g cells: %g\n", IO.int[structureData.instances.numLogics], IO.int[structureData.nets.count], IO.int[structureData.instances.numIOs], IO.int[structureData.objects.count]]; IF debug THEN SCUtil.WriteStructure[handle]}; DoPower: PROC [handle: SC.Handle, instanceName: Rope.ROPE, object: SCPrivate.Object, rootWire: Core.Wire, wireName: Rope.ROPE] ~ { instance: SCPrivate.Instance _ SCInstUtil.DefineInstance[handle, instanceName, object, NIL, NIL]; <> powerWire: Core.Wire _ CoreOps.FindWire[rootWire, wireName]; net: SCPrivate.Net _ SCUtil.FindNetByWire[handle, powerWire]; SCNetUtil.AddConnection[handle, net, instance, object.pins.p[0], 0, compPin]; SCNetUtil.AddConnection[handle, net, instance, object.pins.p[1], 1, compPin]}; DoBuses: PROCEDURE [handle: SC.Handle, lRSide: RTBasic.LRSide] = { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; powerBuses: SCPrivate.PowerBuses _ layoutData.powerBuses; net: SCPrivate.Net _ SCUtil.FindNet[handle, powerBuses[lRSide].name]; powerBuses[lRSide].net _ net}; DefineObject: PROCEDURE [handle: SC.Handle, objectName: Rope.ROPE, class: SCPrivate.CompClass, cellType: Core.CellType _ NIL] RETURNS [object: SCPrivate.Object _ NIL] = { <> <<>> <> structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; objects: SCPrivate.Objects _ structureData.objects; parms: SCPrivate.Parms _ NARROW[handle.parms]; obRect: CD.Rect; useClass: SCPrivate.CompClass; ob: CD.Object _ NIL; SELECT TRUE FROM class = io => {ob _ BuildIOObject[handle]; useClass _ io}; class = ft OR class = other => { lib: CoreDirectory.Library _ CoreDirectory.FetchLibrary[parms.libName]; ob _ PWCore.Layout[CoreDirectory.Fetch[lib, objectName]]; IF class = other THEN useClass _ logic ELSE useClass _ ft; -- make power connection cells logic cells -- }; PWCore.GetLayoutAtom[cellType] # NIL => { ob _ PWCore.Layout[cellType]; useClass _ logic}; ENDCASE => NULL; <<>> IF ob = NIL THEN { SC.Signal[callingError, Rope.Cat["No layout for cellType: ", CoreOps.GetCellTypeName[cellType]]]; RETURN}; obRect _ CD.InterestRect[ob].r; objects.count _ objects.count + 1; object _ NEW[SCPrivate.ObjectRec _ [name: objectName, objectNum: objects.count, size: RTBasic.XYToPQ[horizontal, CDBasics.SizeOfRect[obRect]], orgin: RTBasic.XYToPQ[horizontal, CDBasics.BaseOfRect[obRect]], numPins: 0, pins: NIL, typeClass: useClass, numTimesUsed: 0, cdOb: ob, cellType: cellType]]; objects.ob[objects.count] _ object}; DefinePinsFromDecoration: PROCEDURE [handle: SC.Handle, object: SCPrivate.Object, cellType: Core.CellType _ NIL, decoration: CoreGeometry.Decoration] RETURNS [objectPins: SCPrivate.ObjectPins] = { <> <<>> <> CountPins: CoreGeometry.EachWirePinProc = { IF UsePin[min, max, side, layer] THEN object.numPins _ object.numPins + 1}; UsePin: PROC [min, max: INT, side: CoreGeometry.Side, layer: CD.Layer] RETURNS [useIt: BOOLEAN _ FALSE] ~ { IF (side = top OR side = bottom) AND layer = handle.rules.rowRules.branchLayer THEN useIt _ TRUE}; PinEnum: CoreGeometry.EachWirePinProc = { IF UsePin[min, max, side, layer] THEN {rect: SC.Rect _ DefineRect[obRect, min, max, handle.rules.rowRules.branchWidth, side]; name: Rope.ROPE _ CoreOps.GetShortWireName[wire]; scSide: SC.Side _ SELECT side FROM right => right, left => left, top => top, bottom => bottom, ENDCASE => ERROR; objectPins.p[numPins] _ NEW[SCPrivate.ObjectPinRec _ [name: name, pinPos: [scSide, 0, (max+min)/2], publicWire: wire, rect: rect, layer: layer, equivClass: name]]; numPins _ numPins + 1}}; numPins: NAT _ 0; obRect: CD.Rect _ CD.InterestRect[object.cdOb].r; <<>> <> [] _ CoreGeometry.EnumerateNonOverlappingSides[decoration, cellType, CountPins]; objectPins _ NEW[SCPrivate.ObjectPinsRec[object.numPins]]; IF object.numPins > 0 THEN [] _ CoreGeometry.EnumerateNonOverlappingSides[decoration, cellType, PinEnum]}; DefineFtType: PROCEDURE [handle: SC.Handle, name: Rope.ROPE, decoration: CoreGeometry.Decoration] RETURNS [object: SCPrivate.Object] = { mode: Sinix.Mode = SinixOps.GetExtractMode[handle.rules.rowParms.technology]; object _ DefineObject[handle, name, ft, NIL]; object.cellType _ NARROW [Sinix.Extract[object.cdOb, mode].result]; IF object = NIL THEN { SC.Signal[callingError, Rope.Cat["FeedThru object is not defined: ", name, "\n"]]; RETURN}; object.pins _ DefinePinsFromDecoration[handle, object, object.cellType, decoration]}; <> DefineIOType: PROCEDURE [handle: SC.Handle, decoration: CoreGeometry.Decoration] RETURNS [object: SCPrivate.Object _ NIL] = { mode: Sinix.Mode = SinixOps.GetExtractMode[handle.rules.rowParms.technology]; object _ DefineObject[handle, NIL, io, NIL]; object.cellType _ NARROW [Sinix.Extract[object.cdOb, mode].result]; IF object = NIL THEN { SC.Signal[callingError, "IO object is not defined \n"]; RETURN}; object.pins _ DefinePinsFromDecoration[handle, object, object.cellType, decoration]}; <> DefinePowerType: PROCEDURE [handle: SC.Handle, name: Rope.ROPE, decoration: CoreGeometry.Decoration] RETURNS [object: SCPrivate.Object _ NIL] = { mode: Sinix.Mode = SinixOps.GetExtractMode[handle.rules.rowParms.technology]; object _ DefineObject[handle, name, other, NIL]; object.cellType _ NARROW [Sinix.Extract[object.cdOb, mode].result]; IF object = NIL THEN { SC.Signal[callingError, Rope.Cat["Power object is not defined: ", name, "\n"]]; RETURN[NIL]}; object.pins _ DefinePinsFromDecoration[handle, object, object.cellType, decoration]; RETURN[object]}; <> DefineRect: PROC [obRect: SC.Rect, min, max, depth: INT, side: CoreGeometry.Side] RETURNS [pinRect: SC.Rect] ~ { SELECT side FROM bottom => pinRect _ [min, obRect.y1, max, obRect.y1 + depth]; right => pinRect _ [obRect.x2 - depth, min, obRect.x2, max]; top => pinRect _ [min, obRect.y2 - depth, max, obRect.y2]; left => pinRect _ [obRect.x2, min, obRect.x2 + depth, max]; ENDCASE}; BuildIOObject: PROCEDURE [handle: SC.Handle] RETURNS [object: CD.Object _ CDCells.CreateEmptyCell[]] = { minSize: SC.Number _ handle.rules.rowRules.branchWidth; symInst: CD.Instance _ RouteUtil.Include[object, CDSymbolicObjects.CreateSegment[length: minSize], [minSize, 0], CDSymbolicObjects.OrientFromDirection[south]]; CDSymbolicObjects.SetLayer[symInst, handle.rules.rowRules.branchLayer]; CDSymbolicObjects.SetName[symInst, "io"]; CDCells.SetInterestRect[design: NIL, cell: object, r: [0, 0, minSize, minSize]]; -- set interestRect of cell RTBasic.RepositionCell[object]}; GetLogicProperties: PROCEDURE [handle: SC.Handle, instance: SCPrivate.Instance, cellInstance: CoreClasses.CellInstance] = { ProcProps: PROC [prop: ATOM, val: REF ANY] ~ { SELECT TRUE FROM prop = SC.rowProp => instance.fnlRow _ NARROW[val, REF INT]^; prop = SC.positionProp => instance.fnlPos _ NARROW[val, REF INT]^; ENDCASE; }; CoreProperties.Enumerate[cellInstance.properties, ProcProps]}; GetSide: PROC [atom: ATOM] RETURNS [side: SC.SideOrNone] ~ { side _ SELECT atom FROM SC.bottomSideValue => bottom, SC.rightSideValue => right, SC.topSideValue => top, SC.leftSideValue => left, ENDCASE => SC.Error[programmingError, "Not suppose to happen."]}; GetIOProperties: PROCEDURE [handle: SC.Handle, instance: SCPrivate.Instance, net: SCPrivate.Net, wire: Core.Wire, usePositions: BOOL] = { ProcProps: PROC [prop: ATOM, val: REF ANY] ~ { SELECT TRUE FROM prop = SC.sideProp => instance.fnlSide _ GetSide[NARROW[val, ATOM]]; prop = SC.positionProp => instance.fnlPos _ IF usePositions THEN NARROW[val, REF INT]^ ELSE 0; ENDCASE}; CoreProperties.Enumerate[wire.properties, ProcProps]}; DestroyStructure: PUBLIC PROC [handle: SC.Handle] ~ { EachObj: SCObjUtil.EachObjectProc ~ { object.pins _ NIL; object.cdOb _ NIL; objects.ob[object.objectNum] _ NIL}; EachInst: SCInstUtil.EachInstanceProc ~ { EachPin: SCInstUtil.EachPinProc ~ {netPin.pin _ NIL; netPin.net _ NIL}; [] _ SCInstUtil.EnumeratePinsOnInst[instance, EachPin]; instance.pinNets _ NIL; instance.ftNet _ NIL; instances.inst[instance.num] _ NIL}; EachNet: SCNetUtil.EachNetProc ~ { EachPin: SCNetUtil.EachPinProc ~ {netPin.pin _ NIL; netPin.instance _ NIL}; [] _ SCNetUtil.EnumeratePinsOnNet[net, EachPin]; net.pins _ NIL; net.netDat _ NIL; nets.nets[net.num] _ NIL}; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; objects: SCPrivate.Objects _ structureData.objects; instances: SCPrivate.Instances _ structureData.instances; nets: SCPrivate.Nets _ structureData.nets; [] _ SCObjUtil.EnumerateAllObjects[handle, EachObj]; [] _ SCInstUtil.EnumerateAllInstances[handle, EachInst]; [] _ SCNetUtil.EnumerateNets[handle, EachNet]}; END.