///stdcell/SCGetStructureImpl.mesa
Last Edited by: Preas, September 9, 1985 10:06:38 am PDT
Frank Bowers February 3, 1986 5:41:01 pm PST
get design data by reading Core connectivity and ChipnDale cells
DIRECTORY
CD,
CDBasics,
CDPinObjects,
CDSymbolicObjects,
Core,
CoreClasses,
CoreOps,
CoreProperties,
PW,
PWPins,
Rope,
Route,
RTBasic,
SC,
SCCoreUtil,
SCInstUtil,
SCNetUtil,
SCPrivate,
SCUtil,
TerminalIO;
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: BOOLEANFALSE;
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.LayerCDPinObjects.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.