SCAreaEstImpl.mesa
Copyright Ó 1988 by Xerox Corporation. All rights reserved.
Massoud Pedram March 10, 1989 11:48:07 am PST
DIRECTORY
SC, SCPrivate, SCInstUtil, SCNetUtil, DABasics, RefTab, Real, RealFns, TerminalIO, Rope, IO, SCAreaEst, CDSimpleRules;
SCAreaEstImpl: CEDAR PROGRAM
IMPORTS SC, SCInstUtil, SCNetUtil, RefTab, Real, RealFns, TerminalIO, IO, CDSimpleRules
EXPORTS SCAreaEst
SHARES SC , SCPrivate =
BEGIN
Common Types
ChipData: TYPE = REF ChipDataRec;
ChipDataRec: TYPE = RECORD [
name: Rope.ROPE,
numRows, numComp, numNets: INT ← 0,
xRange, yRange: INT ← 0,
any: REFNIL];
Set: TYPE = LIST OF REF INT;
Sets: TYPE = LIST OF Set;
Int0: TYPE = INT ← 0;
Real0: TYPE = REAL ← 0.0;
VecSeq: TYPE = RECORD[SEQUENCE ncols: INTEGER OF Int0];
RowN: TYPE = REF VecSeq;
VecSeqR: TYPE = RECORD[SEQUENCE ncols: INTEGER OF Real0];
RowR: TYPE = REF VecSeqR;
technologyKey: ATOM = $cmosB;
lambda: INT ← CDSimpleRules.GetTechnology[technologyKey].lambda;
maxPinPerNet: NAT ← 25;
maxRows: INT ← 30;
Utilities
CreateChipData: PROC [name: Rope.ROPE, numComp, numRows, numNets: NAT] RETURNS [chipData: ChipData] ~ {
chipData ← NEW[ChipDataRec ← [name: name]];
chipData.numComp ← numComp;
chipData.numRows ← numRows;
chipData.numNets ← numNets;
chipData.any ← NIL};
Poisson: PUBLIC PROC [a: REAL, k: INT] RETURNS [res: REAL] ~ {
res ← -a + k * RealFns.Ln[a];
FOR i: INT ← 1, i+1 UNTIL i > k DO
res ← res - RealFns.Ln[Real.Float[i]];
ENDLOOP;
IF res < -88 THEN res ← 0
ELSE IF res <= 88 THEN res ← RealFns.Exp[res]
ELSE SC.Signal[callingError, "a is too large."];
};
Power: PUBLIC PROC [i: REAL, n: INT] RETURNS [res: REAL] ~ {
res ← 1.0;
FOR k: INT ← 1, k+1 UNTIL k > n DO
res ← res * i;
ENDLOOP;
};
Factorial: PUBLIC PROC [n: INT] RETURNS [p: REAL] ~ {
n=34 is highest integer permissible.
IF n > 34 THEN SC.Signal[callingError, "n is too large."];
p ← 1.0;
UNTIL n <= 0 DO
p ← p*n; n ← n-1;
ENDLOOP;
};
Choose: PUBLIC PROC [n: INT, i: INT] RETURNS [p: REAL] ~ {
n=125, i=62 are highest set permissible.
k: REAL;
IF (n < i) THEN p ← 0
ELSE {
p ← 1.0;
k ← n;
UNTIL k <= n-i DO
p ← (p*k)/(n-k+1); k ← k-1;
ENDLOOP};
};
SumOver: PUBLIC PROC [clientData: REF, clientProc: SCAreaEst.StatProc, start, end: INT] RETURNS [sum: REAL] ~ {
sum ← 0.0;
FOR i: INT ← start, i+1 UNTIL i > end DO
sum ← sum + clientProc[clientData, i];
ENDLOOP;
};
ExpectedVal: PUBLIC PROC [clientData: REF, clientProc: SCAreaEst.StatProc, start, end: INT] RETURNS [val: REAL] ~ {
val ← 0.0;
FOR i: INT ← start, i+1 UNTIL i > end DO
val ← val + i * clientProc[clientData, i];
ENDLOOP;
};
Area Estimation
SolveBase: PROC[sum: INT] RETURNS [sets: Sets] ~ {
w: INT ← 1;
UNTIL w > sum/2 DO
set: Set ← NIL;
IF w <= sum - w THEN {
set ← CONS[NEW[INT ← sum-w], set];
set ← CONS[NEW[INT← w], set];
sets ← CONS[set, sets]};
w ← w + 1;
ENDLOOP};
SolveN: PROC[n, sum: INT] RETURNS [sets: Sets] ~ {
sets ← NIL;
IF n <= 1 THEN
RETURN[sets]
ELSE IF n = 2 THEN
sets ← SolveBase[sum]
ELSE {
w: INT ← 1;
UNTIL w > sum/n DO
preSets: Sets ← SolveN[n-1, sum-w];
FOR preSets ← preSets, preSets.rest WHILE preSets#NIL DO
set: Set ← NIL;
firstPreSet: Set ← preSets.first;
IF w <= firstPreSet.first^ THEN {
FOR firstPreSet ← firstPreSet, firstPreSet.rest WHILE firstPreSet#NIL DO
set ← CONS[firstPreSet.first, set];
ENDLOOP;
set ← CONS[NEW[INT ← w], set];
sets ← CONS[set, sets]};
ENDLOOP;
w ← w + 1;
ENDLOOP}};
FracLength: PUBLIC PROC [clientData: REF, m, w: INT] RETURNS [tdf: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← j * (w - j + 1) * Choose[j-2, m-2] / w / Choose[w, m];
};
tdf ← IF m > w THEN 1.0
ELSE IF m < 2 THEN 0
ELSE SumOver[clientData, applyMe, m, w];
};
FracHeight: PUBLIC PROC [clientData: REF, m, w: INT] RETURNS [numFT: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← j * (w - j + 1) * Choose[j-2, m-2] / Choose[w, m];
};
numFT ← IF m > w OR m < 2 THEN 0
ELSE SumOver[clientData, applyMe, m, w] - m;
};
VertSpan: PROC [clientData: REF, m, w: INT] RETURNS [span: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← j * (w - j + 1) * Choose[j-2, m-2] / Choose[w, m];
};
IF m > w OR m < 1 THEN
span ← 0
ELSE IF m=1 THEN
span ← 1
ELSE
span ← SumOver[clientData, applyMe, m, w];
};
BTrackProb: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
B: PROC [clientData: REF, i: INT] RETURNS [p: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
chipData: ChipData ← NARROW[clientData];
p ← Choose[i, j] * B[chipData, j];
};
p ← IF i = 1 THEN 1.0 ELSE Power[i, d] - SumOver[clientData, applyMe, 1, i-1];
};
chipData: ChipData ← NARROW[clientData];
d: INTNARROW[chipData.any, REF INT]^;
n: INT ← chipData.yRange;
k: INTIF d < n THEN d ELSE n;
p ← IF j > d THEN 0 ELSE Power[1.0 / n, d] * Choose[n, j] * B[clientData, j];
};
BFTProb: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
Bft: PROC [clientData: REF, i: INT] RETURNS [p: REAL] ~ {
p ← i * Power[(n-1.0)/(2.0*n), i];
};
chipData: ChipData ← NARROW[clientData];
n: INT ← chipData.yRange;
h: INTNARROW[chipData.any, REF INT]^;
p ← Power[Bft[clientData, 2], j] * Power[(1 - Bft[clientData, 2]), h - j] * Choose[h, j];
};
POccupyRow: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
B: PROC [clientData: REF, i: INT] RETURNS [p: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
chipData: ChipData ← NARROW[clientData];
p ← Choose[i, j] * B[chipData, j];
};
p ← IF i = 1 THEN 1.0 ELSE Power[i, d] - SumOver[clientData, applyMe, 1, i-1];
};
chipData: ChipData ← NARROW[clientData];
d: INTNARROW[chipData.any, REF INT]^;
n: INT ← chipData.yRange; -- Must be yRange and not numRows.
k: INTIF d < n THEN d ELSE n;
p ← IF j > d THEN 0 ELSE Power[1.0 / n, d] * Choose[n, j] * B[clientData, j];
};
PTrack: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
P: PROC [clientData: REF, i: INT] RETURNS [p: REAL] ~ {
F: PROC [m: INT, set: Set] RETURNS [f: REAL] ~ {
vecN: RowN ← NEW[VecSeq[d+1]];
f ← Factorial[m];
FOR set ← set, set.rest WHILE set#NIL DO
curInt: INT ← set.first^;
vecN[curInt] ← vecN[curInt] + 1;
ENDLOOP;
FOR i: INT IN [1..d] DO
f ← f / Factorial[vecN[i]];
ENDLOOP;
};
G: PROC [set: Set] RETURNS [g: REAL] ~ {
g ← Factorial[d];
FOR set ← set, set.rest WHILE set#NIL DO
curInt: INT ← set.first^;
g ← g / Factorial[curInt];
ENDLOOP;
};
A: PROC [clientData: REF, set: Set] RETURNS [a: REAL] ~ {
count: INT ← 0;
curInt: INT;
a ← 0;
FOR set ← set, set.rest WHILE set#NIL DO
IF count = 0 THEN {
curInt ← set.first^;
IF curInt # 1 THEN a ← a + FracLength[clientData, curInt, w]}
ELSE {
curInt ← set.first^ + 1;
a ← a + FracLength[clientData, curInt, w]};
count ← count + 1;
ENDLOOP;
a ← a / i;
};
sets: Sets;
c: INT ← 0;
IF i = 1 THEN {
RETURN[FracLength[clientData, d, w]]};
sets ← SolveN[i, d];
p ← 0;
FOR sets ← sets, sets.rest WHILE sets#NIL DO
set: Set ← sets.first;
p ← p + F[i, set] * G[set] * A[clientData, set];
c ← c + 1;
ENDLOOP;
};
chipData: ChipData ← NARROW[clientData];
d: INTNARROW[chipData.any, REF INT]^;
n: INT ← chipData.yRange;
w: INT ← chipData.xRange;
p ← IF j > d THEN 0 ELSE Power[1.0 / n, d] * Choose[n, j] * P[clientData, j];
};
PCentralFts: PROC [clientData: REF, d: INT] RETURNS [p: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
meAgain: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← Power[(n-1.0) / (2.0*n), d-l] * Choose[d-l, j];
};
l: INT ← j;
p ← Choose[d, l] * SumOver[clientData, meAgain, 1, d - l -1];
};
chipData: ChipData ← NARROW[clientData];
n: INT ← chipData.numRows;
p ← IF n <= 2 THEN 0 ELSE SumOver[clientData, applyMe, 0, d-2] / (Power[2, d] - d -1);
};
PFtInRow: PROC [clientData: REF, d: INT, i: INT] RETURNS [p: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
meAgain: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← Power[(i-1.0) / n, j] * Power[Real.Float[n-i] / n, d-j-l] * Choose[d-l, j];
};
l: INT ← j;
p ← Choose[d, l] * SumOver[clientData, meAgain, 1, d - l -1];
};
chipData: ChipData ← NARROW[clientData];
n: INT ← chipData.numRows;
p ← SumOver[clientData, applyMe, 0, d-2] / (Power[2, d] - d -1);
};
PAllFts: PROC [clientData: REF, d: INT] RETURNS [p: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
meAgain: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
allowMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← Power[(i-1.0) / n, j] * Power[Real.Float[n-i] / n, d-j-l] * Choose[d-l, j];
};
l: INT ← j;
p ← Choose[d, l] * SumOver[clientData, allowMe, 1, d - l -1];
};
i: INT ← j;
p ← SumOver[clientData, meAgain, 0, d-2];
};
chipData: ChipData ← NARROW[clientData];
n: INT ← chipData.numRows;
p ← SumOver[clientData, applyMe, 1, n] / (Power[2, d] - d -1);
};
LengthD: PUBLIC PROC [clientData: REF] RETURNS [c: REAL] ~ {
chipData: ChipData ← NARROW[clientData];
c ← 0.0;
FOR i: INT ← 1, i+1 UNTIL i > chipData.yRange DO
c ← c + i * PTrack[clientData, i];
ENDLOOP;
};
HeightD: PROC[clientData: REF] RETURNS [c: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← POccupyRow[clientData, j] * FracHeight[clientData, j, n];
};
k: INT;
chipData: ChipData ← NARROW[clientData];
n: INT ← chipData.yRange;
d: INTNARROW[chipData.any, REF INT]^;
IF d <= n THEN k ← d ELSE k ← n;
c ← SumOver[clientData, applyMe, 2, k];
};
XSpan: PROC [clientData: REF] RETURNS [c: REAL] ~ {
chipData: ChipData ← NARROW[clientData];
c ← 0.0;
FOR i: INT ← 1, i+1 UNTIL i > chipData.yRange DO
c ← c + i * HorizSpan[clientData, i];
ENDLOOP;
};
YSpan: PROC[clientData: REF] RETURNS [c: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← POccupyRow[clientData, j] * VertSpan[clientData, j, n];
};
k: INT;
chipData: ChipData ← NARROW[clientData];
n: INT ← chipData.yRange;
d: INTNARROW[chipData.any, REF INT]^;
IF d <= n THEN k ← d ELSE k ← n;
c ← SumOver[clientData, applyMe, 1, k];
};
EstimateArea: PUBLIC PROC [handle: SC.Handle, numRows: NAT, basic: BOOLEANTRUE] RETURNS[size: DABasics.Position]~ {
estimates the area of an SC cellType.
TrackScaleRatio: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
chipData: ChipData ← NARROW[clientData];
d: INTNARROW[chipData.any, REF INT]^;
p ← (cellWidth*cellPerRow*pAllFts + ftWidth*numFTs*PFtInRow[clientData, d, j]) / (cellWidth*cellPerRow*pAllFts + ftWidth*numFTs*PFtInRow[clientData, d, j-1]);
};
ChanWidthCorrection: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
chipData: ChipData ← NARROW[clientData];
d: INTNARROW[chipData.any, REF INT]^;
chanWidth: REAL ← (cellWidth*cellPerRow + ftWidth*numFTs*PFtInRow[clientData, d, j-1] / pAllFts + cellWidth*cellPerRow + ftWidth*numFTs*PFtInRow[clientData, d, j] / pAllFts) / 2.0;
centralChanWidth: REAL ← cellWidth*cellPerRow + ftWidth*maxFtRatio*numFTs;
p ← centralChanWidth - chanWidth;
};
PinPerNet: PROC[clientData: REF] RETURNS [p: REAL] ~ {
applyMe: SCAreaEst.StatProc ~ {
PROC [clientData: REF, j: INT] RETURNS [p: REAL];
p ← nets[j] * j;
};
p ← SumOver[clientData, applyMe, 2, maxPinPerNet] / numNets;
};
EachSourceInst: RefTab.EachPairAction ~ {
EachPinNet: SCInstUtil.EachPinProc ~ {
PROC [instance: SCPrivate.Instance, pin: NAT, netPin: SCPrivate.PinNet] RETURNS [quit: BOOLFALSE];
EachNetPinInit: SCNetUtil.EachPinProc = {
PROC [netPin: SCPrivate.NetPin] RETURNS [quit: BOOLFALSE];
instance: SCPrivate.Instance ← netPin.instance;
IF instance # NIL THEN {
IF netPin.pinClass = compPin AND netPin.pin.pinPos.side = top THEN numPins ← numPins + 1;
};
};
EachNetPin: SCNetUtil.EachPinProc = {
PROC [netPin: SCPrivate.NetPin] RETURNS [quit: BOOLFALSE];
instance: SCPrivate.Instance ← netPin.instance;
IF instance # NIL THEN {
IF netPin.pinClass = compPin AND netPin.pin.pinPos.side = top THEN {
[] ← RefTab.Insert[instanceTable, instance, instance]
};
};
};
numPins: INT ← 0;
Poor choice of variable names in SCPrivate.PinNet
IF netPin.pin.pinPos.side = top THEN {
[] ← SCNetUtil.EnumeratePinsOnNet[netPin.net, EachNetPinInit];
numPins ← IF netPin.net.externNet THEN numPins + 1 ELSE numPins;
IF numPins <= numLogics/10 THEN
[] ← SCNetUtil.EnumeratePinsOnNet[netPin.net, EachNetPin];
};
};
instance: SCPrivate.Instance ← NARROW [val];
widthSum ← widthSum + SCInstUtil.InstWidth[instance];
numSourceInst ← numSourceInst + 1;
[] ← SCInstUtil.EnumeratePinsOnInst[instance, EachPinNet];
connCellSum ← connCellSum + RefTab.GetSize[instanceTable];
RefTab.Erase[instanceTable];
};
EachNet: RefTab.EachPairAction ~ {
net: SCPrivate.Net ← NARROW [val];
netPin: SCPrivate.NetPin ← net.pins;
numPins: NAT ← 0;
WHILE netPin#NIL DO
next: SCPrivate.NetPin ← netPin.link;
numPins ← IF netPin.pinClass = compPin AND netPin.pin.pinPos.side = top THEN numPins + 1 ELSE numPins;
netPin ← next;
ENDLOOP;
IF numPins > maxPinPerNet THEN {
numLargeNets ← numLargeNets + 1;
nets[maxPinPerNet] ← nets[maxPinPerNet] + 1;
IF net.externNet THEN publicNets[maxPinPerNet] ← publicNets[maxPinPerNet] + 1}
ELSE {
IF net.externNet THEN {
numPins ← numPins + 1;
publicNets[numPins] ← publicNets[numPins] + 1};
nets[numPins] ← nets[numPins] + 1};
};
totConnCells, numConnCells, connCellSum: INT ← 0;
numLargeNets, numSourceInst, numLogics, numNets, numIOs: NAT ← 0;
cellPerRow: NAT;
areaCorrection, cellHeight, cellWidth: REAL;
ftWidth, trackSpacing, contactToContact: INT;
cRow: NAT;
pinPerNet, pinPerChan, netPerChan, ftPerNet, pAllFts, maxFtRatio: REAL;
numPTracks, numAdjTracks, numWTracks, numFTs, numCentralFTs: REAL ← 0;
numSegPerNet: NAT;
tracksInChan, segLength, widthSum: REAL ← 0;
heuristicMul1, heuristicMul2: REAL ← 1.5;
nets: RowN ← NIL;
publicNets: RowN ← NIL;
lookUpL: RowR ← NIL;
lookUpH: RowR ← NIL;
ySpan: RowR ← NIL;
chipData: ChipData ← NIL;
structureData: SCPrivate.StructureData ← NARROW[handle.structureData];
parms: SCPrivate.Parms ← NARROW[handle.parms];
done: BOOLEANFALSE;
tks: INT ← 0;
density, confidence, confLevel: REAL ← 0;
instanceTable: RefTab.Ref ← RefTab.Create[]; -- temporary table
estAR, yToXCost: REAL ← 2.0;
cellAR: REAL;
fracLengthSum, fracHeightSum: REAL;
yRange, numRects: INT;
IF numRows < 2 THEN numRows ← 2;
numLogics ← structureData.instances.numLogics;
numNets ← RefTab.GetSize[structureData.nets];
numIOs ← structureData.instances.numIOs;
[] ← RefTab.Pairs[structureData.sourceInstances, EachSourceInst];
numConnCells ← Real.Round[Real.Float[connCellSum] / Real.Float[numSourceInst]];
IF numConnCells < 2 THEN numConnCells ← 2;
cellWidth ← widthSum / Real.Float[numSourceInst] / Real.Float[lambda];
cellHeight ← Real.Float[parms.ftObject.size.q] / Real.Float[lambda];
ftWidth ← parms.ftObject.size.p / lambda;
trackSpacing ← handle.rules.rowRules.trunkToTrunk / lambda;
contactToContact ← handle.rules.rowRules.contactToContact / lambda;
nets ← NEW[VecSeq[maxPinPerNet+1]];
publicNets ← NEW[VecSeq[maxPinPerNet+1]];
lookUpL ← NEW[VecSeqR[maxPinPerNet+1]];
lookUpH ← NEW[VecSeqR[maxPinPerNet+1]];
ySpan ← NEW[VecSeqR[maxPinPerNet+1]];
[] ← RefTab.Pairs[structureData.nets, EachNet];
numNets ← numNets - nets[0] - nets[1];
chipData ← CreateChipData[handle.name, numLogics, numRows, numNets];
cellPerRow ← Real.Ceiling[Real.Float[numLogics] / Real.Float[numRows]];
estAR ← yToXCost*(numRows*cellHeight)/(cellPerRow*cellWidth);
cellAR ← cellHeight / cellWidth;
FOR i: NAT IN [2..maxPinPerNet) DO
IF i <= 20 AND nets[i] # 0 THEN {
chipData.any ← NEW[INT ← i];
IF basic THEN {
chipData.yRange ← numRows;
chipData.xRange ← numLogics / numRows;
lookUpL[i] ← LengthD[chipData] * chipData.xRange * numRows / numLogics;
numPTracks ← numPTracks + nets[i] * lookUpL[i];
lookUpH[i] ← HeightD[chipData];
numFTs ← numFTs + nets[i] * lookUpH[i];
}
ELSE {
totConnCells ← IF i*(numConnCells-1) > numLogics THEN numLogics ELSE i*(numConnCells-1);
fracLengthSum ← 0; fracHeightSum ← 0; numRects ← 0;
yRange ← Real.Round[RealFns.SqRt[totConnCells/(2*cellAR)]];
FOR y: INT IN [1..numRows] DO
chipData.yRange ← y;
chipData.xRange ← IF Real.Ceiling[Real.Float[totConnCells]/y] > numLogics/numRows THEN numLogics/numRows ELSE Real.Ceiling[Real.Float[totConnCells]/y];
IF Real.Float[chipData.yRange]/chipData.xRange <= 2*cellAR THEN {
IF y = yRange THEN {
fracLengthSum ← fracLengthSum + 4 * LengthD[chipData] * chipData.xRange * numRows / numLogics;
fracHeightSum ← fracHeightSum + 4 * HeightD[chipData];
numRects ← numRects + 4}
ELSE IF y = yRange+1 OR y = yRange-1 THEN {
fracLengthSum ← fracLengthSum + 2 * LengthD[chipData] * chipData.xRange * numRows / numLogics;
fracHeightSum ← fracHeightSum + 2 * HeightD[chipData];
numRects ← numRects + 2}
ELSE {
fracLengthSum ← fracLengthSum + LengthD[chipData] * chipData.xRange * numRows / numLogics;
fracHeightSum ← fracHeightSum + HeightD[chipData];
numRects ← numRects + 1}
}
ELSE EXIT;
ENDLOOP;
IF numRects = 0 THEN {
SC.Signal[callingError, "numRects cannot be zero"];
numRects ← 1};
lookUpL[i] ← fracLengthSum / numRects;
numPTracks ← numPTracks + nets[i] * lookUpL[i];
lookUpH[i] ← fracHeightSum / numRects;
numFTs ← numFTs + nets[i] * lookUpH[i];
};
};
ENDLOOP;
cellPerRow ← Real.Ceiling[Real.Float[numLogics] / Real.Float[numRows]];
ftPerNet ← numFTs / numNets;
pinPerNet ← PinPerNet[chipData];
netPerChan ← Real.Float[numNets] / Real.Float[numRows-1];
pinPerChan ← (ftPerNet + pinPerNet)* netPerChan;
IF basic THEN {
pAllFts ← PAllFts[chipData, Real.Round[pinPerNet]];
cRow ← Real.Ceiling[numRows / 2.0];
chipData.any ← NEW[INT ← Real.Round[pinPerNet]];
maxFtRatio ← IF numRows = 2 THEN 1 ELSE PFtInRow[chipData, Real.Round[pinPerNet], cRow] / pAllFts;
numCentralFTs ← numFTs * maxFtRatio;
}
ELSE {
numCentralFTs ← numFTs / numRows;
};
numAdjTracks ← 0;
FOR i: INT IN [2..maxPinPerNet) DO
IF nets[i]#0 THEN {
numSegPerNet ← Real.Ceiling[ySpan[i]] - 1;
segLength ← lookUpL[i] / numSegPerNet + contactToContact / (cellPerRow * cellWidth);
IF segLength > 1 THEN segLength ← 1;
tracksInChan ← nets[i] * Real.Float[numSegPerNet] / (numRows - 1) / Real.Floor[1.0/segLength];
numAdjTracks ← numAdjTracks + Real.Ceiling[tracksInChan] * (numRows - 1)};
ENDLOOP;
density ← numPTracks / (numRows - 1);
confLevel ← IF basic THEN 0.9995 ELSE 0.975;
WHILE NOT done DO
confidence ← confidence + Poisson[density, tks];
tks ← tks + 1;
IF confidence >= confLevel THEN done ← TRUE;
ENDLOOP;
numAdjTracks ← (tks - 1) * (numRows - 1);
IF basic THEN areaCorrection ← 2 * numAdjTracks * trackSpacing * SumOver[chipData, ChanWidthCorrection, 2, cRow] / (numRows-1)
ELSE areaCorrection ← 0;
size.x ← Real.Ceiling[cellPerRow * cellWidth] + Real.Ceiling[numCentralFTs * ftWidth];
numWTracks ← numAdjTracks + areaCorrection / size.x / trackSpacing;
size.y ← Real.Ceiling[numWTracks * trackSpacing] + Real.Ceiling[Real.Float[numRows] * cellHeight];
TerminalIO.PutF["Area Estimator Statistics: \n\tinstances: %g, numNets: %g, numRows: %g", IO.int[numLogics], IO.int[numNets], IO.int[numRows]];
IF NOT basic THEN TerminalIO.PutF["\n\tnumConnCells: %g", IO.real[numConnCells]];
IF numLargeNets # 0 THEN TerminalIO.PutF["\n\tnumLargeNets: %g", IO.real[numLargeNets]];
TerminalIO.PutF["\n\tnumPTracks: %g, numAdjTracks: %g", IO.real[numPTracks], IO.real[numAdjTracks]];
IF basic THEN TerminalIO.PutF["\n\tnumWTracks: %g", IO.real[numWTracks]];
TerminalIO.PutF["\n\tnumFTs: %g, numCentralFTs: %g", IO.real[numFTs], IO.real[numCentralFTs]];
TerminalIO.PutF["\n\tchipWidth: %g, chipHeight: %g\n", IO.int[size.x], IO.int[size.y]];
};
Initialization
vecC: RowR ← NEW[VecSeqR[maxRows]];
END.