RTStructureImpl.mesa
Copyright © 1986 by Xerox Corporation. All rights reversed.
Created by Bryan Preas, August 22, 1986 3:20:09 pm PDT
Bertrand Preas April 3, 1987 1:11:37 pm PST
DIRECTORY
DABasics, CD, CDBasics, CDSymbolicObjects, Convert, Core, CoreClasses, CoreFlat, CoreGeometry, CoreOps, RefTab, RProperties, PW, PWCore, PWPins, RefTabExtras, Rope, RTBasic, RTCoreUtil, RTStructure, TerminalIO;
RTStructureImpl: CEDAR PROGRAM
IMPORTS CD, CDBasics, CDSymbolicObjects, Convert, CoreClasses, CoreGeometry, CoreOps, RefTab, PW, PWCore, PWPins, RefTabExtras, Rope, RTBasic, RTCoreUtil, RTStructure, TerminalIO
EXPORTS RTStructure =
BEGIN
Errors
Error: PUBLIC ERROR[errorType: RTStructure.ErrorType ← callingError, explanation: Rope.ROPENIL] = CODE;
Signal: PUBLIC SIGNAL[signalType: RTStructure.ErrorType ← callingError, explanation: Rope.ROPENIL] = CODE;
Building and Using The Structure Table
Creating The Structure Table
CreateForRopes: PUBLIC PROC [name: Rope.ROPE, nInsts, nObjs, nNets, nPubs: NAT ← 17, netWidth: RTStructure.NetWidthProc ← WidestPinProc, properties: Core.Properties ← NIL] RETURNS [RTStructure.Structure] ~ {
RETURN[NEW[RTStructure.StructureRec ← [name: name, instances: RefTab.Create[nInsts, RefTabExtras.EqualRope, RefTabExtras.HashRope], objects: RefTab.Create[nObjs, RefTabExtras.EqualRope, RefTabExtras.HashRope], nets: RefTab.Create[nNets, RefTabExtras.EqualRope, RefTabExtras.HashRope], netWidth: netWidth -- , properties: CoreProperties.CopyProps[properties] -- ]]]};
Creates new structure for Rope keys.
Instance Manipulation
FetchInstance: PUBLIC PROC [structure: RTStructure.Structure, key: RTStructure.Key] RETURNS [found: BOOLEAN, instance: RTStructure.Instance] ~ {
looks up key in table, returns associated instance (if any)
if found is TRUE, net is value associated with given key
if found is FALSE, instance is NIL
val: REF;
[found, val] ← RefTab.Fetch[structure.instances, key];
instance ← NARROW[val]};
FetchInstancePin: PUBLIC PROC [instance: RTStructure.Instance, key: RTStructure.Key] RETURNS [found: BOOLEAN, iPin: RTStructure.InstancePin] ~ {
looks up key in table, returns associated instancePin (if any)
if found is TRUE, net is value associated with given key
if found is FALSE, instancePin is NIL
val: REF;
[found, val] ← RefTab.Fetch[instance.iPins, key];
iPin ← NARROW[val]};
EnumerateInstances: PUBLIC PROC [structure: RTStructure.Structure, action: RTStructure.EachInstanceAction] RETURNS [quit: BOOLEAN] ~ {
enumerates objects currently in symbol table in unspecified order
instances inserted/deleted during enumeration may or may not be seen
applies action to each object until action returns TRUE or no more pairs
returns TRUE if some action returns TRUE
Eachpair: RefTab.EachPairAction ~ {instance ← NARROW[val]; quit ← action[key, instance]};
instance: RTStructure.Instance;
RETURN[RefTab.Pairs[structure.instances, Eachpair]]};
EnumerateInstancePins: PUBLIC PROC [instance: RTStructure.Instance, action: RTStructure.EachInstancePinAction] RETURNS [quit: BOOLEAN] ~ {
enumerates pins on instance in unspecified order
pins inserted/deleted during enumeration may or may not be seen
applies action to each pin until action returns TRUE or no more pins
returns TRUE if some action returns TRUE
Eachpair: RefTab.EachPairAction ~ {
instancePin ← NARROW[val]; quit ← action[key, instance, instancePin]};
instancePin: RTStructure.InstancePin;
RETURN[RefTab.Pairs[instance.iPins, Eachpair]]};
Object Manipulation
FetchObject: PUBLIC PROC [structure: RTStructure.Structure, key: RTStructure.Key] RETURNS [found: BOOLEAN, object: RTStructure.Object] ~ {
looks up key in table, returns associated object (if any)
if found is TRUE, net is value associated with given key
if found is FALSE, net is NIL
val: REF;
[found, val] ← RefTab.Fetch[structure.objects, key];
object ← NARROW[val]};
FetchObjectPin: PUBLIC PROC [object: RTStructure.Object, key: RTStructure.Key] RETURNS [found: BOOLEAN, oPin: RTStructure.ObjectPin] ~ {
looks up key in table, returns associated objectPin (if any)
if found is TRUE, net is value associated with given key
if found is FALSE, objectPin is NIL
val: REF;
[found, val] ← RefTab.Fetch[object.oPins, key];
oPin ← NARROW[val]};
EnumerateObjects: PUBLIC PROC [structure: RTStructure.Structure, action: RTStructure.EachObjectAction] RETURNS [quit: BOOLEAN] ~ {
enumerates objects currently in symbol table in unspecified order
instances inserted/deleted during enumeration may or may not be seen
applies action to each object until action returns TRUE or no more pairs
returns TRUE if some action returns TRUE
Eachpair: RefTab.EachPairAction ~ {
object ← NARROW[val];
quit ← action[key, object]};
object: RTStructure.Object;
RETURN[RefTab.Pairs[structure.objects, Eachpair]]};
EnumerateObjectPins: PUBLIC PROC [object: RTStructure.Object, action: RTStructure.EachObjectPinAction] RETURNS [quit: BOOLEAN] ~ {
enumerates pins on object in unspecified order
pins inserted/deleted during enumeration may or may not be seen
applies action to each segment until action returns TRUE or no more segments
returns TRUE if some action returns TRUE
Eachpair: RefTab.EachPairAction ~ {
oPin ← NARROW[val];
quit ← action[key, object, oPin]};
oPin: RTStructure.ObjectPin;
RETURN[RefTab.Pairs[object.oPins, Eachpair]]};
EnumeratePhysicalPins: PUBLIC PROC [oPin: RTStructure.ObjectPin, action: RTStructure.EachPhysicalPinAction] RETURNS [quit: BOOLEANFALSE] ~ {
enumerates physical pins on ObjectPin in unspecified order
pins inserted/deleted during enumeration may or may not be seen
applies action to each segment until action returns TRUE or no more object pins
returns TRUE if some action returns TRUE
FOR list: LIST OF RTStructure.PhysicalPin ← oPin.physicalPins, list.rest WHILE list # NIL AND ~quit DO
quit ← action[oPin, list.first]
ENDLOOP;
};
PosOfObjectPin: PUBLIC PROC [object: RTStructure.Object, pPin: RTStructure.PhysicalPin] RETURNS [position: DABasics.Position] ~ {
returns position of object Pin wrt the object
position ← SELECT pPin.side FROM
bottom => [pPin.range.min, 0],
right => [CD.InterestSize[object.cdObject].x, pPin.range.min],
top => [pPin.range.min, CD.InterestSize[object.cdObject].y],
left => [0, pPin.range.min],
ENDCASE => [0, 0]};
Net Manipulation
FetchNet: PUBLIC PROC [structure: RTStructure.Structure, key: RTStructure.Key] RETURNS [found: BOOLEAN, net: RTStructure.Net] ~ {
looks up key in table, returns associated net (if any)
if found is TRUE, net is value associated with given key
if found is FALSE, net is NIL
val: REF;
[found, val] ← RefTab.Fetch[structure.nets, key];
net ← NARROW[val]};
FetchNetPin: PUBLIC PROC [net: RTStructure.Net, key: RTStructure.Key] RETURNS [found: BOOLEAN, nPin: RTStructure.NetPin] ~ {
looks up key in table, returns associated netPin (if any)
if found is TRUE, net is value associated with given key
if found is FALSE, netPin is NIL
val: REF;
[found, val] ← RefTab.Fetch[net.nPins, key];
nPin ← NARROW[val]};
EnumerateNets: PUBLIC PROC [structure: RTStructure.Structure, action: RTStructure.EachNetAction] RETURNS [quit: BOOLEAN] ~ {
enumerates nets currently in symbol table in unspecified order
nets inserted/deleted during enumeration may or may not be seen
applies action to each net until action returns TRUE or no more nets
returns TRUE if some action returns TRUE
eachPair: RefTab.EachPairAction ~ {
net ← NARROW[val];
quit ← action[key, net]};
net: RTStructure.Net;
RETURN[RefTab.Pairs[structure.nets, eachPair]]};
EnumerateNetPins: PUBLIC PROC [net: RTStructure.Net, action: RTStructure.EachNetPinAction] RETURNS [quit: BOOLEAN] ~ {
enumerates pins on net in unspecified order
pins inserted/deleted during enumeration may or may not be seen
applies action to each pin until action returns TRUE or no more pins
returns TRUE if some action returns TRUE
eachPair: RefTab.EachPairAction ~ {
nPin ← NARROW[val];
quit ← action[key, net, nPin]};
nPin: RTStructure.NetPin;
RETURN[RefTab.Pairs[net.nPins, eachPair]]};
WidestPinProc: PUBLIC RTStructure.NetWidthProc ~ {
PROC[net: Net, structure: Structure, direction: RTBasic.Direction, context: REF ANYNIL] RETURNS [wireWidth: INT]
EachNetPin: RTStructure.EachNetPinAction ~ {
PROC [key: Key, net: Net, nPin: NetPin] RETURNS [quit: BOOLEANFALSE];
EachPhysicalPin: RTStructure.EachPhysicalPinAction ~ {
PROC [oPin: ObjectPin, pPin: PhysicalPin] RETURNS [quit: BOOLEANFALSE];
wireWidth ← MAX[wireWidth, pPin.range.max - pPin.range.min]};
[] ← EnumeratePhysicalPins[nPin.oPin, EachPhysicalPin]};
wireWidth ← 0;
[] ← EnumerateNetPins[net, EachNetPin]};
IsPublic: PUBLIC PROC [net: RTStructure.Net] RETURNS [isPublic: BOOLEAN] ~ {
TRUE iff this tet has a connection to the next higher level
EachNetPin: RTStructure.EachNetPinAction ~ {
PROC [key: Key, net: Net, nPin: NetPin] RETURNS [quit: BOOLEANFALSE];
quit ← nPin.instance.object.heirarchyLevel = nextHigher};
isPublic ← EnumerateNetPins[net, EachNetPin]};
Utilities
CreateFromCore: PUBLIC PROC [root: Core.CellType, flattenCellType: RTCoreUtil.FlattenCellTypeProc, instanceName: RTStructure.InstanceName, wireName: RTStructure.WireName, interestingProperties: RTCoreUtil.PropertyKeys, decoration: CoreGeometry.Decoration, libDesign: CD.Design, properties: Core.Properties] RETURNS [ structure: RTStructure.Structure] ~ {
derive the interconnection requirements from a Core data structure.
structure is indexed by the following REFs:
instances: Core cellInstance of flattened object
instancePins: Core public wires on associated object
objects: Core cellType
objectPins: Core public wires on associated object
nets: Core actual wires of flattened object
netPins:
InternalWireProc: RTCoreUtil.FlatWireProc = {
PROC [flatWire: CoreFlat.FlatWireRec] RETURNS [quit: BOOLFALSE]
register the net using internal wire
pathName: Rope.ROPE ← wireName[root, flatWire];
net: RTStructure.Net ← NEW[RTStructure.NetRec ← [name: pathName, nPins: RefTab.Create[], properties: RTCoreUtil.CopyProps[flatWire.wire.properties, interestingProperties]]];
[] ← RTStructure.StoreNet[structure, pathName, net]};
ExternalWireProc: RTCoreUtil.FlatWireProc = {
PROC [flatWire: CoreFlat.FlatWireRec] RETURNS [quit: BOOLFALSE]
build and insert the external object pins from the public wire
pathName: Rope.ROPE ← wireName[root, flatWire];
objectPin: RTStructure.ObjectPin ← NEW[RTStructure.ObjectPinRec ← [name: pathName, heirarchyLevel: nextHigher, properties: RTCoreUtil.CopyProps[flatWire.wire.properties, interestingProperties]]];
netPin: RTStructure.NetPin ← NEW[RTStructure.NetPinRec ← [oPin: objectPin, instance: structure.outerInstance]];
net: RTStructure.Net ← FetchNet[structure, pathName].net;
instancePin: RTStructure.InstancePin ← NEW[RTStructure.InstancePinRec ← [oPin: objectPin, net: net]];
[] ← RTStructure.StoreObjectPin[structure.outerInstance.object, pathName, objectPin];
[] ← RTStructure.StoreInstancePin[structure.outerInstance, pathName, instancePin];
[] ← RTStructure.StoreNetPin[net, pathName, netPin]};
InstanceProc: RTCoreUtil.FlatInstanceProc = {
PROC [flatCellType: CoreFlat.FlatCellTypeRec, cell: Core.CellType, bindings: CoreFlat.Bindings, properties: Core.Properties] RETURNS [quit: BOOLFALSE];
EachPublic: PROC [publicWire: Core.Wire] = {
EachObjectPin: RTStructure.EachObjectPinAction ~ {
-- PROC [key: Key, object: Object, oPin: ObjectPin] RETURNS [quit: BOOLEANFALSE];
IF Rope.Equal[oPin.name, name] THEN {
IF net # NIL THEN {
add connection for comp, pin
netPin: RTStructure.NetPin ← NEW[RTStructure.NetPinRec ← [oPin: oPin, instance: instance]];
instancePin: RTStructure.InstancePin ← NEW[RTStructure.InstancePinRec ← [oPin: oPin, net: net]];
[] ← RTStructure.StoreInstancePin[instance, Rope.Cat[name, oPin.name], instancePin];
[] ← RTStructure.StoreNetPin[net, Rope.Cat[instance.name, oPin.name], netPin]}}};
flatWire: CoreFlat.FlatWire ← NARROW [RefTab.Fetch[bindings, publicWire].val];
name: Rope.ROPE ← wireName[root, flatWire^];
net: RTStructure.Net ← FetchNet[structure, flatWire.wire].net;
IF net = NIL THEN
Signal[callingError, Rope.Cat[Rope.Cat["Net not defined: ", name, " on component: ", instance.name], Rope.Cat[", type: ", object.name]]];
[] ← EnumerateObjectPins[object, EachObjectPin]}; -- get the pin
instName: Rope.ROPE ← instanceName[root, flatCellType];
object: RTStructure.Object ← DefineObject[structure, cell, interestingProperties, decoration, libDesign];
instance: RTStructure.Instance ← DefineInstance[structure, object, instName, properties, interestingProperties];
CoreOps.VisitRootAtomics[cell.public, EachPublic]};
outerName: Rope.ROPE ← CoreOps.GetCellTypeName[root];
outerObject: RTStructure.Object ← NEW[RTStructure.ObjectRec ← [name: outerName, cdObject: NIL, heirarchyLevel: nextHigher, oPins: RefTab.Create[], properties: RTCoreUtil.CopyProps[root.properties, interestingProperties]]];
outerInstance: RTStructure.Instance ← NEW[RTStructure.InstanceRec ← [name: outerName, object: outerObject, iPins: RefTab.Create[]]];
outerCoreInstance: CoreClasses.CellInstance ← CoreClasses.CreateInstance[NIL, root];
structure ← CreateForRopes[name: outerName];
[] ← RTStructure.StoreInstance[structure, outerName, outerInstance];
[] ← RTStructure.StoreObject[structure, outerName, outerObject];
structure.outerInstance ← outerInstance;
TerminalIO.PutRope["Getting structure description . . .\n"];
RTCoreUtil.Flatten[root, flattenCellType, ExternalWireProc, InternalWireProc, InstanceProc, interestingProperties]};
InsertPublic: PUBLIC PROC [structure: RTStructure.Structure, name: Rope.ROPE, cdObject: CD.Object, pinFilter: RTStructure.CDPinFilterProc, userData: REF ANY, makeHashKey: RTStructure.HashKeyProc] ~ {
construct an instance, an object and put the pins on the interest rec of the object in the structure if pinFilter returns true. makeHashKey can be used to transform the pin names to net names.
Ropes are use for keys; this means that CreateForRopes must be used to create the structure used by theis procedure. In addition, the obhect and pins must be named.
};
InsertInstance: PUBLIC PROC [structure: RTStructure.Structure, name: Rope.ROPE, position: DABasics.Position, orientation: DABasics.Orientation, cdObject: CD.Object, pinFilter: RTStructure.CDPinFilterProc, userData: REF ANY, makeHashKey: RTStructure.HashKeyProc] ~ {
construct an instance, an object and put the pins on the interest rec of the object in the structure if pinFilter returns true. makeHashKey can be used to transform the pin names to net names.
Ropes are use for keys; this means that CreateForRopes must be used to create the structure used by theis procedure. In addition, the obhect and pins must be named.
EachInstPin: CDSymbolicObjects.InstEnumerator = {
[inst: CD.Instance] RETURNS [quit: BOOLFALSE]
usePin: BOOLEANIF pinFilter = NIL THEN TRUE ELSE pinFilter[inst, cdObject, userData];
IF usePin THEN {
InsertInstPin[structure, object, instance, inst, makeHashKey]}};
EachObjPin: CDSymbolicObjects.InstEnumerator = {
[inst: CD.Instance] RETURNS [quit: BOOLFALSE]
usePin: BOOLEANIF pinFilter = NIL THEN TRUE ELSE pinFilter[inst, cdObject, userData];
IF usePin THEN {
InsertObjectPin[structure, object, cdObject, inst, makeHashKey]}};
object: RTStructure.Object;
instance: RTStructure.Instance;
IF cdObject # NIL THEN {
objectName: Rope.ROPE ← RTBasic.GetCDCellName[cdObject];
object ← FetchObject[structure, objectName].object;
IF object = NIL THEN {
object ← NEW[RTStructure.ObjectRec ← [objectName, cdObject, this, RefTab.Create[equal: RefTabExtras.EqualRope, hash: RefTabExtras.HashRope] -- , properties: CoreProperties.CopyProps[cdObject.properties] -- ]];
[] ← RTStructure.StoreObject[structure, objectName, object];
[] ← PWPins.EnumerateEdgePins[cdObject, EachObjPin]};
instance ← NEW[RTStructure.InstanceRec ← [name, TRUE, position, orientation, object, RefTab.Create[equal: RefTabExtras.EqualRope, hash: RefTabExtras.HashRope]]];
[] ← RTStructure.StoreInstance[structure, name, instance];
[] ← PWPins.EnumerateEdgePins[cdObject, EachInstPin]}};
PrintStructure: PUBLIC PROC [structure: RTStructure.Structure] ~ {
print the given structure
TerminalIO.PutRopes["Writing structure for: ", structure.name, "\n"];
TerminalIO.PutRope[" Objects\n"];
[] ← EnumerateObjects[structure, PrintObject];
TerminalIO.PutRope[" Instances\n"];
[] ← EnumerateInstances[structure, PrintInstance];
TerminalIO.PutRope[" Nets\n"];
[] ← EnumerateNets[structure, PrintNet]};
Internal Procedures
make a segment from a pin (inst) on an object and put it in the table
InsertInstPin: PROC [structure: RTStructure.Structure, object: RTStructure.Object, instance: RTStructure.Instance, pin: CD.Instance, makeHashKey: RTStructure.HashKeyProc] ~ {
netPin: RTStructure.NetPin;
instancePin: RTStructure.InstancePin;
pinName: Rope.ROPE ← CDSymbolicObjects.GetName[pin];
tabIndex: Rope.ROPEIF makeHashKey=NIL THEN pinName ELSE makeHashKey[pin];
netPinName: Rope.ROPE ← Rope.Cat[tabIndex, "/", instance.name];
rect: CD.Rect ← CDSymbolicObjects.Denotes[pin];
objectPin: RTStructure.ObjectPin ← FetchObjectPin[object, tabIndex].oPin;
net: RTStructure.Net ← FetchNet[structure, tabIndex].net;
IF net = NIL THEN {
net ← NEW[RTStructure.NetRec ← [name: tabIndex, nPins: RefTab.Create[equal: RefTabExtras.EqualRope, hash: RefTabExtras.HashRope]]];
[] ← RTStructure.StoreNet[structure, tabIndex, net]};
netPin ← NEW[RTStructure.NetPinRec ← [oPin: objectPin, instance: instance]];
instancePin ← NEW[RTStructure.InstancePinRec ← [oPin: objectPin, net: net]];
[] ← RTStructure.StoreInstancePin[instance, netPinName, instancePin];
[] ← RTStructure.StoreNetPin[net, netPinName, netPin]};
make an object pin from pin (inst) on an object and put it in the table
InsertObjectPin: PROC [structure: RTStructure.Structure, object: RTStructure.Object, cdObject: CD.Object, pin: CD.Instance, makeHashKey: RTStructure.HashKeyProc] ~ {
physicalPin: RTStructure.PhysicalPin;
pinName: Rope.ROPE ← CDSymbolicObjects.GetName[pin];
tabIndex: Rope.ROPEIF makeHashKey=NIL THEN pinName ELSE makeHashKey[pin];
side: RTBasic.Side ← FromSideToSide[PWPins.GetSide[cdObject, pin].side];
outsideRect: CD.Rect ← CD.InterestRect[cdObject];
pinRect: CD.Rect ← CDSymbolicObjects.Denotes[pin];
depth: INTSELECT side FROM
bottom => pinRect.y1 - outsideRect.y1,
right => outsideRect.x2 - pinRect.x2,
top => outsideRect.y2 - pinRect.y2,
left => pinRect.x1 - outsideRect.x1,
ENDCASE => Error[programmingError, "Call maintainer"];
objectPin: RTStructure.ObjectPin ← FetchObjectPin[object, tabIndex].oPin;
IF objectPin = NIL THEN {
objectPin ← NEW[RTStructure.ObjectPinRec ← [name: tabIndex, heirarchyLevel: this -- , properties: CoreProperties.CopyProps[pin.properties] -- ]];
[] ← RTStructure.StoreObjectPin[object, tabIndex, objectPin]};
physicalPin ← NEW[RTStructure.PhysicalPinRec ← [range: CoordsAlongSide[pin, cdObject, side], side: side, layer: CDSymbolicObjects.GetLayer[pin], depth: depth -- , properties: CoreProperties.CopyProps[pin.properties] -- ]];
RTStructure.StorePhysicalPin[objectPin, physicalPin]};
CoordsAlongSide: PUBLIC PROC [instance: CD.Instance, object: CD.Object, side: RTBasic.Side] RETURNS [range: RTStructure.Range] ~ {
pos: DABasics.Position ← instance.trans.off;
size: DABasics.Position ← CDBasics.SizeOfRect[CDSymbolicObjects.Denotes[instance]];
SELECT side FROM
top, bottom => range ← [pos.x, pos.x + size.x];
left, right => range ← [pos.y, pos.y + size.y];
ENDCASE};
FromSideToSide: PUBLIC PROC [side: PWPins.Side] RETURNS [routeSide: RTBasic.Side] = {
routeSide ← SELECT side FROM
left => left,
right => right,
top => top,
bottom => bottom,
ENDCASE => ERROR};
DefineObject: PROC [structure: RTStructure.Structure, cellType: Core.CellType, interestingProperties: RTCoreUtil.PropertyKeys, decoration: CoreGeometry.Decoration, libDesign: CD.Design] RETURNS [object: RTStructure.Object] = {
EachWire: PROC [wire: Core.Wire] ~ {
construct object pins for this object
name: Rope.ROPE ← CoreOps.GetShortWireName[wire];
objectPin: RTStructure.ObjectPin ← NEW[RTStructure.ObjectPinRec ← [name: name, heirarchyLevel: this -- , properties: CoreProperties.CopyProps[wire.properties] -- ]];
[] ← RTStructure.StoreObjectPin[object, wire, objectPin]};
EachPhysicalPin: CoreGeometry.EachWirePinProc = {
bind pin to public wire of object
PROC [wire: Wire, min, max: INT, side: Side, layer: CD.Layer] RETURNS [quit: BOOLFALSE];
rtSide: RTBasic.Side ← SELECT side FROM
bottom => bottom, right => right, top => top, left => left,
ENDCASE => RTBasic.Error[programmingError, "Not suppose to happen."];
range: RTStructure.Range ← [min, max];
depth: INT ← 0;
physicalPin: RTStructure.PhysicalPin ← NEW[RTStructure.PhysicalPinRec ← [range: range, side: rtSide, layer: layer, depth: depth, properties: RTCoreUtil.CopyProps[wire.properties, interestingProperties]]];
objectPin: RTStructure.ObjectPin ← FetchObjectPin[object, wire].oPin;
RTStructure.StorePhysicalPin[objectPin, physicalPin]};
cdObject: CD.Object ← NIL;
object ← FetchObject[structure, cellType].object;
IF object = NIL THEN {
objectName: Rope.ROPE ← CoreOps.GetCellTypeName[cellType];
get the ChipNDale object
IF PWCore.GetLayoutAtom[cellType] # NIL THEN cdObject ← PWCore.Layout[cellType]
ELSE IF libDesign # NIL THEN cdObject ← PW.Get[libDesign, objectName]
ELSE {
Signal[callingError, Rope.Cat["Core object: ", objectName, " not in found"]];
RETURN};
IF cdObject = NIL THEN {
Signal[callingError, Rope.Cat["Core object: ", objectName, " not in found"]];
RETURN};
define the object
object ← NEW[RTStructure.ObjectRec ← [name: objectName, cdObject: cdObject, heirarchyLevel: this, oPins: RefTab.Create[], properties: RTCoreUtil.CopyProps[cellType.properties, interestingProperties]]];
[] ← RTStructure.StoreObject[structure, objectName, object];
define the pins on the object
CoreOps.VisitRootAtomics[cellType.public, EachWire];
[] ← CoreGeometry.EnumerateNonOverlappingSides[decoration, cellType, EachPhysicalPin]}};
DefineInstance: PROC [structure: RTStructure.Structure, object: RTStructure.Object, name: Rope.ROPE, properties: Core.Properties, interestingProperties: RTCoreUtil.PropertyKeys] RETURNS [instance: RTStructure.Instance] = {
instance ← NEW[RTStructure.InstanceRec ← [name: name, object: object, iPins: RefTab.Create[] , properties: RTCoreUtil.CopyProps[properties, interestingProperties]]];
[] ← RTStructure.StoreInstance[structure, name, instance]};
PrintObject: RTStructure.EachObjectAction ~ {
PrintObjectPins: RTStructure.EachObjectPinAction ~ {
PrintPhysicalPins: RTStructure.EachPhysicalPinAction ~ {
TerminalIO.PutRope[Rope.Cat[" range: [", Convert.RopeFromInt[pPin.range.min], ", ", Convert.RopeFromInt[pPin.range.max], "], "]];
TerminalIO.PutRope[Rope.Cat["side: ", RTBasic.sideName[pPin.side], "\n"]]};
TerminalIO.PutRope[Rope.Cat[" ", oPin.name, IF object.heirarchyLevel = this THEN " this" ELSE " nextHigher"]];
[] ← EnumeratePhysicalPins[oPin, PrintPhysicalPins]};
TerminalIO.PutRope[Rope.Cat[" ", object.name, IF object.heirarchyLevel = this THEN " this" ELSE " nextHigher", "\n"]];
TerminalIO.PutRope[Rope.Cat[" connections: ", "\n"]];
[] ← EnumerateObjectPins[object, PrintObjectPins]};
PrintInstance: RTStructure.EachInstanceAction ~ {
PrintInstancePins: RTStructure.EachInstancePinAction ~ {
TerminalIO.PutRope[Rope.Cat[" net: ", iPin.net.name, ", pin: ", iPin.oPin.name, "\n"]];
};
TerminalIO.PutRope[Rope.Cat[" ", instance.name, "\n"]];
TerminalIO.PutRope[Rope.Cat[" position: [", Convert.RopeFromInt[instance.position.x], ", ", Convert.RopeFromInt[instance.position.y], "], \n"]];
TerminalIO.PutRope[Rope.Cat[" object: ", instance.object.name, "\n"]];
TerminalIO.PutRope[Rope.Cat[" connections: ", "\n"]];
[] ← EnumerateInstancePins[instance, PrintInstancePins]};
PrintNet: RTStructure.EachNetAction ~ {
PrintNetPins: RTStructure.EachNetPinAction ~ {
TerminalIO.PutRope[Rope.Cat[" instance: ", nPin.instance.name, ", pin: ", nPin.oPin.name, "\n"]];
};
TerminalIO.PutRope[Rope.Cat[" ", net.name, "\n"]];
TerminalIO.PutRope[Rope.Cat[" connections: ", "\n"]];
[] ← EnumerateNetPins[net, PrintNetPins]};
TranslateRange: PUBLIC PROC [instance: RTStructure.Instance, pPin: RTStructure.PhysicalPin] RETURNS [range: RTStructure.Range]~ {
find range of an instance pin
range ← SELECT pPin.side FROM
top, bottom => [instance.position.x + pPin.range.min, instance.position.x + pPin.range.max],
left, right => [instance.position.y + pPin.range.min, instance.position.y + pPin.range.max],
ENDCASE => RTBasic.Error[programmingError, "Call maintainer."];
};
END.