Building and Using The Structure Table
Creating The Structure Table
CreateForRopes:
PUBLIC
PROC [name: Rope.
ROPE, nInsts, nObjs, nNets, nPubs: HashTable.SeqIndex ← 17, netWidth: RTStructure.NetWidthProc ← WidestPinProc, properties: Properties.PropList ←
NIL]
RETURNS [RTStructure.Structure] ~ {
RETURN[NEW[RTStructure.StructureRec ← [name: name, instances: HashTable.Create[nInsts, HashTable.RopeEqual, HashTable.HashRope], objects: HashTable.Create[nObjs, HashTable.RopeEqual, HashTable.HashRope], nets: HashTable.Create[nNets, HashTable.RopeEqual, HashTable.HashRope], netWidth: netWidth -- , properties: CoreProperties.CopyProps[properties] -- ]]]};
Creates new structure for Rope keys.
CreateForRefs:
PUBLIC
PROC [name: Rope.
ROPE, nInsts, nObjs, nNets, nPubs: HashTable.SeqIndex ← 17, netWidth: RTStructure.NetWidthProc ← WidestPinProc, properties: Properties.PropList ←
NIL]
RETURNS [RTStructure.Structure] ~ {
RETURN[NEW[RTStructure.StructureRec ← [name: name, instances: HashTable.Create[nInsts], objects: HashTable.Create[nObjs], nets: HashTable.Create[nNets], netWidth: netWidth -- , properties: CoreProperties.CopyProps[properties] -- ]]]};
Creates new structure for REF 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
value: REF;
[found, value] ← HashTable.Fetch[structure.instances, key];
instance ← NARROW[value]};
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
value: REF;
[found, value] ← HashTable.Fetch[instance.iPins, key];
iPin ← NARROW[value]};
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: HashTable.EachPairAction ~ {
TRUSTED{instance ← LOOPHOLE[value]};
quit ← action[key, instance]};
instance: RTStructure.Instance;
RETURN[HashTable.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: HashTable.EachPairAction ~ {
TRUSTED{instancePin ← LOOPHOLE[value]};
quit ← action[key, instance, instancePin]};
instancePin: RTStructure.InstancePin;
RETURN[HashTable.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
value: REF;
[found, value] ← HashTable.Fetch[structure.objects, key];
object ← NARROW[value]};
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
value: REF;
[found, value] ← HashTable.Fetch[object.oPins, key];
oPin ← NARROW[value]};
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: HashTable.EachPairAction ~ {
TRUSTED{object ← LOOPHOLE[value]};
quit ← action[key, object]};
object: RTStructure.Object;
RETURN[HashTable.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: HashTable.EachPairAction ~ {
TRUSTED{oPin ← LOOPHOLE[value]};
quit ← action[key, object, oPin]};
oPin: RTStructure.ObjectPin;
RETURN[HashTable.Pairs[object.oPins, eachPair]]};
EnumeratePhysicalPins:
PUBLIC
PROC [oPin: RTStructure.ObjectPin, action: RTStructure.EachPhysicalPinAction]
RETURNS [quit:
BOOLEAN ←
FALSE] ~ {
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:
CD.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
value: REF;
[found, value] ← HashTable.Fetch[structure.nets, key];
net ← NARROW[value]};
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
value: REF;
[found, value] ← HashTable.Fetch[net.nPins, key];
nPin ← NARROW[value]};
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: HashTable.EachPairAction ~ {
TRUSTED{net ← LOOPHOLE[value]};
quit ← action[key, net]};
net: RTStructure.Net;
RETURN[HashTable.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: HashTable.EachPairAction ~ {
TRUSTED{nPin ← LOOPHOLE[value]};
quit ← action[key, net, nPin]};
nPin: RTStructure.NetPin;
RETURN[HashTable.Pairs[net.nPins, eachPair]]};
WidestPinProc:
PUBLIC RTStructure.NetWidthProc ~ {
PROC[net: Net, structure: Structure, direction: RTBasic.Direction, context: REF ANY ← NIL] RETURNS [wireWidth: INT]
EachNetPin: RTStructure.EachNetPinAction ~ {
PROC [key: Key, net: Net, nPin: NetPin] RETURNS [quit: BOOLEAN ← FALSE];
EachPhysicalPin: RTStructure.EachPhysicalPinAction ~ {
PROC [oPin: ObjectPin, pPin: PhysicalPin] RETURNS [quit: BOOLEAN ← FALSE];
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: BOOLEAN ← FALSE];
quit ← nPin.instance.object.heirarchyLevel = nextHigher};
isPublic ← EnumerateNetPins[net, EachNetPin]};
Utilities
CreateFromCore:
PUBLIC
PROC [cellType: Core.CellType, flattenCellType: RTCoreUtil.FlattenCellTypeProc, pinFilter: RTStructure.CorePinFilterProc ←
NIL, interestingProperties: RTCoreUtil.PropertyKeys, userData:
REF
ANY ←
NIL, decoration: CoreGeometry.Decoration, libDesign:
CD.Design, properties: Properties.PropList]
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 [wire: Core.Wire, pathName: Rope.ROPE]
register the net using internal wire
net: RTStructure.Net ← NEW[RTStructure.NetRec ← [name: pathName, nPins: HashTable.Create[] -- , properties: CoreProperties.CopyProps[wire.properties] -- ]];
[] ← RTStructure.StoreNet[structure, wire, net]};
ExternalWireProc: RTCoreUtil.FlatWireProc = {
PROC [wire: Core.Wire, pathName: Rope.ROPE]
build and insert the external object pins from the public wire
objectPin: RTStructure.ObjectPin ← NEW[RTStructure.ObjectPinRec ← [name: pathName, heirarchyLevel: nextHigher -- , properties: CoreProperties.CopyProps[wire.properties] -- ]];
netPin: RTStructure.NetPin ← NEW[RTStructure.NetPinRec ← [oPin: objectPin, instance: structure.outerInstance]];
net: RTStructure.Net ← FetchNet[structure, wire].net;
instancePin: RTStructure.InstancePin ← NEW[RTStructure.InstancePinRec ← [oPin: objectPin, net: net]];
[] ← RTStructure.StoreObjectPin[structure.outerInstance.object, wire, objectPin];
[] ← RTStructure.StoreInstancePin[structure.outerInstance, wire, instancePin];
[] ← RTStructure.StoreNetPin[net, wire, netPin]};
InstanceProc: RTCoreUtil.FlatInstanceProc = {
PROC [cellInstance: CoreClasses.CellInstance, pathName: Rope.ROPE]
EachInstancePin: RTCoreUtil.EachInstancePinProc = {
PROC [actualWire, publicWire: Wire] RETURNS [subWires: BOOL ← TRUE, quit: BOOL ← FALSE]
EachObjectPin: RTStructure.EachObjectPinAction ~ {
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, publicWire, instancePin];
[] ← RTStructure.StoreNetPin[net, netPin, netPin]}}};
name: Rope.ROPE ← CoreOps.GetShortWireName[publicWire];
net: RTStructure.Net ← FetchNet[structure, actualWire].net;
IF net =
NIL
THEN
Signal[callingError, Rope.Cat[Rope.Cat["Net not defined: ", CoreOps.GetShortWireName[actualWire], " on component: ", instance.name], Rope.Cat[", type: ", object.name]]];
[] ← EnumerateObjectPins[object, EachObjectPin]; -- get the pin
object: RTStructure.Object ← DefineObject[structure, cellInstance.type, pinFilter, userData, decoration, libDesign];
instance: RTStructure.Instance ← DefineInstance[structure, object, cellInstance];
[] ← RTCoreUtil.EnumFlatInstancePins[cellInstance, EachInstancePin]};
outerName: Rope.ROPE ← CoreOps.GetCellTypeName[cellType];
outerObject: RTStructure.Object ← NEW[RTStructure.ObjectRec ← [name: outerName, cdObject: NIL, heirarchyLevel: nextHigher, oPins: HashTable.Create[] -- , properties: CoreProperties.CopyProps[cellType.properties] -- ]];
outerInstance: RTStructure.Instance ← NEW[RTStructure.InstanceRec ← [name: CoreOps.GetCellTypeName[cellType], object: outerObject, iPins: HashTable.Create[]]];
outerCoreInstance: CoreClasses.CellInstance ← CoreClasses.CreateInstance[NIL, cellType];
structure ← CreateForRefs[name: CoreOps.GetCellTypeName[cellType]];
[] ← RTStructure.StoreInstance[structure, outerCoreInstance, outerInstance];
[] ← RTStructure.StoreObject[structure, cellType, outerObject];
structure.outerInstance ← outerInstance;
TerminalIO.WriteRope["Getting structure description . . .\n"];
RTCoreUtil.Flatten[cellType, 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:
CD.Position, orientation:
CD.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: BOOL ← FALSE]
usePin: BOOLEAN ← IF 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: BOOL ← FALSE]
usePin: BOOLEAN ← IF 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 ← CDDirectory.Name[cdObject];
object ← FetchObject[structure, objectName].object;
IF object =
NIL
THEN {
object ← NEW[RTStructure.ObjectRec ← [objectName, cdObject, this, HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope] -- , properties: CoreProperties.CopyProps[cdObject.properties] -- ]];
[] ← RTStructure.StoreObject[structure, objectName, object];
[] ← PWPins.EnumerateEdgePins[cdObject, EachObjPin]};
instance ← NEW[RTStructure.InstanceRec ← [name, TRUE, position, orientation, object, HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.HashRope]]];
[] ← RTStructure.StoreInstance[structure, name, instance];
[] ← PWPins.EnumerateEdgePins[cdObject, EachInstPin]}};
PrintStructure:
PUBLIC
PROC [structure: RTStructure.Structure] ~ {
print the given structure
TerminalIO.WriteRopes["Writing structure for: ", structure.name, "\n"];
TerminalIO.WriteRope[" Objects\n"];
[] ← EnumerateObjects[structure, PrintObject];
TerminalIO.WriteRope[" Instances\n"];
[] ← EnumerateInstances[structure, PrintInstance];
TerminalIO.WriteRope[" 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.ROPE ← IF 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: HashTable.Create[equal: HashTable.RopeEqual, hash: HashTable.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.ROPE ← IF 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:
INT ←
SELECT 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: CD.Position ← PW.GetLocation[instance, object];
size: CD.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, pinFilter: RTStructure.CorePinFilterProc, userData:
REF
ANY, 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: BOOL ← FALSE];
rtSide: RTBasic.Side ←
SELECT side
FROM
bottom => bottom, right => right, top => top, left => left,
ENDCASE => RTBasic.Error[programmingError, "Not suppose to happen."];
usePin: BOOLEAN ← IF pinFilter = NIL THEN TRUE ELSE pinFilter[wire, [min, max], rtSide, layer, userData];
IF usePin
THEN {
range: RTStructure.Range ← [min, max];
depth: INT ← 0;
physicalPin: RTStructure.PhysicalPin ← NEW[RTStructure.PhysicalPinRec ← [range: range, side: rtSide, layer: layer, depth: depth -- , properties: CoreProperties.CopyProps[wire.properties] -- ]];
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: HashTable.Create[] -- , properties: CoreProperties.CopyProps[cellType.properties] -- ]];
[] ← RTStructure.StoreObject[structure, cellType, 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, cellInstance: CoreClasses.CellInstance]
RETURNS [instance: RTStructure.Instance] = {
name: Rope.ROPE ← NARROW[CoreProperties.GetCellInstanceProp[cellInstance, CoreOps.nameProp]];
instance ← NEW[RTStructure.InstanceRec ← [name: name, object: object, iPins: HashTable.Create[] -- , properties: CoreProperties.CopyProps[cellInstance.properties] -- ]];
[] ← RTStructure.StoreInstance[structure, cellInstance, instance]};
PrintObject: RTStructure.EachObjectAction ~ {
PrintObjectPins: RTStructure.EachObjectPinAction ~ {
PrintPhysicalPins: RTStructure.EachPhysicalPinAction ~ {
TerminalIO.WriteRope[Rope.Cat[" range: [", Convert.RopeFromInt[pPin.range.min], ", ", Convert.RopeFromInt[pPin.range.max], "], "]];
TerminalIO.WriteRope[Rope.Cat["side: ", RTBasic.sideName[pPin.side], "\n"]]};
TerminalIO.WriteRope[Rope.Cat[" ", oPin.name, IF object.heirarchyLevel = this THEN " this" ELSE " nextHigher"]];
[] ← EnumeratePhysicalPins[oPin, PrintPhysicalPins]};
TerminalIO.WriteRope[Rope.Cat[" ", object.name, IF object.heirarchyLevel = this THEN " this" ELSE " nextHigher", "\n"]];
TerminalIO.WriteRope[Rope.Cat[" connections: ", "\n"]];
[] ← EnumerateObjectPins[object, PrintObjectPins]};
PrintInstance: RTStructure.EachInstanceAction ~ {
PrintInstancePins: RTStructure.EachInstancePinAction ~ {
TerminalIO.WriteRope[Rope.Cat[" net: ", iPin.net.name, ", pin: ", iPin.oPin.name, "\n"]];
};
TerminalIO.WriteRope[Rope.Cat[" ", instance.name, "\n"]];
TerminalIO.WriteRope[Rope.Cat[" position: [", Convert.RopeFromInt[instance.position.x], ", ", Convert.RopeFromInt[instance.position.y], "], "]];
TerminalIO.WriteRope[Rope.Cat["orientation: ", Convert.RopeFromInt[instance.orientation], "\n"]];
TerminalIO.WriteRope[Rope.Cat[" object: ", instance.object.name, "\n"]];
TerminalIO.WriteRope[Rope.Cat[" connections: ", "\n"]];
[] ← EnumerateInstancePins[instance, PrintInstancePins]};
PrintNet: RTStructure.EachNetAction ~ {
PrintNetPins: RTStructure.EachNetPinAction ~ {
TerminalIO.WriteRope[Rope.Cat[" instance: ", nPin.instance.name, ", pin: ", nPin.oPin.name, "\n"]];
};
TerminalIO.WriteRope[Rope.Cat[" ", net.name, "\n"]];
TerminalIO.WriteRope[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.