PosInitBp:
PROCEDURE[handle:
SC.Handle, side:
SC.Side] = {
PreAssign: SCRowUtil.EachInstProc = {
Check: SCRowUtil.EachInstProc = {
otherPos: SCPrivate.ZMaxPosSr ← instance.fnlPos;
IF curPos = otherPos
THEN {
TerminalIO.WriteRope[Rope.Cat[" Two instances have same position: ", firstInst.name, " and ", instance.name]];
TerminalIO.WriteRope[Rope.Cat["\n pos = ", Convert.RopeFromInt[firstPos], "\n"]]}};
firstInst: SCPrivate.Instance ← instance;
firstPos: SCPrivate.ZMaxPosSr ← pos;
curPos: SCPrivate.ZMaxPosSr ← firstInst.fnlPos;
IF curPos > 0
THEN
[] ← SCRowUtil.EnumerateInstsOnSide[handle, side, firstPos +1, bpRow.nBpsOnSide, Check]};
Sort: SCRowUtil.EachInstProc = {
InnerSort: SCRowUtil.EachInstProc = {
IF instance.fnlPos < firstInst.fnlPos
THEN {
bpRow.bpsOnSide[firstPos] ← instance;
bpRow.bpsOnSide[pos] ← firstInst}};
firstInst: SCPrivate.Instance ← instance;
firstPos: SCPrivate.ZMaxPosSr ← pos;
[] ← SCRowUtil.EnumerateInstsOnSide[handle, side, firstPos +1, bpRow.nBpsOnSide, InnerSort]};
FixUp: SCRowUtil.EachInstProc = {
instance ← bpRow.bpsOnSide[pos];
instance.curPos ← pos};
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRow: SCPrivate.BpRow ← layoutData.bpRows[side];
see if positions have been pre assigned
IF bpRow.fnlBpFxd
OR bpRow.initBpFxd
THEN {
check if pre-assignments are valid
[] ← SCRowUtil.EnumerateAllInstsOnSide[handle, side, PreAssign];
now sort based on fnlPos
[] ← SCRowUtil.EnumerateAllInstsOnSide[handle, side, Sort];
now fix up curbppos, they might not be sequential
[] ← SCRowUtil.EnumerateAllInstsOnSide[handle, side, FixUp]}
ELSE {
-- positions on side were not specified assign positions
this should be replaced with a more sophisticated version
[] ← SCRowUtil.EnumerateAllInstsOnSide[handle, side, FixUp]};
SCInstUtil.BpOffsets[handle, side, 0, 0]};
PosInitLg:
PROCEDURE[handle:
SC.Handle, row: SCPrivate.MaxRowSr] = {
PreAssign: SCRowUtil.EachInstProc = {
Check: SCRowUtil.EachInstProc = {
otherPos: SCPrivate.ZMaxPosSr ← instance.fnlPos;
IF curPos = otherPos
THEN {
TerminalIO.WriteRope[Rope.Cat[" Two instances have same position: ", firstInst.name, " and ", instance.name]];
TerminalIO.WriteRope[Rope.Cat["\n pos = ", Convert.RopeFromInt[curPos], "\n"]]}};
firstInst: SCPrivate.Instance ← instance;
firstPos: SCPrivate.ZMaxPosSr ← pos;
curPos: SCPrivate.ZMaxPosSr ← firstInst.fnlPos;
IF curPos > 0
THEN
[] ← SCRowUtil.EnumerateInstsOnRow[handle, row, firstPos +1, lgRow.nLgsOnRow, Check]};
Sort: SCRowUtil.EachInstProc = {
InnerSort: SCRowUtil.EachInstProc = {
IF instance.fnlPos < firstInst.fnlPos
THEN {
lgRow.lgsOnRow[firstPos] ← instance;
lgRow.lgsOnRow[pos] ← firstInst}};
firstInst: SCPrivate.Instance ← instance;
firstPos: SCPrivate.ZMaxPosSr ← pos;
[] ← SCRowUtil.EnumerateInstsOnRow[handle, row, firstPos +1, lgRow.nLgsOnRow, InnerSort]};
FixUp: SCRowUtil.EachInstProc = {
instance ← lgRow.lgsOnRow[pos];
instance.curPos ← pos};
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
lgRow: SCPrivate.LgRow ← layoutData.lgRows.rows[row];
see if positions have been pre assigned
IF lgRow.fnlLgFxd OR lgRow.initLgFxd THEN {
check if pre-assignments are valid
[] ← SCRowUtil.EnumerateAllInstsOnRow[handle, row, PreAssign];
now sort based on fnllgpos
[] ← SCRowUtil.EnumerateAllInstsOnRow[handle, row, Sort];
now fix up curlgpos, they might not be sequential
[] ← SCRowUtil.EnumerateAllInstsOnRow[handle, row, FixUp]}
ELSE {
-- positions on row were not specified assign positions
this should be replaced with a more sophisticated version
[] ← SCRowUtil.EnumerateAllInstsOnRow[handle, row, FixUp]};
SCInstUtil.LgOffsets[handle, row, 0, 0]};
PosInit:
PUBLIC
PROCEDURE [handle:
SC.Handle] = {
assign the logic row positions
DoRow: SCRowUtil.EachRowProc = {
PosInitLg[handle, row]};
[] ← SCRowUtil.EnumerateRows[handle, DoRow];
now the top and bottom bp sides
the left and right side bp positions were assigned in rowinit
PosInitBp[handle, bottom];
PosInitBp[handle, top]};
RowInit:
PUBLIC
PROCEDURE [handle:
SC.Handle] = {
NextUnplaced:
PROCEDURE [handle:
SC.Handle]
RETURNS [inst: SCPrivate.Instance ←
NIL] = {
EachInstance: SCInstUtil.EachInstanceProc = {
SELECT instance.whichClass
FROM
logic => IF instance.curRow = 0 THEN inst ← instance;
io => IF instance.curSide = none THEN inst ← instance;
ENDCASE;
quit ← inst = instance};
[] ← SCInstUtil.EnumerateAllInstances[handle, EachInstance]};
RowPlacInit:
PROCEDURE [handle:
SC.Handle, instance: SCPrivate.Instance] = {
PutRow: SCRowUtil.EachRowProc = {
IF lgRow.size.p <= minRowLength
THEN
IF ~lgRow.fnlLgFxd
THEN
{minRow ← row; minRowLength ← lgRow.size.p;
useRow ← row}};
minRow, useRow: SCPrivate.ZMaxRowSr ← 0;
minRowLength: SC.Number ← LAST[INT];
[] ← SCRowUtil.EnumerateRows[handle, PutRow];
IF useRow = 0
THEN
{SC.Signal[callingError, Rope.Cat["no valid row to place instance: ", instance.name, "\n"]];
useRow ← 1};
SCPlaceUtil.PutLgRow[handle, instance, useRow]};
SidePlacInit:
PROCEDURE [handle:
SC.Handle, instance: SCPrivate.Instance] = {
PutSide: SCRowUtil.EachSideProc = {
IF bpRow.nBpsOnSide <= minSideLength
THEN
IF ~bpRow.fnlBpFxd
AND bpRow.nBpsOnSide < bpRow.maxBpsOnSide
THEN
{minSide ← side; minSideLength ← bpRow.nBpsOnSide;
useSide ← side}};
minSide, useSide: SC.SideOrNone ← none;
minSideLength: SC.Number ← LAST[INT];
[] ← SCRowUtil.EnumerateSides[handle, PutSide];
IF useSide = none
THEN
{SC.Signal[callingError, Rope.Cat["no valid side to place instance: ",
instance.name, "\n"]];
useSide ← left};
SCPlaceUtil.PutBpSide[handle, instance, useSide]};
RowInit
place instances that were not preplaced
FOR instance: SCPrivate.Instance ← NextUnplaced[handle], NextUnplaced[handle]
WHILE instance #
NIL
DO
IF instance.whichClass = logic THEN RowPlacInit[handle, instance]
ELSE IF instance.whichClass = io THEN SidePlacInit[handle, instance];
ENDLOOP;
preplace the left and right sides, the top and bottom sides are placed in PosInit
PosInitBp[handle, left];
PosInitBp[handle, right]};
}.