EstimateArea:
PUBLIC
PROC [handle:
SC.Handle, numRows:
NAT, basic:
BOOLEAN ←
TRUE]
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: INT ← NARROW[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: INT ← NARROW[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: BOOL ← FALSE];
EachNetPinInit: SCNetUtil.EachPinProc = {
PROC [netPin: SCPrivate.NetPin] RETURNS [quit: BOOL ← FALSE];
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: BOOL ← FALSE];
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: BOOLEAN ← FALSE;
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]];
};