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]; 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. ζ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 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]}; Κ Ό˜codešœ™KšœB™B—šœ5Οk™8Kšœ)™,Kšœ#™#—K˜K™@K˜š ˜ Kšœrœ7œT˜ƒ—K˜šΟnœœ˜!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˜—šž œ!˜-Kš œœ9œœœœ˜cšžœ$˜3šœC˜IKšœQ™QKšœ?˜?KšœIΟc˜WK˜šœœ˜Kšœœ­˜°—šœ œ˜Kšœœ€˜ƒ—š œ œœœœ˜%Kšœ™Kšœœœ˜˜>Kšœ=˜=Kšœ=˜=K˜Kšœ<˜˜>Kšœ?˜?Kšœœ'˜˜>K˜—š žœœœœœ˜<šœœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœœ4˜A—K˜—šžœ œ œZœ˜‰š ž œœœœœ˜.šœœ˜Kšœœ(œœ˜DKšœœ#œœœœœœ˜^Kšœ˜ K˜——Kšœ6˜6K˜—šžœœœ œ ˜5K˜šžœ˜%Kšœœœ"œ˜LK˜—šžœ!˜)šžœ)œœ˜GK˜—Kšœ7˜7Kšœœœ"œ˜TK˜—šžœ˜"šžœ(œœ˜KK˜—Kšœ0˜0Kšœ œœœ˜>K˜—Kšœ)œ˜FKšœ3˜3Kšœ9˜9Kšœ*˜*Kšœ4˜4Kšœ8˜8Kšœ/˜/K˜—Kšœ˜—…—4C¦