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};
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.