file: ///StdCell/SCInitialPlaceImpl.mesa
Last Edited by: Preas, September 6, 1985 7:20:47 pm PDT
DIRECTORY
Convert,
Rope,
SC,
SCInstUtil,
SCInitialPlace,
SCPlaceUtil,
SCPrivate,
SCRowUtil,
TerminalIO;
SCInitialPlaceImpl: CEDAR PROGRAM
IMPORTS Convert, Rope, SC, SCInstUtil, SCPlaceUtil, SCRowUtil, TerminalIO
EXPORTS SCInitialPlace
SHARES SC = {
position instances on specified side
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]};
position instances on specified row
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.EnumerateInstances[handle, EachInstance]};
RowPlacInit: PROCEDURE [handle: SC.Handle, instance: SCPrivate.Instance] = {
PutRow: SCRowUtil.EachRowProc = {
IF lgRow.size.p <= minRowLength THEN
{minRow ← row; minRowLength ← lgRow.size.p;
IF ~lgRow.fnlLgFxd THEN 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
{minSide ← side; minSideLength ← bpRow.nBpsOnSide;
IF ~bpRow.fnlBpFxd AND bpRow.nBpsOnSide < bpRow.maxBpsOnSide THEN 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]};
}.