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, CoreClasses, 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]}}; InstanceProc: RTCoreUtil.FlatInstanceProc = { 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, CoreClasses.GetCellInstanceName[cellInstance], object, cellInstance, NIL]; [] _ RTCoreUtil.EnumFlatInstancePins[cellInstance, EachInstancePin]; GetLogicProperties[handle, instance, cellInstance]}; hasVddConnection, hasGndConnection: BOOLEAN _ 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]; 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] ~ { inst: 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, inst, object.pins.p[0], 0, compPin]; SCNetUtil.AddConnection[handle, net, inst, 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; rules: Route.DesignRules _ handle.rules.sideRules; minWidth: INT _ rules.CDLambda*24 + rules.trunkSpacing; net: SCPrivate.Net _ SCUtil.FindNet[handle, powerBuses[lRSide].name]; pWidth: SC.Number _ IF net # NIL THEN MAX[minWidth, net.trunkWidth + rules.trunkSpacing] ELSE minWidth; 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; inst: CD.Instance _ CDSymbolicObjects.CreateSymInst[name: name, denotes: rect, layer: layer, approachFrom: SCUtil.DirectionFromSide[side]]; objectPins.p[numPins] _ NEW[SCPrivate.ObjectPinRec _ [name: name, pinPos: [scSide, 0, (max+min)/2], cdPin: inst, 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.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.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.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: Route.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] = { ProcProps: PROC [prop: ATOM, val: REF ANY] ~ { SELECT TRUE FROM prop = SC.sideProp => instance.fnlSide _ GetSide[NARROW[val, ATOM]]; prop = SC.positionProp => instance.fnlPos _ NARROW[val, REF INT]^; ENDCASE}; CoreProperties.Enumerate[wire.properties, ProcProps]}; DestroyStructure: PUBLIC PROC [handle: SC.Handle] ~ { EachObj: SCObjUtil.EachObjectProc ~ { EachPin: SCObjUtil.EachPinProc ~ {objectPin.cdPin _ NIL}; [] _ SCObjUtil.EnumeratePinsOnObject[object, EachPin]; 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 c 1986 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, January 9, 1987 7:03:49 pm PST get design data by reading Core connectivity and ChipnDale cells do binding of public to actual; this is clumsy because of chaneg 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]}; Κ θ˜codešœ™Kšœ Οmœ1™<—šœ5Οk™8Kšœ)ž™,Kšœ"ž™%—K˜K™@K˜šž ˜ Kšžœržœ7žœT˜ƒ—K˜šΟnœžœž˜!Kšžœžœkžœ0žœH˜ρKšžœ ˜Kšžœžœ˜ K˜Kšž˜K˜Kšœžœžœ˜K˜šŸ œžœž œ žœ!˜KKšœU˜UKšžœžœžœ˜"K˜šŸœ˜-Kšœ8˜8KšžœžœžœžœA˜Ušžœ4˜8K˜——šŸœ˜-KšœE˜EKšœ8˜8Kšžœžœžœžœ@˜TKšžœ žœžœžœh˜š žœ žœžœžœžœ'ž˜NKšœJžœ"˜oKšœ[˜[K˜Kšœ/˜/—K˜—šŸ œ!˜-šŸœ$˜3šžœCž˜IKšœR™RKšœ?˜?KšœIΟc˜WK˜šžœžœž˜Kšœžœ­˜°—šžœ žœž˜Kšœžœ€˜ƒ—š žœ žœžœžœžœ˜%Kšœ™Kšžœžœžœ˜˜>Kšœ=˜=Kšœ=˜=K˜Kšœ<˜˜>Kšœ?˜?Kšœžœ'˜˜>K˜—š Ÿœžœžœžœžœ˜<šœžœž˜Kšžœ˜Kšžœ˜Kšžœ˜Kšžœ˜Kšžœžœ4˜A—K˜—šŸœž œ žœO˜uš Ÿ œžœžœžœžœ˜.šžœžœž˜Kšœžœ(žœžœ˜DKš œžœ#žœžœžœ˜BKšžœ˜ K˜——Kšœ6˜6—K˜šŸœžœžœ žœ ˜5K˜šŸœ˜%šŸœ-žœ˜9K˜—Kšœ6˜6Kšœžœžœ"žœ˜LK˜—šŸœ!˜)šŸœ)žœžœ˜GK˜—Kšœ7˜7Kšœžœžœ"žœ˜TK˜—šŸœ˜"šŸœ(žœžœ˜KK˜—Kšœ0˜0Kšœ žœžœžœ˜>K˜—Kšœ)žœ˜FKšœ3˜3Kšœ9˜9Kšœ*˜*Kšœ4˜4Kšœ8˜8Kšœ/˜/K˜—Kšžœ˜——…—4μDΈ