file ///StdCell/SCPlaceUtilImpl.mesa
placement utility routines
-- ExchInsts - exchange two like instances
-- ReverseOrientation - reverse orientation of an instance
-- PutLgRow - put component in row and position
-- ExchPosRow - exchange components in positions index1 and index2
-- RemvLgComp - remove a logic instance from current placement
-- PutBpSide - add a bp instance to a side
-- PutBpPos -
-- ExchPosSide - exchange components in positions index1 and index2
-- RemvBpComp - remove a bp instance from current placement
-- WriteCurPlace - write the current placement
-- ClrCurPlac - clear the current placement
-- CheckPlace -- check the placement consistancy
DIRECTORY
RTSets,
SC,
SCInstUtil,
SCNetUtil,
SCPlaceUtil,
SCPrivate,
SCRowUtil,
Rope,
TerminalIO;
SCPlaceUtilImpl: CEDAR PROGRAM
IMPORTS Rope, RTSets, SC, SCInstUtil, SCNetUtil, SCPlaceUtil, SCRowUtil, TerminalIO
EXPORTS SCPlaceUtil
SHARES SC =
BEGIN
exchange two like instances
ExchInsts: PUBLIC PROCEDURE[handle: SC.Handle, instance1, instance2: SCPrivate.Instance] = {
IF Compatable[instance1, instance2] THEN {
SELECT instance1.whichClass FROM
logic, ft => {
i2Row: SCPrivate.MaxRowSr;
i2Pos: SCPrivate.MaxPosSr;
i2Orien: SCPrivate.OrientationOrNone;
i1Row: SCPrivate.MaxRowSr ← instance1.curRow;
i1Pos: SCPrivate.MaxPosSr ← instance1.curPos;
i1Orien: SCPrivate.OrientationOrNone ← instance1.curOrien;
SCPlaceUtil.RemvLgComp[handle, instance1];
i2Row ← instance2.curRow;
i2Pos ← instance2.curPos;
i2Orien ← instance2.curOrien;
SCPlaceUtil.RemvLgComp[handle, instance2];
SCPlaceUtil.PutLgPos[handle, instance1, i2Row, i2Pos, i2Orien, TRUE];
SCPlaceUtil.PutLgPos[handle, instance2, i1Row, i1Pos, i1Orien, TRUE]};
io => {
i2Side: SC.Side;
i2Pos: SCPrivate.MaxPosSr;
i1Side: SC.Side ← instance1.curSide;
i1Pos: SCPrivate.MaxPosSr ← instance1.curPos;
SCPlaceUtil.RemvBpComp[handle, instance1];
i2Side ← instance2.curSide;
i2Pos ← instance2.curPos;
SCPlaceUtil.RemvBpComp[handle, instance2];
SCPlaceUtil.PutBpPos[handle, instance1, i2Side, i2Pos, 0, TRUE];
SCPlaceUtil.PutBpPos[handle, instance2, i1Side, i1Pos, 0, TRUE];
SCInstUtil.CheckBpOffsets[handle, i1Side];
IF i1Side # i2Side THEN SCInstUtil.CheckBpOffsets[handle, i2Side]
};
ENDCASE}
ELSE SC.Error[programmingError, NIL]};
Compatable: PROCEDURE[instance1, instance2: SCPrivate.Instance] RETURNS [compat: BOOLEAN] = {
compat ← IF instance1.whichClass = io THEN instance2.whichClass = io
ELSE IF instance1.whichClass = logic OR instance1.whichClass = ft THEN
instance2.whichClass = logic OR instance2.whichClass = ft
ELSE FALSE};
ReverseOrientation: PUBLIC PROCEDURE[instance: SCPrivate.Instance] = {
reverse the orientation of an instance
scOrien: SCPrivate.OrientationOrNone ← instance.curOrien;
SELECT instance.curOrien FROM
0 => instance.curOrien ← 0;
1 => instance.curOrien ← 5;
2 => instance.curOrien ← 8;
3 => instance.curOrien ← 6;
4 => instance.curOrien ← 7;
5 => instance.curOrien ← 1;
6 => instance.curOrien ← 3;
7 => instance.curOrien ← 4;
8 => instance.curOrien ← 2;
ENDCASE};
add a logic instance to a row
PutLgRow: PUBLIC PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance, row: SCPrivate.MaxRowSr, orien: SCPrivate.OrientationOrNone ← 0] =
BEGIN
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
lgRow: SCPrivate.LgRow ← layoutData.lgRows.rows[row];
instance.curRow ← row;
instance.curPos ← lgRow.nLgsOnRow;
lgRow.size.p ← lgRow.size.p + SCInstUtil.InstWidth[instance];
lgRow.size.q ← MAX[lgRow.size.q, SCInstUtil.InstWidth[instance]];
lgRow.nLgsOnRow ← lgRow.nLgsOnRow +1;
lgRow.lgsOnRow[lgRow.nLgsOnRow] ← instance;
IF orien # 0 THEN instance.curOrien ← orien
ELSE IF instance.fnlOrien > 0 THEN instance.curOrien ← instance.fnlOrien
ELSE IF instance.curOrien > 0 THEN NULL
ELSE IF instance.initOrien > 0 THEN instance.curOrien ← instance.initOrien
ELSE instance.curOrien ← SCInstUtil.defltLgOrien;
IF instance.whichClass = ft THEN
{net: SCPrivate.Net ← instance.ftNet;
lgRow.nFtsOnRow ← lgRow.nFtsOnRow +1;
net.ftsOnRow ← RTSets.RTMdSetUnion[net.ftsOnRow,
RTSets.RTMdSetGenerateElement[(row)-1]]};
END;
PutLgPos: PUBLIC PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance, row: SCPrivate.MaxRowSr, pos: SCPrivate.MaxPosSr, orien: SCPrivate.OrientationOrNone ← 0, updateOffsets: BOOLEAN] = {
putlgpos add a lg instance to a row in a position
EachInst: SCRowUtil.EachInstProc = {
lgRow.lgsOnRow[pos+1] ← instance;
SELECT instance.whichClass FROM
ft, logic => instance.curPos ← pos+1;
ENDCASE};
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
lgRow: SCPrivate.LgRow ← layoutData.lgRows.rows[row];
instance.curRow ← row;
instance.curPos ← pos;
lgRow.size.p ← lgRow.size.p + SCInstUtil.InstWidth[instance];
lgRow.size.q ← MAX[lgRow.size.q, SCInstUtil.InstWidth[instance]];
IF 1 > pos OR pos > lgRow.nLgsOnRow+1 THEN
SC.Error[programmingError, "pos must be in range 1 .. lgRow.nLgsOnRow"];
IF orien # 0 THEN instance.curOrien ← orien
ELSE IF instance.fnlOrien > 0 THEN instance.curOrien ← instance.fnlOrien
ELSE IF instance.curOrien > 0 THEN NULL
ELSE IF instance.initOrien > 0 THEN instance.curOrien ← instance.initOrien
ELSE instance.curOrien ← SCInstUtil.defltLgOrien;
[] ← SCRowUtil.EnumerateInstsOnRowDecreasing[handle, row, pos, lgRow.nLgsOnRow, EachInst];
lgRow.lgsOnRow[pos] ← instance;
IF instance.whichClass = ft THEN
{net: SCPrivate.Net ← instance.ftNet;
lgRow.nFtsOnRow ← lgRow.nFtsOnRow +1;
net.ftsOnRow ← RTSets.RTMdSetUnion[net.ftsOnRow,
RTSets.RTMdSetGenerateElement[(row)-1]]};
lgRow.nLgsOnRow ← lgRow.nLgsOnRow +1;
IF updateOffsets THEN SCInstUtil.LgOffsets[handle, row, pos, SCPrivate.maxPos]};
exchange components in positions index1 and index2
ExchPosRow: PUBLIC PROCEDURE[handle: SC.Handle, index1, index2: SCPrivate.MaxPosSr, row: SCPrivate.MaxRowSr] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
lgRow: SCPrivate.LgRow ← layoutData.lgRows.rows[row];
instance1: SCPrivate.Instance ← lgRow.lgsOnRow[index1];
instance2: SCPrivate.Instance ← lgRow.lgsOnRow[index2];
lgRow.lgsOnRow[index1] ← instance2;
lgRow.lgsOnRow[index2] ← instance1;
now modify instance data
SELECT instance1.whichClass FROM
ft, logic => instance1.curPos ← index2;
ENDCASE;
SELECT instance2.whichClass FROM
ft, logic => instance2.curPos ← index1;
ENDCASE;
SCInstUtil.LgOffsets[handle, row, index1, index2]};
remove a logic instance from current placement
RemvLgComp: PUBLIC PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance] = {
remove instance from row
EachInst: SCRowUtil.EachInstProc = {
lgRow.lgsOnRow[pos-1] ← instance;
SELECT instance.whichClass FROM
ft, logic => instance.curPos ← pos-1;
ENDCASE};
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
lgRow: SCPrivate.LgRow;
row: SCPrivate.MaxRowSr;
pos: SCPrivate.MaxPosSr;
widthOfComp: SC.Number ← SCInstUtil.InstWidth[instance];
heightOfComp: SC.Number ← SCInstUtil.InstHeight[instance];
SELECT instance.whichClass FROM
ft, logic => {
row ← instance.curRow; pos ← instance.curPos;
instance.curPos ← 0; instance.curRow ← 0; instance.curOrien ← 0};
ENDCASE;
lgRow ← layoutData.lgRows.rows[row];
lgRow.size.p ← lgRow.size.p - widthOfComp;
IF heightOfComp >= lgRow.size.q THEN lgRow.dimInvalid ← TRUE;
IF lgRow.lgsOnRow[pos] # instance THEN SC.Error[programmingError, "Invalid row"];
[] ← SCRowUtil.EnumerateInstsOnRow[handle, row, pos + 1, lgRow.nLgsOnRow, EachInst];
lgRow.nLgsOnRow ← lgRow.nLgsOnRow -1;
IF instance.whichClass = ft THEN {
DeleteFt: SCInstUtil.EachInstanceProc = {
newNum: SCPrivate.MaxInstanceSr ← instance.num-1;
structureData.instances.inst[newNum] ← instance;
instance.num ← newNum;
instance.ftNet ← NIL;
instance.object ← NIL;
structureData.instances.count ← structureData.instances.count -1;
structureData.instances.numFts ← structureData.instances.numFts -1;
SCNetUtil.RemoveConnections[handle, instance]};
net: SCPrivate.Net ← instance.ftNet;
IF lgRow.nFtsOnRow <= 0 THEN SC.Error[programmingError, "Invalid row"];
lgRow.nFtsOnRow ← lgRow.nFtsOnRow - 1;
net.ftsOnRow ← RTSets.RTMdSetDifference[net.ftsOnRow, RTSets.RTMdSetGenerateElement[row-1]];
[] ← SCInstUtil.EnumerateInstances[handle, instance.num+1, structureData.instances.count, DeleteFt]}};
add a bp instance to a side
PutBpSide: PUBLIC PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance, side: SC.SideOrNone, orien: SCPrivate.OrientationOrNone ← 0] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRow: SCPrivate.BpRow ← layoutData.bpRows[side];
instance.curSide ← side;
instance.curPos ← bpRow.nBpsOnSide;
bpRow.size.p ← bpRow.size.p + SCInstUtil.BpWidth[instance];
bpRow.size.q ← MAX[bpRow.size.q, SCInstUtil.BpHeight[instance]];
bpRow.nBpsOnSide ← bpRow.nBpsOnSide +1;
bpRow.bpsOnSide[bpRow.nBpsOnSide] ← instance;
IF orien # 0 THEN instance.curOrien ← orien
ELSE IF instance.fnlOrien > 0 THEN instance.curOrien ← instance.fnlOrien
ELSE IF instance.curOrien > 0 THEN NULL
ELSE IF instance.initOrien > 0 THEN instance.curOrien ← instance.initOrien
ELSE instance.curOrien ← SCInstUtil.defltBpOrien[side]};
PutBpPos: PUBLIC PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance, side: SC.Side, pos: SCPrivate.MaxPosSr, orien: SCPrivate.OrientationOrNone ← 0, updateOffsets: BOOLEAN ← TRUE] = {
add a bp instance to a side in a position
EachInst: SCRowUtil.EachInstProc = {
bpRow.bpsOnSide[pos+1] ← instance;
instance.curPos ← pos+1};
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRow: SCPrivate.BpRow ← layoutData.bpRows[side];
instance.curSide ← side;
instance.curPos ← pos;
bpRow.size.p ← bpRow.size.p + SCInstUtil.BpWidth[instance];
bpRow.size.q ← MAX[bpRow.size.q, SCInstUtil.BpHeight[instance]];
[] ← SCRowUtil.EnumerateInstsOnSideDecreasing[handle, side, pos, bpRow.nBpsOnSide, EachInst];
bpRow.nBpsOnSide ← bpRow.nBpsOnSide + 1;
bpRow.bpsOnSide[pos] ← instance;
IF orien # 0 THEN instance.curOrien ← orien
ELSE IF instance.fnlOrien > 0 THEN instance.curOrien ← instance.fnlOrien
ELSE IF instance.curOrien > 0 THEN NULL
ELSE IF instance.initOrien > 0 THEN instance.curOrien ← instance.initOrien
ELSE instance.curOrien ← SCInstUtil.defltBpOrien[side];
IF updateOffsets THEN SCInstUtil.BpOffsets[handle, side, pos, SCPrivate.maxPos]};
exchange components in positions index1 and index2
ExchPosSide: PUBLIC PROCEDURE[handle: SC.Handle, index1, index2: SCPrivate.MaxPosSr, side: SC.Side] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRow: SCPrivate.BpRow ← layoutData.bpRows[side];
instance1: SCPrivate.Instance ← bpRow.bpsOnSide[index1];
instance2: SCPrivate.Instance ← bpRow.bpsOnSide[index2];
bpRow.bpsOnSide[index1] ← instance2;
bpRow.bpsOnSide[index2] ← instance1;
instance1.curPos ← index2;
instance2.curPos ← index1;
SCInstUtil.BpOffsets[handle, side, index1, index2]};
remove a bp instance from current placement
RemvBpComp: PUBLIC PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance] = {
side: SC.SideOrNone;
pos: SCPrivate.MaxPosSr;
bpRow: SCPrivate.BpRow;
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
widthOfComp: SC.Number ← SCInstUtil.BpWidth[instance];
heightOfComp: SC.Number ← SCInstUtil.BpHeight[instance];
EachInst: SCRowUtil.EachInstProc = {
bpRow.bpsOnSide[pos-1] ← instance;
instance.curPos ← pos-1};
IF instance.whichClass # io THEN SC.Error[programmingError, Rope.Cat["invalid instance: ", instance.name]];
IF instance.curSide = none THEN SC.Error[programmingError, Rope.Cat["invalid side for instance", instance.name]];
side ← instance.curSide;
pos ← instance.curPos;
instance.curPos ← 0;
instance.curSide ← none;
instance.curOrien ← 0;
bpRow ← layoutData.bpRows[side];
bpRow.size.p ← bpRow.size.p - widthOfComp;
IF bpRow.nBpsOnSide <= 0 THEN SC.Error[programmingError, "invalid side"];
IF bpRow.bpsOnSide[pos] # instance THEN SC.Error[programmingError, Rope.Cat["instance: ", instance.name, " not in specified position"]];
remove instance from side
IF heightOfComp >= bpRow.size.q THEN bpRow.dimInvalid ← TRUE;
[] ← SCRowUtil.EnumerateInstsOnSide[handle, side, pos + 1, bpRow.nBpsOnSide, EachInst];
bpRow.bpsOnSide[bpRow.nBpsOnSide] ← NIL;
bpRow.nBpsOnSide ← bpRow.nBpsOnSide -1};
WriteCurPlace: PUBLIC PROCEDURE [handle: SC.Handle] = {
EachInst: SCInstUtil.EachInstanceProc = {
TerminalIO.WriteRope[Rope.Cat[" instance: ", instance.name, ", object: ", instance.object.name]];
SELECT instance.whichClass FROM
ft, logic => {TerminalIO.WriteRope[", logic row: "]; TerminalIO.WriteInt[instance.curRow]};
io => {TerminalIO.WriteRope[Rope.Cat[", IO side: ", SCRowUtil.sideName[instance.curSide]]]};
ENDCASE;
TerminalIO.WriteRope[", pos: "]; TerminalIO.WriteInt[instance.curPos];
TerminalIO.WriteLn[]};
[] ← SCInstUtil.EnumerateAllInstances[handle, EachInst]};
clear the current placement in preparation for reinitialization
ClrCurPlac: PUBLIC PROCEDURE[handle: SC.Handle, initPrePlace: BOOLEAN] = {
EachInst: SCInstUtil.EachInstanceProc = {
SELECT instance.whichClass FROM
logic, ft =>
{IF instance.curRow > 0 THEN RemvLgComp[handle, instance];
instance.curRow ← 0; instance.curPos ← 0; instance.curOrien ← 0;
IF initPrePlace THEN
{instance.preRow ← 0; instance.prePos ← 0; instance.preOrien ← 0}};
io =>
{IF instance.curSide > none THEN RemvBpComp[handle, instance];
instance.curSide ← none; instance.curPos ← 0; instance.curOrien ← 0;
IF initPrePlace THEN
{instance.preSide ← none; instance.prePos ← 0; instance.preOrien ← 0}};
ENDCASE};
[] ← SCInstUtil.EnumerateAllInstances[handle, EachInst]};
CheckPlace: PUBLIC PROCEDURE[handle: SC.Handle] = {
check the placement consistancy
EachRow: SCRowUtil.EachRowProc = {
EachInst: SCRowUtil.EachInstProc = {
IF instance.curRow # row OR instance.curPos # pos THEN
SC.Error[programmingError, "Invalid row or position for instance"]};
[] ← SCRowUtil.EnumerateAllInstsOnRow[handle, row, EachInst]};
[] ← SCRowUtil.EnumerateRows[handle, EachRow]};
END.