DIRECTORY CD, CDBasics, CDIO, CDSymbolicObjects, Core, CoreClasses, CoreDirectory, CoreOps, CoreProperties, PW, PWCore, PWPins, Rope, Route, RTBasic, RTCoreUtil, SC, SCInstUtil, SCObjUtil, SCNetUtil, SCPrivate, SCUtil, TerminalIO; SCGetStructureImpl: CEDAR PROGRAM IMPORTS CD, CDBasics, CDIO, CDSymbolicObjects, CoreClasses, CoreDirectory, CoreOps, CoreProperties, PW, PWCore, PWPins, Rope, RTBasic, RTCoreUtil, SC, SCInstUtil, SCObjUtil, SCNetUtil, SCUtil, TerminalIO EXPORTS SCPrivate SHARES SC = BEGIN debug: BOOLEAN _ FALSE; GetStructure: PUBLIC PROCEDURE [handle: SC.Handle, cellType: Core.CellType, flattenCellType: RTCoreUtil.FlattenCellTypeProc] 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 = { typeName: Rope.ROPE _ CoreOps.GetCellTypeName[cellInstance.type]; object: SCPrivate.Object _ SCUtil.FindObject[handle, typeName]; IF object = NIL THEN object _ DefineObject[handle, typeName, logic, cellInstance.type]; IF object = NIL THEN SC.Signal[callingError, Rope.Cat["Object is not defined: ", typeName, "\n"]] ELSE { EachInstancePin: RTCoreUtil.EachInstancePinProc = { pinName: Rope.ROPE _ CoreOps.GetShortWireName[publicWire]; IF ~SCUtil.IsPowerName[handle, pinName] THEN {net: SCPrivate.Net _ SCUtil.FindNetByWire[handle, actualWire]; pin: SCPrivate.ObjectPin _ SCUtil.FindPin[object, pinName]; -- 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 pin = NIL THEN {SC.Signal[callingError, Rope.Cat[Rope.Cat["not enough pins on component: ", instance.name], Rope.Cat[", type: ", object.name]]]}; IF pin # 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 _ objectPins.p[pinIndex]; IF objPin # NIL THEN IF Rope.Equal[objPin.name, pin.name] THEN SCNetUtil.AddConnection[handle, net, instance, objPin, pinIndex, compPin]; ENDLOOP}}}; instance: SCPrivate.Instance _ SCInstUtil.DefineInstance[handle, CoreClasses.GetCellInstanceName[cellInstance], object, cellInstance, NIL]; objectPins: SCPrivate.ObjectPins _ object.pins; IF objectPins = NIL THEN SC.Signal[callingError, Rope.Cat[Rope.Cat["Pins not defined on instance: ", instance.name], Rope.Cat[", object: ", object.name, "\n"]]] ELSE { [] _ 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]; parms.ftObject _ DefineFtType[handle, "feedthru"]; parms.vddObject _ DefinePowerType[handle, "vdd"]; parms.gndObject _ DefinePowerType[handle,"gnd"]; TerminalIO.WriteRope["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]; 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; numClocks: NAT _ 0; 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].width _ pWidth; powerBuses[lRSide].net _ net}; DefineObject: PROCEDURE [handle: SC.Handle, objectName: Rope.ROPE, class: SCPrivate.CompClass, cellType: Core.CellType _ NIL] RETURNS [object: SCPrivate.Object _ NIL] = { CountPins: PWPins.InstanceEnumerator = { IF UsePin[inst] THEN object.numPins _ object.numPins + 1}; UsePin: PROC [pin: CD.Instance] RETURNS [useIt: BOOLEAN _ FALSE] ~ { IF CDSymbolicObjects.IsSymbolicOb[pin.ob] THEN { side: PWPins.Side _ PWPins.GetSide[ob, pin]; IF side = top OR side = bottom OR useClass = io THEN useIt _ TRUE}}; structureData: SCPrivate.StructureData _ NARROW[handle.structureData]; objects: SCPrivate.Objects _ structureData.objects; parms: SCPrivate.Parms _ NARROW[handle.parms]; numPins: NAT _ 0; obRect: CD.Rect; useClass: SCPrivate.CompClass; size, orgin: RTBasic.PQPos; 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]; ct: Core.CellType _ CoreDirectory.Fetch[lib, objectName]; ob _ PWCore.Layout[ct]; IF class = other THEN useClass _ logic ELSE useClass _ ft; -- make power connection cells logic cells -- }; ENDCASE => { IF PWCore.GetLayoutAtom[cellType] # NIL THEN { ob _ PWCore.Layout[cellType]; useClass _ logic} ELSE IF parms.libName # NIL THEN { IF parms.libDesign # NIL THEN parms.libDesign _ CDIO.ReadDesign[parms.libName, NIL, CDIO.GetWorkingDirectory[]]; -- this is buggy!!! LMM ob _ PW.Get[parms.libDesign, objectName]; useClass _ logic}; }; IF ob = NIL THEN { SC.Signal[callingError, Rope.Cat["Core object: ", objectName, " not in CND library"]]; RETURN}; obRect _ CD.InterestRect[ob].r; size _ RTBasic.XYToPQ[horizontal, CDBasics.SizeOfRect[obRect]]; orgin _ RTBasic.XYToPQ[horizontal, CDBasics.BaseOfAnyRect[obRect]]; objects.count _ objects.count + 1; object _ NEW[SCPrivate.ObjectRec _ [objectName, objects.count, size, orgin, 0, NIL, useClass, 0, ob]]; objects.ob[objects.count] _ object; [] _ PWPins.EnumerateDeepPins[ob, CountPins]; object.pins _ NEW[SCPrivate.ObjectPinsRec[object.numPins]]; IF object.numPins > 0 THEN { PinEnum: PWPins.InstanceEnumerator = { name: Rope.ROPE _ CDSymbolicObjects.GetName[inst]; IF UsePin[inst] THEN {pinPos: SCPrivate.PinPos; rect: SC.Rect; objectPin: SCPrivate.ObjectPin; name: Rope.ROPE _ CDSymbolicObjects.GetName[inst]; layer: SC.Layer _ CDSymbolicObjects.GetLayer[inst]; [pinPos, rect] _ GetPinPos[inst.location, inst.ob.size, object, obRect]; objectPin _ NEW[SCPrivate.ObjectPinRec _ [name, pinPos, inst, rect, layer, name]]; object.pins.p[numPins] _ objectPin; numPins _ numPins + 1}}; [] _ PWPins.EnumerateDeepPins[ob, PinEnum]}; IF cellType # NIL THEN { WireEnum: RTCoreUtil.EachWireProc = { IF ~SCUtil.IsPowerName[handle, CoreOps.GetShortWireName[wire]] THEN {IF SCUtil.FindPin[object, CoreOps.GetShortWireName[wire]] = NIL THEN SC.Signal[callingError, Rope.Cat["Physical pins and logical pins on object: ", object.name, " do not correspond"]]}}; [] _ RTCoreUtil.EnumerateFlatWires[cellType.public, WireEnum]}}; DefineFtType: PROCEDURE [handle: SC.Handle, name: Rope.ROPE] RETURNS [object: SCPrivate.Object _ NIL] = { IF SCUtil.FindObject[handle, name] # NIL THEN { SC.Signal[callingError, Rope.Cat["Duplicate FeedThru object: ", name, "\n"]]; RETURN}; object _ DefineObject[handle, name, ft]; IF object = NIL THEN SC.Signal[callingError, Rope.Cat["FeedThru object is not defined: ", name, "\n"]]}; DefineIOType: PROCEDURE [handle: SC.Handle] RETURNS [object: SCPrivate.Object] = { object _ DefineObject[handle, NIL, io]; IF object = NIL THEN SC.Signal[callingError, "IO object is not defined \n"]}; DefinePowerType: PROCEDURE [handle: SC.Handle, name: Rope.ROPE] RETURNS [object: SCPrivate.Object _ NIL] = { IF SCUtil.FindObject[handle, name] # NIL THEN { SC.Signal[callingError, Rope.Cat["Duplicate Power object: ", name, "\n"]]; RETURN}; object _ DefineObject[handle, name, other]; IF object = NIL THEN SC.Signal[callingError, Rope.Cat["Power object is not defined: ", name, "\n"]]}; GetPinPos: PROCEDURE [loc, size: SC.Pos, object: SCPrivate.Object, obRect: CD.Rect] RETURNS [pinPos: SCPrivate.PinPos, rect: SC.Rect] = { px, py: SC.Number; rect.x1 _ loc.x - obRect.x1; rect.y1 _ loc.y - obRect.y1; rect.x2 _ loc.x + size.x - obRect.x1; rect.y2 _ loc.y + size.y - obRect.y1; py _ (rect.y1 + rect.y2)/2; px _ (rect.x1 + rect.x2)/2; IF py > object.size.q/2 THEN RETURN [[top, object.size.q - py, object.size.p - px], rect] ELSE RETURN [[bottom, py, px], rect]}; BuildIOObject: PROCEDURE [handle: SC.Handle] RETURNS [object: CD.Object _ PW.CreateEmptyCell[]] = { minSize: SC.Number _ handle.rules.rowRules.trunkWidth; [] _ PW.IncludeInCell[object, CDSymbolicObjects.CreateSegment[length: minSize]]; CDCells.SetInterestRect[object, [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]^; prop = SC.leftPowerProp => { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; layoutData.powerBuses[left].name _ NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]; layoutData.powerBuses[left].net _ net}; prop = SC.rightPowerProp => { layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; layoutData.powerBuses[right].name _ NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]; layoutData.powerBuses[right].net _ net}; 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]; structureData.objects _ NIL; structureData.instances _ NIL; structureData.nets _ NIL; handle.structureData _ NIL}; END. ΆSCGetStructureImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last Edited by: Preas, September 9, 1985 10:06:38 am PDT Last Edited by: Louis Monier December 15, 1986 10:51:22 pm PST Frank Bowers February 3, 1986 5:41:01 pm PST Preas, September 8, 1986 5:20:55 pm PDT get design data by reading Core connectivity and ChipnDale cells 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 IF class = io THEN { ob _ BuildIOObject[handle]; useClass _ io} ELSE IF class = ft OR class = other THEN { lib: CoreDirectory.Library _ CoreDirectory.FetchLibrary[parms.libName]; ct: Core.CellType _ CoreDirectory.Fetch[lib, objectName]; ob _ PWCore.Layout[ct]; IF class = other THEN useClass _ logic ELSE useClass _ ft; -- make power connection cells logic cells -- } ELSE IF PWCore.GetLayoutAtom[cellType] # NIL THEN {ob _ PWCore.Layout[cellType]; useClass _ logic} ELSE IF parms.libName # NIL THEN { IF parms.libDesign # NIL THEN parms.libDesign _ CDIO.ReadDesign[parms.libName, NIL, CDIO.GetWorkingDirectory[]]; ob _ PW.Get[parms.libDesign, objectName]; useClass _ logic}; define the pins on the object check physical pins against the logical pins analyze cell for relevant parameters Κ'˜šœ™Icodešœ Οmœ1™<—šœ5Οk™8K™>Kšœ)ž™,Kšœ$ž™'—J˜J™@J˜šž ˜ Jšžœ žœPžœ3žœC˜ή—J˜šΟnœžœž˜!Kš žœžœ žœJžœ-žœ7˜ΜKšžœ ˜Kšžœžœ˜ K˜Kšž˜K˜Kšœžœžœ˜K˜šŸ œžœž œ žœ!˜KKšœ0˜0Kšžœžœžœ˜"K˜šŸœ˜-Jšœ8˜8JšžœžœžœžœA˜Ušž˜Jšœ3˜3J˜——šŸœ˜-JšœE˜EJšœ8˜8Jšžœžœžœžœ@˜TJšžœ žœžœžœh˜š žœ žœžœžœžœ'ž˜NJšœJžœ"˜oJšœ[˜[J˜Jšœ/˜/—J˜—šŸ œ!˜-Jšœžœ.˜AJšœ?˜?šžœ žœžœ˜KšœB˜B—šžœ žœžœ˜KšžœJ˜L—šžœ˜šŸœ$˜3Jšœ:˜:šžœ&ž˜,Jšœ?˜?Kšœ<Οc˜JK˜šžœžœž˜Kšœžœ­˜°—šžœžœž˜Kšœžœ€˜ƒ—š žœžœžœžœžœ˜!Kšœ™Kšžœžœžœ˜Jšœ`žœ˜zK™Kš ™KšžœžœA˜YJšžœžœA˜YK™Kšœ+™+Jšœ˜Jšœ˜Jšžœžœ ˜-K˜—š Ÿœžœ žœžœ@žœ˜‚K˜JšœSžœžœ˜]Jšœ9™9Jšœ<˜˜>K˜—š Ÿœžœžœžœžœ˜<šœžœž˜Kšžœ˜Kšžœ˜Kšžœ˜Kšžœ˜Kšžœžœ3˜@—K˜K˜—šŸœž œ žœO˜uš Ÿ œžœžœžœžœ˜.šžœžœž˜Kšœžœ(žœžœ˜DKš œžœ#žœžœžœ˜Bšœžœ˜Kšœ#žœ˜=Kšœ#žœ5˜^Kšœ'˜'—šœžœ˜Kšœ#žœ˜=Kšœ$žœ5˜_Kšœ(˜(—Kšžœ˜—Kšœ˜—Kšœ6˜6—K˜šŸœžœžœ žœ ˜5K˜šŸœ˜%šŸœ˜"Kšœžœ˜K˜—Kšœ6˜6Kšœžœ˜Kšœžœ˜Kšœžœ˜$K˜—šŸœ!˜)šŸœ˜#Kšœ žœžœ˜$K˜—Kšœ7˜7Kšœžœ˜Kšœžœ˜Kšœžœ˜$K˜—šŸœ˜"šŸœ˜"Kšœ žœžœ˜)K˜—Kšœ0˜0Kšœ žœ˜Kšœ žœ˜Kšœžœ˜K˜—Kšœ)žœ˜FKšœ3˜3Kšœ9˜9Kšœ*˜*Kšœ4˜4Kšœ8˜8Kšœ.˜.K˜Kšœžœ˜Kšœžœ˜Kšœžœ˜Kšœžœ˜K˜—Jšžœ˜——…—4|HY