///StdCell/SCPrePlaceImpl.mesa
DIRECTORY
Convert,
Rope,
Real,
SC,
SCChanUtil,
SCInitialPlace,
SCInstUtil,
SCPlaceUtil,
SCPrivate,
SCRowUtil,
TerminalIO;
SCPrePlaceImpl: CEDAR PROGRAM
IMPORTS Convert, Real, Rope, SC, SCChanUtil, SCInstUtil, SCPlaceUtil, SCRowUtil, TerminalIO
EXPORTS SCInitialPlace
SHARES SC =
BEGIN
debug: BOOLEANFALSE;
ChooseNonZero: PROCEDURE [num1, num2, num3: SC.Number ← 0]
RETURNS[ result: SC.Number] = {
Choose non zero num in priority order
IF num1 # 0 THEN result ← num1
ELSE IF num2 # 0 THEN result ← num2
ELSE result ← num3};
InitBpSide: PROCEDURE [handle: SC.Handle] = {
make the bonding pad rows empty
SideProc: SCRowUtil.EachSideProc = {
bpRow.maxBpsOnSide ← bpRow.initMaxBpsOnSide;
bpRow.size.p ← 0;
bpRow.size.q ← 0;
bpRow.dimInvalid ← FALSE;
bpRow.nBpsOnSide ← 0;
bpRow.fnlBpFxd ← FALSE;
bpRow.initBpFxd ← FALSE};
[] ← SCRowUtil.EnumerateSides[handle, SideProc]};
InitLgRow: PROCEDURE [handle: SC.Handle] = {
make the interior rows empty
RowProc: SCRowUtil.EachRowProc = {
lgRow.size.p ← 0;
lgRow.size.q ← 0;
lgRow.dimInvalid ← FALSE;
lgRow.nLgsOnRow ← 0;
lgRow.nFtsOnRow ← 0;
lgRow.fnlLgFxd ← FALSE;
lgRow.initLgFxd ← FALSE};
[] ← SCRowUtil.EnumerateRows[handle, RowProc]};
PrePlaceComps: PROCEDURE [handle: SC.Handle, initialized: BOOLEAN] = {
pre place the components
IntBounds: PROCEDURE[checkNum, lowLimit, upLimit, default: SC.Number, name: Rope.ROPE]
RETURNS[ result: SC.Number] = {
IF lowLimit <= checkNum AND checkNum <= upLimit THEN
result ← checkNum
ELSE {
result ← default;
TerminalIO.WriteRope[Rope.Cat[Rope.Cat[" instance: ", name, " variable: ", Convert.RopeFromInt[checkNum], " limits = "], Rope.Cat[Convert.RopeFromInt[lowLimit], Convert.RopeFromInt[upLimit], "\n"]]]}};
SideBounds: PROCEDURE[checkNum, lowLimit, upLimit, default: SC.SideOrNone, name: Rope.ROPE]
RETURNS[ result: SC.SideOrNone] = {
IF lowLimit <= checkNum AND checkNum <= upLimit THEN
result ← checkNum
ELSE {
result ← default;
TerminalIO.WriteRope[Rope.Cat[Rope.Cat[" instance: ", name, " variable: ", SCRowUtil.sideName[checkNum], " limits: "], Rope.Cat[SCRowUtil.sideName[lowLimit], " .. ", SCRowUtil.sideName[upLimit], "\n"]]]}};
PrePlacLg: PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance, initialized: BOOLEAN] = {
preplace the logic component instance
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
lgRows: SCPrivate.LgRows ← layoutData.lgRows;
iRow, fRow: SCPrivate.ZMaxRowSr;
IF initialized THEN {
instance.curRow ← instance.initRow;
instance.curPos ← instance.initPos;
instance.curOrien ← instance.initOrien};
check if this instance has a currently defined position
fRow ← IntBounds[instance.fnlRow, 0, SCPrivate.maxLgRows, 0, instance.name];
iRow ← IntBounds[instance.initRow, 0, SCPrivate.maxLgRows, 0, instance.name];
IF instance.preRow > 0 THEN {
instance.preRow ← IntBounds[instance.preRow, 1, SCPrivate.maxLgRows, 0, instance.name];
instance.prePos ← IntBounds[instance.prePos, 1, SCPrivate.maxPos, 0, instance.name];
instance.preOrien ← IntBounds[instance.preOrien, 1, SCPrivate.maxOrien, SCInstUtil.defltLgOrien, instance.name];
IF instance.preRow = 0 OR instance.prePos = 0 OR instance.preOrien = 0 THEN {
instance.preRow ← 0;
instance.prePos ← 0;
instance.preOrien ← 0}}
check if the final position is specified
ELSE IF fRow > 0 THEN {
instance.preRow ← fRow;
instance.prePos ← IntBounds[ChooseNonZero[instance.fnlPos, instance.initPos], 0, SCPrivate.maxPos, 0, instance.name];
instance.preOrien ← IntBounds[ChooseNonZero[instance.fnlOrien, instance.initOrien, SCInstUtil.defltLgOrien], 1, SCPrivate.maxOrien, SCInstUtil.defltLgOrien, instance.name]}
check for initial position specified
ELSE IF iRow > 0 THEN {
instance.preRow ← iRow;
instance.prePos ← IntBounds[ChooseNonZero[instance.fnlPos, instance.initPos], 0, SCPrivate.maxPos, 0, instance.name];
instance.preOrien ← IntBounds[ChooseNonZero[instance.fnlOrien, instance.initOrien, SCInstUtil.defltLgOrien], 1, SCPrivate.maxOrien, SCInstUtil.defltLgOrien, instance.name]};
IF instance.preRow > 0 THEN SCPlaceUtil.PutLgRow[handle, instance, instance.preRow, instance.preOrien]
ELSE {instance.curRow ← 0; instance.curPos ← 0; instance.curOrien ← 0};
check if this instance restricts a row by specifying a position on a row
IF instance.preRow > 0 AND instance.prePos > 0 THEN {
IF fRow > 0 AND instance.fnlPos > 0 THEN lgRows.rows[fRow].fnlLgFxd ← TRUE;
IF iRow > 0 AND instance.initPos > 0 THEN lgRows.rows[iRow].initLgFxd ← TRUE}};
PrePlacBp: PROCEDURE[handle: SC.Handle, instance: SCPrivate.Instance, initialized:BOOLEAN] = {
preplace the bonding pad component instance
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
bpRows: SCPrivate.BpRows ← layoutData.bpRows;
iSide, fSide: SC.SideOrNone;
IF initialized THEN {
instance.curSide ← instance.initSide;
instance.curPos ← instance.initPos;
instance.curOrien ← instance.initOrien};
check if this instance has a currently defined position
iSide ← SideBounds[instance.initSide, bottom, none, none, instance.name];
fSide ← SideBounds[instance.fnlSide, bottom, none, none, instance.name];
IF instance.preSide # none THEN {
instance.preSide ← SideBounds[instance.preSide, bottom, right, none, instance.name];
instance.prePos ← IntBounds[instance.prePos, 1, SCPrivate.maxPos, 0, instance.name];
instance.preOrien ← IntBounds[instance.preOrien, 1, SCPrivate.maxOrien, SCInstUtil.defltBpOrien[instance.preSide], instance.name];
IF instance.preSide = none OR instance.prePos = 0 OR instance.preOrien = 0 THEN {
instance.preSide ← none;
instance.prePos ← 0;
instance.preOrien ← 0}}
check if the final position is specified
ELSE IF fSide # none THEN {
instance.preSide ← fSide;
instance.prePos ← IntBounds[ChooseNonZero[instance.fnlPos, instance.initPos], 0, SCPrivate.maxPos, 0, instance.name];
instance.preOrien ← IntBounds[ChooseNonZero[instance.fnlOrien, instance.initOrien, SCInstUtil.defltBpOrien[instance.preSide]], 1, SCPrivate.maxOrien, SCInstUtil.defltBpOrien[instance.preSide], instance.name]}
check for initial position specified
ELSE IF iSide # none THEN {
instance.preSide ← iSide;
instance.prePos ← IntBounds[ChooseNonZero[instance.fnlPos, instance.initPos], 0, SCPrivate.maxPos, 0, instance.name];
instance.preOrien ← IntBounds[ChooseNonZero[instance.fnlOrien, instance.initOrien, SCInstUtil.defltBpOrien[iSide]], 1, SCPrivate.maxOrien, SCInstUtil.defltBpOrien[iSide], instance.name]};
IF instance.preSide # none THEN SCPlaceUtil.PutBpSide[handle, instance, instance.preSide]
ELSE {instance.curSide ← none; instance.curPos ← 0; instance.curOrien ← 0};
check to see if this bp restricts this side by having a position assigned
IF instance.preSide # none AND instance.prePos > 0 THEN {
IF fSide # none AND instance.fnlPos > 0 THEN bpRows[fSide].fnlBpFxd ← TRUE;
IF iSide # none AND instance.initPos >0 THEN bpRows[iSide].initBpFxd ← TRUE}};
EachInstance: SCInstUtil.EachInstanceProc = {
SELECT instance.whichClass FROM
logic, ft => PrePlacLg[handle, instance, initialized];
io => PrePlacBp[handle, instance, initialized];
ENDCASE};
[] ← SCInstUtil.EnumerateAllInstances[handle, EachInstance]};
DetermineRows: PROCEDURE [handle: SC.Handle, numRows: NAT ← 0] = {
determine the number of rows to use
EachInstance: SCInstUtil.EachInstanceProc = {
IF instance.whichClass = logic THEN {
maxRowSpec ← MAX[instance.initRow, MAX[maxRowSpec, instance.fnlRow]];
must use direct data access, no placement exists yet
totLinComps ← totLinComps + SCInstUtil.InstWidth[instance];
avgHeight ← avgHeight + SCInstUtil.InstHeight[instance]}};
layoutData: SCPrivate.LayoutData ← NARROW[handle.layoutData];
lgRows: SCPrivate.LgRows ← layoutData.lgRows;
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
instances: SCPrivate.Instances ← structureData.instances;
routFact: REAL = 2.5;
detRow: NAT;
maxRowSpec, avgHeight, totLinComps: SC.Number ← 0;
[] ← SCInstUtil.EnumerateAllInstances[handle, EachInstance];
avgHeight ← avgHeight /MAX[1, instances.numLogics];
IF avgHeight > 0 THEN
detRow ← MAX[1, Real.RoundI[Real.SqRt[totLinComps * avgHeight* routFact] / (avgHeight * routFact)]]
ELSE detRow ← 0;
IF numRows > 0 THEN
lgRows.count ← MIN[SC.Number[SCPrivate.maxLgRows], MAX[maxRowSpec, numRows]]
ELSE IF maxRowSpec > 0 THEN
lgRows.count ← MIN[SC.Number[SCPrivate.maxLgRows], MAX[maxRowSpec, detRow]]
ELSE
lgRows.count ← MIN[SCPrivate.maxLgRows, detRow];
lgRows.count ← MAX[1, lgRows.count];
layoutData.rowChans.count ← lgRows.count +1;
TerminalIO.WriteRope[" number of rows calculation:\n"];
TerminalIO.WriteRope[" maximum row specified = "]; TerminalIO.WriteInt[maxRowSpec];
TerminalIO.WriteRope["\n computed number of rows = "]; TerminalIO.WriteInt[detRow];
TerminalIO.WriteRope["\n number of rows specified = "]; TerminalIO.WriteInt[numRows];
TerminalIO.WriteRope["\n number of rows used = "]; TerminalIO.WriteInt[lgRows.count];
TerminalIO.WriteLn[]};
DetermineSides: PROCEDURE [handle: SC.Handle] = {
determine the number of Bps on sides to use
SideSlots: SCRowUtil.EachSideProc = {
bpRow.maxBpsOnSide ← MAX[bpRow.initMaxBpsOnSide, bpRow.nBpsOnSide];
IF bpRow.maxBpsOnSide > 0 THEN {
totBpSlots ← totBpSlots + bpRow.maxBpsOnSide;
nSidesAvail ← nSidesAvail -1}};
SetSlots: SCRowUtil.EachSideProc = {
IF bpRow.maxBpsOnSide <= 0 THEN bpRow.maxBpsOnSide ← nBps};
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
instances: SCPrivate.Instances ← structureData.instances;
nSidesAvail: NAT[0..4] ← 4;
totBpSlots: NAT ← 0; 
nBps: NAT;
compute number of slots to put on currently empty sides
[] ← SCRowUtil.EnumerateSides[handle, SideSlots];
IF nSidesAvail > 0 THEN
nBps ← MAX[0, (instances.numIOs - totBpSlots +3) /nSidesAvail]
ELSE {
nBps ← 0;
IF instances.numIOs > totBpSlots THEN
SC.Error[callingError, "Too many IO's"]};
[] ← SCRowUtil.EnumerateSides[handle, SetSlots]};
PrePlace: PUBLIC PROCEDURE[handle: SC.Handle, numRows: NAT ← 0, initialized: BOOLEAN ← TRUE] = {
TerminalIO.WriteRope["Pre placement\n"];
InitBpSide[handle];
InitLgRow[handle];
SCChanUtil.ClearRouteDat[handle];
PrePlaceComps[handle, initialized];
DetermineRows[handle, numRows];
DetermineSides[handle];
TerminalIO.WriteRope["End pre placement\n"];
IF debug THEN SCPlaceUtil.WriteCurPlace[handle]};
END.