DIRECTORY CD, CDBasics, CDCells, CDSymbolicObjects, Core, CoreClasses, CoreDirectory, CoreFlat, CoreGeometry, CoreOps, CoreProperties, CoreRoute, DABasics, IO, PWCore, RefTab, Rope, Route, RouteUtil, RTBasic, RTCoreUtil, SC, SCInstUtil, SCObjUtil, SCNetUtil, SCPrivate, SCUtil, Sinix, SinixOps, TerminalIO; SCGetStructureImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDCells, CDSymbolicObjects, CoreDirectory, CoreFlat, CoreGeometry, CoreOps, CoreProperties, CoreRoute, IO, PWCore, RefTab, 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, root: Core.CellType, flattenCellType: RTCoreUtil.FlattenCellTypeProc, decoration: CoreGeometry.Decoration] RETURNS [done: BOOLEAN _ TRUE] = { InternalWireProc: RTCoreUtil.FlatWireProc = { pathName: Rope.ROPE _ CoreRoute.LabelFlatWire[root, flatWire]; net: SCPrivate.Net _ SCUtil.FindNet[handle, pathName]; IF net # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate net name: ", pathName]] ELSE net _ SCNetUtil.DefineNet[handle, pathName]}; ExternalWireProc: RTCoreUtil.FlatWireProc = { pathName: Rope.ROPE _ CoreRoute.LabelFlatWire[root, flatWire]; instance: SCPrivate.Instance _ SCUtil.FindInstance[handle, pathName]; net: SCPrivate.Net _ SCUtil.FindNet[handle, pathName]; 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 THEN { net.externNet _ externalNet; net.publicWire _ flatWire.wire; IF ~SCUtil.IsPowerName[handle, pathName] THEN { FOR side: DABasics.Side IN [bottom .. right] DO IF WireOnSide[side, flatWire.wire] THEN { instance _ SCInstUtil.DefineInstance[handle, pathName, parms.portObject, pathName]; SCNetUtil.AddConnection[handle, net, instance, parms.portObject.pins.p[0], 0, externalPin]; instance.fnlSide _ side; instance.fnlPos _ GetIOPosition[side, flatWire.wire.properties, usePositions]} ENDLOOP; IF instance = NIL THEN { instance _ SCInstUtil.DefineInstance[handle, pathName, parms.portObject, pathName]; SCNetUtil.AddConnection[handle, net, instance, parms.portObject.pins.p[0], 0, externalPin]}}}}; InstanceProc: RTCoreUtil.FlatInstanceProc = { EachPublic: PROC [publicWire: Core.Wire] = { pinName: Rope.ROPE _ CoreOps.GetShortWireName[publicWire]; IF ~SCUtil.IsPowerName[handle, pinName] THEN { flatWire: CoreFlat.FlatWire _ NARROW [RefTab.Fetch[bindings, publicWire].val]; wireName: Rope.ROPE _ CoreRoute.LabelFlatWire[root, flatWire^]; net: SCPrivate.Net _ SCUtil.FindNet[handle, wireName]; thisPin: SCPrivate.ObjectPin _ SCUtil.FindPin[object, pinName]; -- get the pin IF net = NIL THEN {SC.Signal[callingError, Rope.Cat[Rope.Cat["Net not defined: ", wireName, " 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; pathName: Rope.ROPE _ CoreFlat.InstancePathRope[root, flatCellType.path]; object: SCPrivate.Object _ SCUtil.FindObjectByCell[handle, cell]; IF object = NIL THEN { object _ DefineObject[handle, CoreOps.GetCellTypeName[cell], logic, cell]; object.pins _ DefinePinsFromDecoration[handle, object, cell, decoration]}; instance _ SCInstUtil.DefineInstance[handle, pathName, object, NIL]; CoreOps.VisitRootAtomics[cell.public, EachPublic]; GetLogicProperties[instance, properties]}; hasVddConnection, hasGndConnection: BOOLEAN _ FALSE; usePositions: BOOL _ RTCoreUtil.GetCoreBoolProp[root, 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[root, flattenCellType, ExternalWireProc, InternalWireProc, InstanceProc, SC.interestingProperties]; IF hasVddConnection THEN DoPower[handle, "Vdd", parms.vddObject, "Vdd"]; IF hasGndConnection THEN DoPower[handle, "Gnd", parms.gndObject, "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, wireName: Rope.ROPE] ~ { instance: SCPrivate.Instance _ SCInstUtil.DefineInstance[handle, instanceName, object, NIL]; net: SCPrivate.Net _ SCUtil.FindNet[handle, wireName]; 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 [instance: SCPrivate.Instance, properties: Core.Properties] = { 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[properties, ProcProps]}; WireOnSide: PROC [side: DABasics.Side, wire: Core.Wire] RETURNS [onSide: BOOL _ FALSE] ~ { ProcProps: PROC [prop: ATOM, val: REF ANY] ~ { SELECT TRUE FROM prop = SC.bottomSideProp => IF side = bottom THEN onSide _ TRUE; prop = SC.rightSideProp => IF side = right THEN onSide _ TRUE; prop = SC.topSideProp => IF side = top THEN onSide _ TRUE; prop = SC.leftSideProp => IF side = left THEN onSide _ TRUE; ENDCASE}; CoreProperties.Enumerate[wire.properties, ProcProps]}; GetIOPosition: PROC [side: DABasics.Side, properties: Core.Properties, usePositions: BOOL] RETURNS [position: INT _ 0] ~ { ProcProps: PROC [prop: ATOM, val: REF ANY] ~ { SELECT TRUE FROM prop = SC.bottomPositionProp => IF side = bottom THEN position _ NARROW[val, REF INT]^; prop = SC.rightPositionProp => IF side = right THEN position _ NARROW[val, REF INT]^; prop = SC.topPositionProp => IF side = top THEN position _ NARROW[val, REF INT]^; prop = SC.leftPositionProp => IF side = left THEN position _ NARROW[val, REF INT]^; ENDCASE}; IF usePositions THEN CoreProperties.Enumerate[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. ήSCGetStructureImpl.mesa Copyright Σ 1986, 1987 by Xerox Corporation. All rights reserved. Last Edited by: Preas, September 9, 1985 10:06:38 am PDT Frank Bowers February 3, 1986 5:41:01 pm PST Preas, July 21, 1987 5:19:57 pm PDT get design data by reading Core connectivity and ChipnDale cells PROC [flatWire: CoreFlat.FlatWireRec] RETURNS [quit: BOOL _ FALSE]; PROC [flatWire: CoreFlat.FlatWireRec] RETURNS [quit: BOOL _ FALSE]; make a pin for each side that the pin is restricted to no side restriction, leave the pin free to move PROC [flatCellType: CoreFlat.FlatCellTypeRec, cell: Core.CellType, bindings: CoreFlat.Bindings, properties: Core.Properties] RETURNS [quit: BOOL _ FALSE]; do binding of public to actual; this is clumsy because of chane to Core Geometry add connection for comp, pin set up the private data get auxalliary components -- connect to power cells fix up the bus widths based on connectivity construct and add an entry to net list for this instance get physical description and define the type enter a new object into standard cell data structure get physical description and define the type enter a new object into standard cell data structure define the pins on the object object.pins _ DefinePinsFromBoundry[handle, object, ft]}; object.pins _ DefinePinsFromBoundry[handle, object, io]; object.pins _ DefinePinsFromBoundry[handle, object, logic]}; assign row and position to instance RETURNS TRUE if wire is restricted to side find position for wire on side Κ 3˜codešœ™KšœB™B—šœ5Οk™8Kšœ)™,Kšœ ™#—K˜K™@K˜š ˜ Kšœœ?œT˜©—K˜šΟnœœ˜!Kšœœsœ8œH˜Kšœ ˜Kšœœ˜K˜Kšœœœ˜K˜—šž œœ œ œ˜GKšœU˜UKšœœœ˜"K˜šžœ˜-KšœC™CKšœœ+˜>Kšœ6˜6KšœœœœA˜Ušœ.˜2K˜——šžœ˜-KšœC™CKšœœ+˜>KšœE˜EKšœ6˜6Kšœœœœ@˜TKšœ œœœh˜š œ œœœœ˜&K˜Kšœ˜šœ&œ˜/Kšœ6™6šœœ˜/šœ!œ˜)KšœS˜SKšœ[˜[Kšœ˜KšœN˜N—Kšœ˜—K˜Kšœ/™/šœ œœ˜KšœS˜SKšœ_˜_———K˜—šž œ!˜-Kšœš™šK˜šž œœ˜,Kšœœ(˜:šœ&˜,KšœQ™QKšœ˜Kšœœ*˜NKšœœ,˜?Kšœ6˜6Kšœ@Οc˜NK˜šœœ˜Kšœœ‘˜”—šœ œ˜Kšœœ€˜ƒ—š œ œœœœ˜%Kšœ™Kšœœœ˜˜>Kšœ=˜=Kšœ=˜=K˜Kšœ<˜˜>Kšœ?˜?Kšœœ'˜Kš œœœ œ œ˜:Kš œœœ œ œ˜K˜—Kšœ)œ˜FKšœ3˜3Kšœ9˜9Kšœ*˜*Kšœ4˜4Kšœ8˜8Kšœ/˜/K˜—Kšœ˜—…—6πJ