file ///StdCell/SCPlaceUtilImpl.mesa
placement utility routines
-- 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,
SCPlaceUtil,
SCPrivate,
SCRowUtil,
Rope,
TerminalIO;
SCPlaceUtilImpl: CEDAR PROGRAM
IMPORTS Rope, RTSets, SC, SCInstUtil, SCRowUtil, TerminalIO
EXPORTS SCPlaceUtil
SHARES SC =
BEGIN
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] = {
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;
SCInstUtil.LgOffsets[handle, row, pos, 0]};
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] = {
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
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;
remove instance from row
BEGIN
EachInst: SCRowUtil.EachInstProc = {
lgRow.lgsOnRow[pos-1] ← instance;
SELECT instance.whichClass FROM
ft, logic => instance.curPos ← pos;
ENDCASE};
lgRow: SCPrivate.LgRow ← layoutData.lgRows.rows[row];
IF lgRow.lgsOnRow[pos] # instance THEN SC.Error[programmingError, "Invalid row"];
lgRow.size.p ← lgRow.size.p - widthOfComp;
IF heightOfComp >= lgRow.size.q THEN lgRow.dimInvalid ← TRUE;
[] ← SCRowUtil.EnumerateInstsOnRow[handle, row, pos + 1, lgRow.nLgsOnRow, EachInst];
lgRow.nLgsOnRow ← lgRow.nLgsOnRow -1;
IF instance.whichClass = ft THEN {
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]]};
END};
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] = {
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];
SCInstUtil.BpOffsets[handle, side, pos, 0]};
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;
IF instance.whichClass = io THEN {
side ← instance.curSide;
pos ← instance.curPos;
instance.curPos ← 0;
instance.curSide ← none;
instance.curOrien ← 0};
check if side is valid
IF side # none THEN
SC.Error[programmingError, Rope.Cat["invalid instance: ", instance.name, " on side"]];
remove instance from side
BEGIN
EachInst: SCRowUtil.EachInstProc = {
bpRow.bpsOnSide[pos-1] ← instance;
instance.curPos ← pos-1};
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRow: SCPrivate.BpRow ← layoutData.bpRows[side];
bpRow.size.p ← bpRow.size.p - SCInstUtil.BpWidth[instance];
IF SCInstUtil.BpHeight[instance] >= bpRow.size.q THEN bpRow.dimInvalid ← TRUE;
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"]];
[] ← SCRowUtil.EnumerateInstsOnSide[handle, side, pos, bpRow.nBpsOnSide, EachInst];
bpRow.nBpsOnSide ← bpRow.nBpsOnSide -1;
END};
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.EnumerateInstances[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.EnumerateInstances[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.