SCGetStructureImpl:
CEDAR
PROGRAM
IMPORTS CD, CDBasics, CDPinObjects, CDSymbolicObjects, CoreClasses, CoreOps, CoreProperties, PW, PWPins, Rope, RTBasic, SC, SCCoreUtil, SCInstUtil, SCNetUtil, SCUtil, TerminalIO
EXPORTS SCPrivate
SHARES SC =
BEGIN
debug: BOOLEAN ← FALSE;
GetStructure:
PUBLIC
PROCEDURE [handle:
SC.Handle, cellType: Core.CellType]
RETURNS [done: BOOLEAN] = {
InternalWireProc: SCCoreUtil.EachWireProc = {
net: SCPrivate.Net ← SCUtil.FindNet[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]];
IF net # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate net name: ", NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]]
ELSE
net ← SCNetUtil.DefineNet[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]};
ExternalWireProc: SCCoreUtil.EachWireProc = {
instance: SCPrivate.Instance ← SCUtil.FindInstance[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]];
net: SCPrivate.Net ← SCUtil.FindNet[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]];
IF net = NIL THEN SC.Signal[callingError, Rope.Cat["Missing net name: ", NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]];
IF instance # NIL THEN SC.Signal[callingError, Rope.Cat["Duplicate port name: ", NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]], ", object: ", parms.portObject.name]];
IF instance =
NIL
AND net #
NIL
THEN
{instance ← SCInstUtil.DefineInstance[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]], parms.portObject, NIL, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]];
SCNetUtil.AddConnection[handle, net, instance, parms.portObject.pins.p[0], 0];
net.externNet ← externalNet;
GetIOHints[handle, instance, wire.properties]}};
InstanceProc: SCCoreUtil.EachInstanceProc = {
object: SCPrivate.Object ← SCUtil.FindObject[handle, NARROW[CoreProperties.GetCellTypeProp[cellInstance.type, CoreOps.nameProp]]];
IF object =
NIL
THEN
object ← DefineObject[handle, NARROW[CoreProperties.GetCellTypeProp[cellInstance.type, CoreOps.nameProp]], logic, cellInstance.type];
IF object =
NIL
THEN
SC.Signal[callingError, Rope.Cat["Object is not defined: ", NARROW[CoreProperties.GetCellTypeProp[cellInstance.type, CoreOps.nameProp]], "\n"]]
ELSE
{
GetCellName:
PROC [cellInstance: CoreClasses.CellInstance]
RETURNS [name: Rope.
ROPE ← ""] = {
this is a lot to go through to get an instance name
name ← NARROW[CoreProperties.GetCellInstanceProp[cellInstance, CoreClasses.instanceNameProp]]};
EachInstancePin: SCCoreUtil.EachInstancePinProc = {
IF ~SCUtil.IsPowerName[handle, NARROW[CoreProperties.GetWireProp[publicWire, CoreOps.nameProp]]]
THEN
{net: SCPrivate.Net ← SCUtil.FindNet[handle, NARROW[CoreProperties.GetWireProp[actualWire, CoreOps.nameProp]]];
pin: SCPrivate.ObjectPin ← SCUtil.FindPin[object, NARROW[CoreProperties.GetWireProp[publicWire, CoreOps.nameProp]]]; -- get the pin
IF net =
NIL
THEN
{SC.Signal[callingError, Rope.Cat[Rope.Cat["Net not defined: ", NARROW[CoreProperties.GetWireProp[actualWire, CoreOps.nameProp]], " 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 {
add connection for comp, pin
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];
ENDLOOP}}};
instance: SCPrivate.Instance ← SCInstUtil.DefineInstance[handle, GetCellName[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 {
[] ← SCCoreUtil.EnumFlatInstancePins[cellInstance, EachInstancePin];
GetLogicHints[handle, instance, cellInstance.properties]}}};
set up the private data
recCell: CoreClasses.RecordCellType ← NARROW[cellType.data];
parms: SCPrivate.Parms ← NARROW[handle.parms];
portName:Rope.ROPE ← "IOPort"; -- need to get from Core
ftName:Rope.ROPE ← "Feedthru"; -- need to get from Core
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, portName];
parms.ftObject ← DefineAuxType[handle, ftName, ft];
get auxalliary components
TerminalIO.WriteRope["Getting structure description . . .\n"];
done ← ~SCCoreUtil.EnumerateFlatWires[recCell.internal, InternalWireProc];
done ← done AND ~SCCoreUtil.EnumerateFlatWires[cellType.public, ExternalWireProc];
done ← done AND ~SCCoreUtil.EnumerateInstances[cellType, InstanceProc];
fix up the bus widths based on connectivity
DoBuses[handle, left];
DoBuses[handle, right];
IF debug THEN SCUtil.WriteStructure[handle]};
DoBuses: PROCEDURE [handle: SC.Handle, lRSide: RTBasic.LRSide] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
powerBuses: SCPrivate.PowerBuses ← layoutData.powerBuses;
acBuses: SCPrivate.AcBuses ← layoutData.acBuses;
rules: Route.DesignRules ← handle.rules.sideRules;
pWidth: SC.Number ← 0;
numClocks: NAT ← 0;
net: SCPrivate.Net ← SCUtil.FindNet[handle, powerBuses[lRSide].name];
IF net # NIL THEN pWidth ← net.trunkWidth + rules.trunkSpacing; -- fill in width !!!
powerBuses[lRSide].width ← pWidth;
powerBuses[lRSide].net ← net;
FOR clockIndex:
NAT
IN [0 .. acBuses[lRSide].count)
DO
IF acBuses[lRSide].sigs.c[clockIndex].onSide = lRSide
THEN
{numClocks ← numClocks + 1;
acBuses[lRSide].sigs.c[clockIndex].depth ← pWidth + (numClocks-1)*rules.trunkToTrunk + rules.trunkWidth/2};
ENDLOOP;
acBuses[lRSide].width ← numClocks* rules.trunkToTrunk};
DefineObject:
PROCEDURE [handle:
SC.Handle, objectName: Rope.
ROPE, class: SCPrivate.CompClass, cellType: Core.CellType ←
NIL]
RETURNS [object: SCPrivate.Object ← NIL] = {
get physical description and define the type
enter a new object into standard cell data structure
CountPins: PWPins.InstanceEnumerator = {
name: Rope.ROPE ← CDPinObjects.GetName[inst];
IF ~SCUtil.IsPowerName[handle, name] AND CDSymbolicObjects.IsPin[inst.ob] THEN
object.numPins ← object.numPins + 1};
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
objects: SCPrivate.Objects ← structureData.objects;
parms: SCPrivate.Parms ← NARROW[handle.parms];
ob: CD.Object ← PW.Get[parms.libDesign, objectName];
numPins: NAT ← 0;
obRect: CD.Rect;
size, orgin: RTBasic.PQPos;
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, class, 0, ob]];
objects.ob[objects.count] ← object;
define the pins on the object
[] ← PWPins.EnumerateDeepPins[ob, CountPins];
object.pins ← NEW[SCPrivate.ObjectPinsRec[object.numPins]];
IF object.numPins > 0
THEN {
PinEnum: PWPins.InstanceEnumerator = {
name: Rope.ROPE ← CDPinObjects.GetName[inst];
IF ~SCUtil.IsPowerName[handle, name]
AND CDSymbolicObjects.IsPin[inst.ob]
THEN
{pinPos: SCPrivate.PinPos;
rect: SC.Rect;
objectPin: SCPrivate.ObjectPin;
name: Rope.ROPE ← CDPinObjects.GetName[inst];
layer: SC.Layer ← CDPinObjects.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]};
check physical pins against the logical pins
IF cellType #
NIL
THEN {
WireEnum: SCCoreUtil.EachWireProc = {
IF ~SCUtil.IsPowerName[handle, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]]
THEN
{
IF SCUtil.FindPin[object, NARROW[CoreProperties.GetWireProp[wire, CoreOps.nameProp]]] =
NIL
THEN
SC.Signal[callingError, Rope.Cat["Physical pins and logical pins on object: ", object.name, " do not correspond"]]}};
[] ← SCCoreUtil.EnumerateFlatWires[cellType.public, WireEnum]}};
DefineAuxType:
PROCEDURE [handle:
SC.Handle, name: Rope.
ROPE, class: SCPrivate.CompClass]
RETURNS [object: SCPrivate.Object ←
NIL] = {
object ← SCUtil.FindObject[handle, name];
IF object #
NIL
THEN {
SC.Signal[callingError, Rope.Cat["Duplicate auxillary object: ", name, "\n"]];
RETURN};
object ← DefineObject[handle, name, class];
IF object =
NIL
THEN
SC.Signal[callingError, Rope.Cat["Auxillary object is not defined: ", name, "\n"]]};
DefineIOType:
PROCEDURE [handle:
SC.Handle, name: Rope.
ROPE]
RETURNS [object: SCPrivate.Object ←
NIL] = {
object ← SCUtil.FindObject[handle, name];
IF object #
NIL
THEN {
SC.Signal[callingError, Rope.Cat["Duplicate IO object: ", name, "\n"]];
RETURN};
object ← DefineObject[handle, name, io];
IF object =
NIL
THEN
SC.Signal[callingError, Rope.Cat["IO 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] = {
analyze cell for relevant parameters
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.p - px, object.size.q - py], rect]
ELSE RETURN [[bottom, px, py], rect]};
GetLogicHints:
PROCEDURE [handle:
SC.Handle, instance: SCPrivate.Instance, properties: Core.Properties] = {
};
GetIOHints:
PROCEDURE [handle:
SC.Handle, instance: SCPrivate.Instance, properties: Core.Properties] = {
};
END.