<> 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: BOOLEAN _ FALSE; ChooseNonZero: PROCEDURE [num1, num2, num3: SC.Number _ 0] RETURNS[ result: SC.Number] = { << >> <> IF num1 # 0 THEN result _ num1 ELSE IF num2 # 0 THEN result _ num2 ELSE result _ num3}; InitBpSide: PROCEDURE [handle: SC.Handle] = { << >> <> 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] = { << >> <> 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] = { <
>

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] = {
<>

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};
 
<>
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}}
<<>>
<>
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]}
<<>>
<>
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};
<<>>
<>
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] = {
<>

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};
<<>>
<>
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}}
<<>>
<>
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]}
<<>>
<>
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};
<<>>
<>
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.EnumerateInstances[handle, EachInstance]}; 

DetermineRows: PROCEDURE [handle: SC.Handle] = {
<>

EachInstance: SCInstUtil.EachInstanceProc = {
IF instance.whichClass = logic THEN {
maxRowSpec _ MAX[instance.initRow, MAX[maxRowSpec, instance.fnlRow]];
<>
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 _ 0;
maxRowSpec, avgHeight, totLinComps: SC.Number _ 0;
numRows: NAT _ 0;

[] _ SCInstUtil.EnumerateInstances[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] = {

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

<>
[] _ 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, initialized: BOOLEAN] = {

TerminalIO.WriteRope["Pre placement\n"];
InitBpSide[handle];
InitLgRow[handle];
SCChanUtil.ClearRouteDat[handle];
PrePlaceComps[handle, initialized];
DetermineRows[handle];
DetermineSides[handle];
TerminalIO.WriteRope["End pre placement\n"];
IF debug THEN SCPlaceUtil.WriteCurPlace[handle]}; 
END.