SCInstUtilImpl.mesa
Copyright Ó 1986, 1987 by Xerox Corporation. All rights reserved.
Bryan Preas, January 19, 1987 12:18:55 pm PST
Jean-Marc Frailong October 14, 1987 12:52:56 pm PDT
Christian Le Cocq January 4, 1988 9:42:54 am PST
compoments utility routines
-- InstWidth - find width of component at current orientation
-- InstHeight - find height of component at current orientation
-- BpHeight - find height of bp when considering side it is on
-- BpWidth - find width of bp when considering side it is on
-- MinMaxBPOffset - find min and max offsets of bonding pads on side
-- BpOffsets - find offsets of bonding pads on side
-- BpPos - find position of inst on side
-- PosOf- find the position (side, x, and y) of a component on a pin
-- RotateRect- Rotate a rectangle of a cell
-- LgOffsets- determine offsets of components in row
-- AllOffsets - determine all component offsets
-- AsgnChanPos - assign current positions to horizontal and vertical channels
-- CheckInsts - check row and position of comps
-- CheckInst - check row and position of a inst
-- EnumeratePinsOnInst - enumerate the net pins on an instance
DIRECTORY
CD, CDBasics, CoreClasses, CoreFlat, RefTab, Rope, RTBasic, RTSets, SC, SCInstUtil, SCPrivate, SCRowUtil, SCUtil;
SCInstUtilImpl:
CEDAR
PROGRAM
IMPORTS CDBasics, CoreFlat, RefTab, Rope, RTBasic, RTSets, SC, SCInstUtil, SCRowUtil, SCUtil
EXPORTS SCInstUtil
SHARES SC =
BEGIN
defltLgOrien: PUBLIC SCPrivate.Orientation ← 1;
defltBpOrien: PUBLIC ARRAY SC.Side OF SCPrivate.Orientation ← [3, 1, 4, 2];
find width of component at current orientation
InstWidth:
PUBLIC
PROC[inst: SCPrivate.Instance]
RETURNS[width:
SC.Number] =
BEGIN
find current orientation
orien: SCPrivate.OrientationOrNone ← inst.curOrien;
now get width based on orientation
SELECT orien
FROM
0, 1, 3, 5, 6 => width ← inst.object.size.p;
2, 4, 7, 8 => width ← inst.object.size.q;
ENDCASE;
END;
find height of component at current orientation
InstHeight:
PUBLIC
PROC[inst: SCPrivate.Instance]
RETURNS[height:
SC.Number] =
BEGIN
find current orientation
orien: SCPrivate.OrientationOrNone ← inst.curOrien;
now get height based on orientation
SELECT orien
FROM
0, 1, 3, 5, 6 => height ← inst.object.size.q;
2, 4, 7, 8 => height ← inst.object.size.p;
ENDCASE;
END;
find height of bp when considering its side
(this is, the dimension perpendicular to side)
BpHeight:
PUBLIC
PROC[inst: SCPrivate.Instance]
RETURNS[height:
SC.Number] = {
IF inst.whichClass # io
THEN
SC.Error[programmingError, Rope.Cat["Instance: ", inst.name, " should be an IO"]];
SELECT inst.curSide
FROM
top, bottom => height ← InstHeight[inst];
left, right => height ← InstWidth[inst];
ENDCASE => SC.Error[programmingError, NIL]};
find height of bp when considering side it is on
this is along to side
BpWidth:
PUBLIC
PROC[inst: SCPrivate.Instance]
RETURNS[width:
SC.Number] = {
IF inst.whichClass # io
THEN
SC.Error[programmingError, Rope.Cat["Instance: ", inst.name, " should be an IO"]];
SELECT inst.curSide
FROM
top, bottom => width ← InstWidth[inst];
left, right => width ← InstHeight[inst];
ENDCASE => SC.Error[programmingError, NIL]};
find offsets of bonding pads on side
MinMaxBPOffset:
PUBLIC
PROC[handle:
SC.Handle, side:
SC.Side]
RETURNS [minOffset, maxOffset:
SC.Number] = {
InstProc: SCRowUtil.EachInstProc = {
minOffset ← MIN[minOffset, instance.offset];
maxOffset ← MAX[maxOffset, instance.offset]};
minOffset ← LAST[INT];
maxOffset ← FIRST[INT];
[] ← SCRowUtil.EnumerateAllInstsOnSide[handle, side, InstProc]};
find offsets of bonding pads on side
BpOffsets:
PUBLIC
PROC[handle:
SC.Handle, side:
SC.Side, pos1, pos2: SCPrivate.ZMaxPosSr] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRow: SCPrivate.BpRow ← layoutData.bpRows[side];
offset: SC.Number;
posA: SCPrivate.ZMaxPosSr ← MIN[pos1, pos2];
posB: SCPrivate.ZMaxPosSr ← MAX[pos1, pos2];
IF posA <= 1 THEN {posA ← 1; offset ← 0}
ELSE
{inst: SCPrivate.Instance ← bpRow.bpsOnSide[posA-1];
IF side = bottom OR side = right THEN offset ← inst.offset + InstWidth[inst] + bpRow.bpSpacing
ELSE offset ← inst.offset + bpRow.bpSpacing};
IF posB = 0 OR posB > bpRow.nBpsOnSide THEN posB ← bpRow.nBpsOnSide;
FOR posIndex: SCPrivate.ZMaxPosSr
IN [posA .. posB]
DO
inst: SCPrivate.Instance ← bpRow.bpsOnSide[posIndex];
width: SC.Number ← BpWidth[inst];
IF side = bottom OR side = right THEN inst.offset ← offset
ELSE inst.offset ← offset + width;
offset ← offset + width + bpRow.bpSpacing;
ENDLOOP};
check offsets of bonding pads on side
CheckBpOffsets:
PUBLIC
PROC[handle:
SC.Handle, side:
SC.Side] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRow: SCPrivate.BpRow ← layoutData.bpRows[side];
offset: SC.Number ← 0;
FOR posIndex: SCPrivate.ZMaxPosSr
IN [1 .. bpRow.nBpsOnSide]
DO
inst: SCPrivate.Instance ← bpRow.bpsOnSide[posIndex];
width: SC.Number ← BpWidth[inst];
IF side = bottom
OR side = right
THEN {
IF inst.offset # offset THEN SC.Error[programmingError, "Not suppose to happen"]}
ELSE {
IF inst.offset # offset + width THEN SC.Error[programmingError, "Not suppose to happen"]};
offset ← offset + width + bpRow.bpSpacing;
ENDLOOP};
find position of inst on side
assumes that channel and bp positions have been assigned.
BpPos:
PUBLIC
PROC[handle:
SC.Handle, inst: SCPrivate.Instance]
RETURNS[result:
SC.Number] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRow: SCPrivate.BpRow ← layoutData.bpRows[inst.curSide];
IF inst.whichClass # io
THEN
SC.Error[programmingError, "objet must be of type io"];
SELECT inst.curSide
FROM
left, right => result ← bpRow.sideOrg.q + inst.offset;
bottom, top => result ← bpRow.sideOrg.p + inst.offset;
ENDCASE};
find position of pin on an inst
assumes that channel and instance positions have been assigned.
InstPosOf:
PUBLIC
PROC[handle:
SC.Handle, inst: SCPrivate.Instance, pin: SCPrivate.ObjectPin]
RETURNS[pos: RTBasic.PQPos] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
this code is copied from PosOf for efficiency
first find the position at normal orientation
xy:
CD.Position ←
SELECT pin.pinPos.side
FROM
bottom => [pin.pinPos.location, pin.pinPos.depth],
right => [InstWidth[inst] - pin.pinPos.depth, pin.pinPos.location],
top => [pin.pinPos.location, InstHeight[inst] - pin.pinPos.depth],
left => [pin.pinPos.depth, pin.pinPos.location],
ENDCASE =>
SC.Error[programmingError, "No suppose to happen"];
now rotate the pin position to current orien
xyPos:
CD.Position ←
SELECT inst.curOrien
FROM
1 => [xy.x, xy.y], -- original
2 => [xy.y, InstWidth[inst] - xy.x], -- rotate270
3 => [InstWidth[inst] - xy.x, InstHeight[inst] - xy.y], -- rotate180
4 => [InstHeight[inst] - xy.y, xy.x], -- rotate90
5 => [InstWidth[inst] - xy.x, xy.y], -- mirrorX
6 => [xy.x, InstHeight[inst] - xy.y], -- rotate180X
7 => [xy.y, xy.x], -- rotate270X
8 => [InstHeight[inst] - xy.y, InstWidth[inst] - xy.x], -- rotate90X
ENDCASE => SC.Error[programmingError, "No suppose to happen"];
SELECT inst.whichClass
FROM
logic, ft => {
lgRow: SCPrivate.LgRow ← layoutData.lgRows.rows[inst.curRow];
pos ← [lgRow.rowOrg.p + inst.offset + xyPos.x, lgRow.rowOrg.q + xyPos.y]};
io => {
bpRow: SCPrivate.BpRow ← layoutData.bpRows[inst.curSide];
pos ←
SELECT inst.curSide
FROM
left, right => [bpRow.sideOrg.p + xyPos.x, bpRow.sideOrg.q + inst.offset + xyPos.y],
bottom, top => [bpRow.sideOrg.p + inst.offset + xyPos.x, bpRow.sideOrg.q + xyPos.y],
ENDCASE => SC.Error[programmingError, "No suppose to happen"]};
ENDCASE};
find the position (side, x, and y) of a component on a pin
PosOf:
PUBLIC
PROC[inst: SCPrivate.Instance, pin: SCPrivate.ObjectPin]
RETURNS [pinDes: SCInstUtil.PinDescription] = {
first find the position at normal orientation
xy: CD.Position ← SELECT pin.pinPos.side
FROM
bottom => [pin.pinPos.location, pin.pinPos.depth],
right => [InstWidth[inst] - pin.pinPos.depth, pin.pinPos.location],
top => [pin.pinPos.location, InstHeight[inst] - pin.pinPos.depth],
left => [pin.pinPos.depth, pin.pinPos.location],
ENDCASE =>
SC.Error[programmingError, "No suppose to happen"];
now rotate the pin position to current orien
xyOrien
: CD.Position ← SELECT inst.curOrien
FROM
1 => [xy.x, xy.y], -- original
2 => [xy.y, InstWidth[inst] - xy.x], -- rotate270
3 => [InstWidth[inst] - xy.x, InstHeight[inst] - xy.y], -- rotate180
4 => [InstHeight[inst] - xy.y, xy.x], -- rotate90
5 => [InstWidth[inst] - xy.x, xy.y], -- mirrorX
6 => [xy.x, InstHeight[inst] - xy.y], -- rotate180X
7 => [xy.y, xy.x], -- rotate270X
8 => [InstHeight[inst] - xy.y, InstWidth[inst] - xy.x], -- rotate90X
ENDCASE => SC.Error[programmingError, "No suppose to happen"];
pinDes ← [xyOrien.x, xyOrien.y, SCUtil.SideTranslate[pin.pinPos.side, inst.curOrien]]};
find the position of a rotated rectangle wintin a component
RotateRect:
PUBLIC
PROC[inst: SCPrivate.Instance, defRect:
SC.Rect]
RETURNS [SC.Rect] = {
now rotate the pin position to current orien
newRect: SC.Rect;
SELECT inst.curOrien
FROM
1 =>
-- original
{newRect.x1 ← defRect.x1; newRect.y1 ← defRect.y1;
newRect.x2 ← defRect.x2; newRect.y2 ← defRect.y2};
2 =>
-- rotate270
{newRect.x1 ← defRect.y1; newRect.y1 ← InstWidth[inst] - defRect.x1;
newRect.x2 ← defRect.y2; newRect.y2 ← InstWidth[inst] - defRect.x2};
3 =>
-- rotate180
{newRect.x1 ← InstWidth[inst] - defRect.x1; newRect.y1 ← InstHeight[inst] - defRect.y1;
newRect.x2 ← InstWidth[inst] - defRect.x2; newRect.y2 ← InstHeight[inst] - defRect.y2};
4 =>
-- rotate90
{newRect.x1 ← InstHeight[inst] - defRect.y1; newRect.y1 ← defRect.x1;
newRect.x2 ← InstHeight[inst] - defRect.y2; newRect.y2 ← defRect.x2};
5 =>
-- mirrorX
{newRect.x1 ← InstWidth[inst] - defRect.x1; newRect.y1 ← defRect.y1;
newRect.x2 ← InstWidth[inst] - defRect.x2; newRect.y2 ← defRect.y2};
6 =>
-- rotate180X
{newRect.x1 ← defRect.x1; newRect.y1 ← InstHeight[inst] - defRect.y1;
newRect.x2 ← defRect.x2; newRect.y2 ← InstHeight[inst] - defRect.y2};
7 =>
-- rotate270X
{newRect.x1 ← defRect.y1; newRect.y1 ← defRect.x1;
newRect.x2 ← defRect.y2; newRect.y2 ← defRect.x2};
8 =>
-- rotate90X
{newRect.x1 ← InstHeight[inst] - defRect.y1; newRect.y1 ← InstWidth[inst] - defRect.x1;
newRect.x2 ← InstHeight[inst] - defRect.y2; newRect.y2 ← InstWidth[inst] - defRect.x2};
ENDCASE => SC.Error[programmingError, "No suppose to happen"];
RETURN[CDBasics.ReInterpreteRect[newRect]]};
determine offsets of components in row
LgOffsets:
PUBLIC
PROC[handle:
SC.Handle, row: SCPrivate.ZMaxRowSr, pos1, pos2: SCPrivate.ZMaxPosSr] = {
compute offsets of all comps on row
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
lgRows: SCPrivate.LgRows ← layoutData.lgRows;
lgRow: SCPrivate.LgRow ← lgRows.rows[row];
offset: SC.Number;
posA: SCPrivate.ZMaxPosSr ← MIN[pos1, pos2];
posB: SCPrivate.ZMaxPosSr ← MAX[pos1, pos2];
IF posA <= 1 THEN {posA ← 1; offset ← 0}
ELSE
{inst: SCPrivate.Instance ← lgRow.lgsOnRow[posA-1];
offset ← inst.offset + InstWidth[inst]};
IF posB = 0 OR posB > lgRow.nLgsOnRow THEN posB ← lgRow.nLgsOnRow;
FOR posIndex: SCPrivate.MaxPosSr
IN [posA .. posB]
DO
inst: SCPrivate.Instance ← lgRow.lgsOnRow[posIndex];
SELECT inst.whichClass
FROM
ft, logic => {inst.offset ← offset; offset ← offset + InstWidth[inst]};
ENDCASE;
ENDLOOP;
update max row widths
IF posB = lgRow.nLgsOnRow
THEN
{lgRow.size.p ← offset;
IF lgRow.size.p >= lgRows.maxRowWidth
THEN
{lgRows.maxRowWidth ← lgRow.size.p; lgRows.numMaxRows ← 1}
ELSE [lgRows.maxRowWidth, lgRows.numMaxRows] ← SCRowUtil.FindMaxRow[handle]}};
determine all component offsets
AllOffsets:
PUBLIC
PROC [handle:
SC.Handle] = {
RowRroc: SCRowUtil.EachRowProc = {
LgOffsets[handle, row, 0, SCPrivate.maxPos]};
SideProc: SCRowUtil.EachSideProc = {
BpOffsets[handle, side, 0, SCPrivate.maxPos]};
[] ← SCRowUtil.EnumerateRows[handle, RowRroc];
[] ← SCRowUtil.EnumerateSides[handle, SideProc]};
assign current positions to horizontal and vertical channels
AsgnChanPos:
PUBLIC
PROC[handle:
SC.Handle] =
BEGIN
compute the minimum channel dimensions
EachSide: SCRowUtil.EachSideProc = {
IF bpRow.dimInvalid THEN SCRowUtil.ComputeSideHeight[handle, side];
sideDim[side] ← MAX[0, bpRow.size.p + (bpRow.nBpsOnSide -1) * bpRow.bpSpacing]};
EachRow: SCRowUtil.EachRowProc = {
IF lgRow.dimInvalid THEN SCRowUtil.ComputeRowHeight[handle, lgRow.rowNum]};
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
parms: SCPrivate.Parms ← NARROW[handle.parms];
lgRows: SCPrivate.LgRows ← layoutData.lgRows;
bpRows: SCPrivate.BpRows ← layoutData.bpRows;
sideChans: SCPrivate.SideChans ← layoutData.sideChans;
rowChans: SCPrivate.RowChans ← layoutData.rowChans;
nChans: SCPrivate.MaxChanSr ← rowChans.count;
pitch: SC.Number ← RTBasic.IRSize[parms.ftObject.cdOb].x;
sideDim: ARRAY SC.Side OF SC.Number;
[] ← SCRowUtil.EnumerateSides[handle, EachSide];
[] ← SCRowUtil.EnumerateRows[handle, EachRow];
row 1 and channel 1 data
rowChans.chans[1].chanPos ← 0;
sideChans[left].sideChanPos ← 0;
lgRows.horzRowOrg ← 0;
lgRows.rows[1].rowOrg.p ← lgRows.horzRowOrg + ((lgRows.maxRowWidth - lgRows.rows[1].size.p)/2)/pitch*pitch;
lgRows.rows[1].rowOrg.q ← rowChans.chans[1].chanPos;
now the interior channels
FOR chan: SCPrivate.MaxChanSr
IN [2 .. nChans]
DO
rowChans.chans[chan].chanPos ← lgRows.rows[chan-1].rowOrg.q + lgRows.rows[chan-1].size.q;
IF chan <= lgRows.count
THEN {
lgRows.rows[chan].rowOrg.q ← rowChans.chans[chan].chanPos + rowChans.chans[chan].chanWidth;
lgRows.rows[chan].rowOrg.p ← lgRows.horzRowOrg + ((lgRows.maxRowWidth - lgRows.rows[chan].size.p)/2)/pitch*pitch};
now the right side
sideChans[right].sideChanPos ← lgRows.horzRowOrg + lgRows.maxRowWidth;
get total height and width
layoutData.totHeight ← rowChans.chans[nChans].chanPos; -- + rowChans.chans[nChans].chanWidth;
layoutData.totWidth ← sideChans[right].sideChanPos;
now update the side orgs
bpRows[bottom].sideOrg.q ← 0;
bpRows[bottom].sideOrg.p ← lgRows.horzRowOrg + (lgRows.maxRowWidth - sideDim[bottom]) / 2;
update right side data
bpRows[right].sideOrg.p ← layoutData.totWidth;
bpRows[right].sideOrg.q ← (layoutData.totHeight - sideDim[right])/ 2;
update top side data
bpRows[top].sideOrg.p ← lgRows.horzRowOrg + (lgRows.maxRowWidth - sideDim[top])/ 2;
bpRows[top].sideOrg.q ← layoutData.totHeight;
update left side data
bpRows[left].sideOrg.p ← 0;
bpRows[left].sideOrg.q ← (layoutData.totHeight - sideDim[left])/ 2;
END;
find chans that these comps touch
ChansForInsts:
PUBLIC
PROC[handle:
SC.Handle, insts: SCPrivate.InstanceList]
RETURNS [touchesChan: SCPrivate.ChanSet ← RTSets.RTLgSetEmpty] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
FOR instList: SCPrivate.InstanceList ← insts, instList.rest
WHILE instList #
NIL
DO
inst: SCPrivate.Instance ← instList.first;
SELECT inst.whichClass
FROM
ft, logic => {
IF inst.curRow > 0
THEN
{touchesChan ← RTSets.RTLgSetUnion[touchesChan, RTSets.RTLgSetGenerateElement[(inst.curRow+1)-1]];
touchesChan ← RTSets.RTLgSetUnion[touchesChan , RTSets.RTLgSetGenerateElement[(inst.curRow)-1]]}};
io => {
IF inst.curSide = bottom
THEN
touchesChan ← RTSets.RTLgSetUnion[touchesChan, RTSets.RTLgSetGenerateElement[(1)-1]];
IF inst.curSide = top
THEN
touchesChan ← RTSets.RTLgSetUnion[touchesChan, RTSets.RTLgSetGenerateElement[(layoutData.rowChans.count)-1]]};
ENDCASE;
ENDLOOP};
check row and position of a inst
CheckInst:
PUBLIC
PROC[handle:
SC.Handle, inst: SCPrivate.Instance] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
SELECT inst.whichClass
FROM
logic, ft =>
{row: SC.Number ← inst.curRow;
pos: SC.Number ← inst.curPos;
lgRow: SCPrivate.LgRow ← layoutData.lgRows.rows[row];
IF row <= 0
OR row > layoutData.rowChans.count
THEN
{
IF ~(row = 0
AND pos = 0
AND inst.whichClass = ft)
THEN
SC.Error[programmingError, " "]}
ELSE
IF pos <= 0
OR pos > lgRow.nLgsOnRow
THEN
SC.Error[programmingError, " "]
ELSE
{trialInst: SCPrivate.Instance ← lgRow.lgsOnRow[pos];
IF inst # trialInst
THEN
SC.Error[programmingError, " "]}};
io =>
{side: SC.Side ← inst.curSide;
pos: SC.Number ← inst.curPos;
bpRow: SCPrivate.BpRow ← layoutData.bpRows[side];
IF side = none
THEN
SC.Error[programmingError, " "]
ELSE
IF pos <= 0
OR pos > bpRow.nBpsOnSide
THEN
SC.Error[programmingError, " "]
ELSE
{trialInst: SCPrivate.Instance ← bpRow.bpsOnSide[pos];
IF inst # trialInst
THEN
SC.Error[programmingError, " "]}};
ENDCASE};
check row and position of a inst
CheckInsts:
PUBLIC
PROC[handle:
SC.Handle] = {
EachInst: SCInstUtil.EachInstanceProc = {
CheckInst[handle, instance]};
[] ← SCInstUtil.EnumerateAllInstances[handle, EachInst]};
EnumerateAllInstances:
PUBLIC
PROC [handle:
SC.Handle, eachInstance: SCInstUtil.EachInstanceProc]
RETURNS [quit:
BOOL] = {
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
quit ← EnumerateInstances[handle, 1, structureData.instances.count, eachInstance]};
EnumerateInstances:
PUBLIC
PROC [handle:
SC.Handle, startInst, stopInst: SCPrivate.MaxInstanceSr, eachInstance: SCInstUtil.EachInstanceProc]
RETURNS [quit:
BOOL ←
FALSE] = {
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
FOR inst: SCPrivate.MaxInstanceSr
IN [startInst .. stopInst]
WHILE ~quit
DO
quit ← eachInstance[structureData.instances.inst[inst]];
ENDLOOP};
EnumeratePinsOnInst:
PUBLIC
PROC [instance: SCPrivate.Instance, eachPin: SCInstUtil.EachPinProc]
RETURNS [quit:
BOOL ←
FALSE] = {
FOR pin:
NAT
IN [0 .. instance.pinNets.size)
WHILE ~quit
DO
quit ← eachPin[instance, pin, instance.pinNets.n[pin]];
ENDLOOP};
DefineInstance:
PUBLIC
PROC [handle:
SC.Handle, instanceName: Rope.
ROPE, object: SCPrivate.Object, equivName: Rope.
ROPE ←
NIL]
RETURNS [instance: SCPrivate.Instance ← NIL] = {
define a component (an instance of object)
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
instances: SCPrivate.Instances ← structureData.instances;
object.numTimesUsed ← object.numTimesUsed + 1;
construct he instance record
SELECT object.typeClass
FROM
logic =>
{instance ← NEW[SCPrivate.InstanceRec];
{instance ← NEW[logic SCPrivate.InstanceRec];
instance.whichClass ← logic;
instances.numLogics ← instances.numLogics + 1};
ft =>
{instance ← NEW[SCPrivate.InstanceRec];
{instance ← NEW[ft SCPrivate.InstanceRec];
instance.whichClass ← ft;
instances.numFts ← instances.numFts + 1};
io =>
{instance ← NEW[SCPrivate.InstanceRec];
{instance ← NEW[io SCPrivate.InstanceRec];
instance.equivPortClass ← equivName;
instance.whichClass ← io;
instances.numIOs ← instances.numIOs + 1};
ENDCASE => SC.Error[callingError, Rope.Cat["Feedthrus not allowed in input: ", instance.name, ", object: ", object.name, "\n"]];
instance.name ← instanceName;
instance.object ← object;
initialize the nets connected to these pins
instance.pinNets ← NEW[SCPrivate.PinNetsRec[object.numPins]];
instances.count ← instances.count + 1;
instance.num ← instances.count;
instances.inst[instances.count] ← instance};
NumInstsOnList:
PUBLIC
PROC [instances: SCPrivate.InstanceList]
RETURNS [count: SCPrivate.ZMaxInstanceSr ← 0] = {
FOR instList: SCPrivate.InstanceList ← instances, instList.rest
WHILE instList #
NIL
DO
count ← count + 1;
ENDLOOP};
CDOrien:
PUBLIC
PROC[instance: SCPrivate.Instance]
RETURNS [orien:
CD.Orientation] = {
get the CD orientation
SELECT instance.curOrien
FROM
0 => orien ← SC.Error[programmingError, "Not suppose to happen"];
1 => orien ← original;
2 => orien ← rotate270;
3 => orien ← rotate180;
4 => orien ← rotate90;
5 => orien ← mirrorX;
6 => orien ← rotate180X;
7 => orien ← rotate270X;
8 => orien ← rotate90X;
ENDCASE};
FindSourceInstance:
PUBLIC PROC [handle:
SC.Handle, flatCT: CoreFlat.FlatCellType]
RETURNS [instance: SCPrivate.Instance] ~ {
Find the instance for a source flat cell from the global table, scream if not found.
structureData: SCPrivate.StructureData = NARROW [handle.structureData];
instance ← NARROW [RefTab.Fetch[structureData.sourceInstances, flatCT].val];
IF instance=NIL THEN SC.Error[callingError, Rope.Cat["Unable to find instance for source cell : ", CoreFlat.InstancePathRope[handle.coreCellType, flatCT.path]]];
};
DefineSourceInstance:
PUBLIC PROC [handle:
SC.Handle, flatCT: CoreFlat.FlatCellType, instance: SCPrivate.Instance] ~ {
structureData: SCPrivate.StructureData = NARROW [handle.structureData];
IF NOT RefTab.Insert[structureData.sourceInstances, flatCT, instance] THEN SC.Error[callingError, Rope.Cat["Trying to register twice cell instance : ", CoreFlat.InstancePathRope[handle.coreCellType, flatCT.path]]];
};
END.