file: SCInitialPlaceImpl.mesa
Last Edited by: Preas, December 21, 1986 3:46:20 pm PST
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] = {
check to see if two bondingpads have been preassigned to the same slot
PreAssign: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
Check: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
IF firstInst.fnlPos = instance.fnlPos THEN {
TerminalIO.PutRope[Rope.Cat[" Two instances have same position: ", firstInst.name, " and ", instance.name]];
TerminalIO.PutRope[Rope.Cat["\n pos = ", Convert.RopeFromInt[instance.fnlPos], "\n"]]}};
firstInst: SCPrivate.Instance ← instance;
IF firstInst.fnlPos > 0 THEN
[] ← SCRowUtil.EnumerateInstsOnSide[handle, side, pos +1, bpRow.nBpsOnSide, Check]};
sort the bondingpads by preassigned slot
Sort: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
InnerSort: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
IF bpRow.bpsOnSide[pos].fnlPos < bpRow.bpsOnSide[firstPos].fnlPos THEN {
bpRow.bpsOnSide[pos] ← bpRow.bpsOnSide[firstPos];
bpRow.bpsOnSide[firstPos] ← instance}};
firstInst: SCPrivate.Instance ← instance;
firstPos: INT ← pos;
[] ← SCRowUtil.EnumerateInstsOnSide[handle, side, pos +1, bpRow.nBpsOnSide, InnerSort]};
assign sequential slots to the bondingpads
FixUp: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
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, SCPrivate.maxPos]};
position instances on specified row
PosInitLg: PROCEDURE[handle: SC.Handle, row: SCPrivate.MaxRowSr] = {
sort the logics by preassigned slot
PreAssign: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
Check: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
IF firstInst.fnlPos = instance.fnlPos THEN {
TerminalIO.PutRope[Rope.Cat[" Two instances have same position: ", firstInst.name, " and ", instance.name]];
TerminalIO.PutRope[Rope.Cat["\n pos = ", Convert.RopeFromInt[instance.fnlPos], "\n"]]}};
firstInst: SCPrivate.Instance ← instance;
IF firstInst.fnlPos > 0 THEN
[] ← SCRowUtil.EnumerateInstsOnRow[handle, row, pos +1, lgRow.nLgsOnRow, Check]};
sort the logics by preassigned slot
Sort: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
InnerSort: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
IF lgRow.lgsOnRow[pos].fnlPos < lgRow.lgsOnRow[firstPos].fnlPos THEN {
lgRow.lgsOnRow[pos] ← lgRow.lgsOnRow[firstPos];
lgRow.lgsOnRow[firstPos] ← instance}};
firstInst: SCPrivate.Instance ← instance;
firstPos: INT ← pos;
[] ← SCRowUtil.EnumerateInstsOnRow[handle, row, pos +1, lgRow.nLgsOnRow, InnerSort]};
assign sequential slots to the logics
FixUp: SCRowUtil.EachInstProc = {
PROC [pos: NAT, instance: SCPrivate.Instance] RETURNS [quit: BOOL ← FALSE];
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, SCPrivate.maxPos]};
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]};
}.