DIRECTORY IO, Rope, SC, SCStats, TerminalIO, SCPrivate, RefTab, RefTabExtras, CDSimpleRules, Real; SCStatsImpl: CEDAR PROGRAM IMPORTS SC, IO, TerminalIO, RefTab, RefTabExtras, CDSimpleRules, Real EXPORTS SCStats SHARES SC = BEGIN OPEN SCStats; CreateForRopes: PUBLIC PROC [mod: NAT _ 17] RETURNS [Table] ~ { RETURN[RefTab.Create[mod, RefTabExtras.EqualRope, RefTabExtras.HashRope]]}; Fetch: PUBLIC PROC [table: Table, key: Key] RETURNS [found: BOOL, netStat: NetStat] ~ { value: REF; [found, value] _ RefTab.Fetch[table, key]; netStat _ NARROW[value]}; Store: PUBLIC PROC [table: Table, key: Key, netStat: NetStat] RETURNS [BOOL] ~ { RETURN[RefTab.Store[table, key, netStat]]}; EnumerateNetStats: PUBLIC PROC [table: Table, action: EachNetStatAction] RETURNS [BOOL] ~ { eachPair: RefTab.EachPairAction ~ {quit _ action[key, NARROW [val]]}; RETURN [RefTab.Pairs[table, eachPair]]}; WriteSummaryStats: PUBLIC PROC [result: SC.Result] ~ { handle: SC.Handle _ result.handle; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; rowChans: SCPrivate.RowChans _ layoutData.rowChans; lgRows: SCPrivate.LgRows _ layoutData.lgRows; TerminalIO.PutRope[text: "\n Routing Summary Statistics"]; FOR chanNum: NAT IN [1 .. rowChans.count] DO chan: SCPrivate.RowChan _ rowChans.chans[chanNum]; TerminalIO.PutF[format: "\n\tchannel: %g", v1: IO.int[chanNum]]; TerminalIO.PutF[format: "\n\t\tnumTracks: %g", v1: IO.int[chan.chanWidth/handle.rules.rowRules.trunkToTrunk]]; ENDLOOP; FOR rowNum: NAT IN [1 .. lgRows.count] DO row: SCPrivate.LgRow _ lgRows.rows[rowNum]; TerminalIO.PutF[format: "\n\trow: %g", v1: IO.int[rowNum]]; TerminalIO.PutF[format: "\n\t\tCellsOnRow: %g", v1: IO.int[row.nLgsOnRow - row.nFtsOnRow]]; TerminalIO.PutF[format: "\n\t\tFtsOnRow: %g", v1: IO.int[row.nFtsOnRow]]; ENDLOOP; TerminalIO.PutRope[text: "\n End Routing Summary Statistics\n"]; }; WriteDetailStats: PUBLIC PROC [result: SC.Result] ~ { stats: LIST OF SC.ChannelStats _ result.stats; TerminalIO.PutRope[text: "\n Routing Statistics"]; UNTIL stats = NIL DO netStats: LIST OF SC.NetEntry _ stats.first.netStats; TerminalIO.PutF[format: "\n\tchannel: %g", v1: IO.int[stats.first.channel]]; UNTIL netStats = NIL DO pinStats: LIST OF SC.PinEntry _ netStats.first.pinStats; ftStats: LIST OF SC.PinEntry _ netStats.first.ftStats; TerminalIO.PutF[format: "\n\t\tname: %g, leftExit: %g, rightExit: %g", v1: IO.rope[netStats.first.name], v2: IO.bool[netStats.first.leftExit], v3: IO.bool[netStats.first.rightExit]]; UNTIL ftStats = NIL DO TerminalIO.PutF[format: "\n\t\t\tfeedThroughBottom: %g, position: %g", v1: IO.bool[ftStats.first.bottom], v2: IO.int[ftStats.first.position]]; ftStats _ ftStats.rest; ENDLOOP; UNTIL pinStats = NIL DO TerminalIO.PutF[format: "\n\t\t\tbottom: %g, position: %g", v1: IO.bool[pinStats.first.bottom], v2: IO.int[pinStats.first.position]]; pinStats _ pinStats.rest; ENDLOOP; netStats _ netStats.rest; ENDLOOP; stats _ stats.rest; ENDLOOP; TerminalIO.PutRope[text: "\n End Routing Statistics\n"]; }; CreateNetStats: PUBLIC PROC [result: SC.Result] RETURNS [table: Table] ~ { EachNet: RefTab.EachPairAction ~ { net: SCPrivate.Net _ NARROW [val]; netPin: SCPrivate.NetPin _ net.pins; numPins: NAT _ 0; netStat: NetStat; 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 net.externNet THEN numPins _ numPins + 1; netStat _ Fetch[table, net.name].netStat; IF netStat#NIL THEN { netStat.numPins _ numPins; [] _ Store[table, net.name, netStat]}; }; technologyKey: ATOM = $cmosB; lambda: INT _ CDSimpleRules.GetTechnology[technologyKey].lambda; stats: LIST OF SC.ChannelStats _ result.stats; minX, maxX: INT; minY, maxY: INT; trackLength: INT; structureData: SCPrivate.StructureData _ NARROW[result.handle.structureData]; layoutData: SCPrivate.LayoutData _ NARROW[result.handle.layoutData]; totWidth: INT _ layoutData.totWidth / lambda; table _ CreateForRopes[]; TerminalIO.PutRope[text: "\n Routing Statistics"]; UNTIL stats = NIL DO netStats: LIST OF SC.NetEntry _ stats.first.netStats; netStat: NetStat; minY _ LAST[INT]; maxY _ FIRST[INT]; UNTIL netStats = NIL DO pinStats: LIST OF SC.PinEntry _ netStats.first.pinStats; ftStats: LIST OF SC.PinEntry _ netStats.first.ftStats; numFTs: INT _ 0; minX _ LAST[INT]; maxX _ FIRST[INT]; IF netStats.first.leftExit THEN minX _ 0; IF netStats.first.rightExit THEN maxX _ totWidth; UNTIL ftStats = NIL DO IF ftStats.first.bottom THEN numFTs _ numFTs + 1; ftStats _ ftStats.rest; ENDLOOP; IF numFTs > 1 THEN numFTs _ 1; UNTIL pinStats = NIL DO IF pinStats.first.position / lambda < minX THEN minX _ pinStats.first.position / lambda; IF pinStats.first.position / lambda > maxX THEN maxX _ pinStats.first.position / lambda; pinStats _ pinStats.rest; ENDLOOP; IF stats.first.channel < minY THEN minY _ stats.first.channel; IF stats.first.channel > maxY THEN maxY _ stats.first.channel; netStat _ Fetch[table, netStats.first.name].netStat; trackLength _ maxX - minX; IF netStat=NIL THEN { netStat _ NEW [NetStatRec _ [name: netStats.first.name, xSpan: [minX, maxX], ySpan: [minY, maxY], trackLength: trackLength, ftHeight: numFTs]]} ELSE { IF netStat.xSpan.min > minX THEN netStat.xSpan.min _ minX; IF netStat.xSpan.max < maxX THEN netStat.xSpan.max _ maxX; IF netStat.ySpan.min > minY THEN netStat.ySpan.min _ minY; IF netStat.ySpan.max < maxY THEN netStat.ySpan.max _ maxY; netStat.ftHeight _ netStat.ftHeight + numFTs; netStat.trackLength _ netStat.trackLength + maxX - minX}; IF netStat.trackLength < 0 THEN netStat.trackLength _ 0; [] _ Store[table, netStats.first.name, netStat]; netStats _ netStats.rest; ENDLOOP; stats _ stats.rest; ENDLOOP; [] _ RefTab.Pairs[structureData.nets, EachNet]; TerminalIO.PutRope[text: "\n End Routing Statistics\n"]; }; WriteDetailNetStats: PUBLIC PROC [table: Table] ~ { EachNetStat: EachNetStatAction ~ { TerminalIO.PutF[format: "\n\t\tname: %g, \tnumPins: %g", v1: IO.rope[netStat.name], v2: IO.int[netStat.numPins]]; TerminalIO.PutF[format: "\n\t\t\txSpan: %g, %g, \t\tySpan: %g, %g", v1: IO.int[netStat.xSpan.min], v2: IO.int[netStat.xSpan.max], v3: IO.int[netStat.ySpan.min], v4: IO.int[netStat.ySpan.max]]; TerminalIO.PutF[format: "\n\t\t\ttrackLength: %g, \tftHeight: %g \n", v1: IO.int[netStat.trackLength], v2: IO.int[netStat.ftHeight]]}; [] _ EnumerateNetStats[table, EachNetStat]}; WriteSummaryNetStats: PUBLIC PROC [result: SC.Result, table: Table] ~ { NumNets: EachNetStatAction ~ { k: NAT _ netStat.numPins; IF k > maxPinPerNet THEN k _ maxPinPerNet; nets[k] _ nets[k] + 1; }; Avg: EachNetStatAction ~ { k: NAT _ netStat.numPins; IF k > maxPinPerNet THEN k _ maxPinPerNet; IF netStat.xSpan.max < netStat.xSpan.min THEN SC.Signal[callingError, "netStat.xSpan is calculated wrong."]; IF netStat.ySpan.max < netStat.ySpan.min THEN SC.Signal[callingError, "netStat.ySpan is calculated wrong."]; IF netStat.trackLength < 0 THEN netStat.trackLength _ 0; IF netStat.ftHeight < 0 THEN netStat.trackLength _ 0; IF nets[k] # 0 THEN { fracL[k] _ fracL[k] + Real.Float[netStat.trackLength] / nets[k]; fracH[k] _ fracH[k] + Real.Float[netStat.ftHeight] / nets[k]; spanX[k] _ spanX[k] + Real.Float[(netStat.xSpan.max - netStat.xSpan.min)] / nets[k]; spanY[k] _ spanY[k] + Real.Float[(netStat.ySpan.max - netStat.ySpan.min + 1)] / nets[k]; }; }; Var: EachNetStatAction ~ { k: NAT _ netStat.numPins; IF k > maxPinPerNet THEN k _ maxPinPerNet; IF nets[k] # 0 THEN { varL[k] _ varL[k] + (netStat.trackLength - fracL[k]) * (netStat.trackLength - fracL[k]) / nets[k]; varH[k] _ varH[k] + (netStat.ftHeight - fracH[k]) * (netStat.ftHeight - fracH[k]) / nets[k]; varX[k] _ varX[k] + (netStat.xSpan.max - netStat.xSpan.min - spanX[k]) * (netStat.xSpan.max - netStat.xSpan.min - spanX[k]) / nets[k]; varY[k] _ varY[k] + (netStat.ySpan.max - netStat.ySpan.min + 1 - spanY[k]) * (netStat.ySpan.max - netStat.ySpan.min + 1 - spanY[k]) / nets[k]}; }; maxPinPerNet: NAT _ 25; nets: RowN _ NIL; fracL, fracH, varL, varH, sigmaL, sigmaH: RowR _ NIL; spanX, spanY, varX, varY, sigmaX, sigmaY: RowR _ NIL; technologyKey: ATOM = $cmosB; lambda: INT _ CDSimpleRules.GetTechnology[technologyKey].lambda; layoutData: SCPrivate.LayoutData _ NARROW[result.handle.layoutData]; totWidth: INT _ layoutData.totWidth / lambda; nets _ NEW[VecSeqN[maxPinPerNet+1]]; fracL _ NEW[VecSeqR[maxPinPerNet+1]]; fracH _ NEW[VecSeqR[maxPinPerNet+1]]; varL _ NEW[VecSeqR[maxPinPerNet+1]]; varH _ NEW[VecSeqR[maxPinPerNet+1]]; sigmaL _ NEW[VecSeqR[maxPinPerNet+1]]; sigmaH _ NEW[VecSeqR[maxPinPerNet+1]]; spanX _ NEW[VecSeqR[maxPinPerNet+1]]; spanY _ NEW[VecSeqR[maxPinPerNet+1]]; varX _ NEW[VecSeqR[maxPinPerNet+1]]; varY _ NEW[VecSeqR[maxPinPerNet+1]]; sigmaX _ NEW[VecSeqR[maxPinPerNet+1]]; sigmaY _ NEW[VecSeqR[maxPinPerNet+1]]; FOR i: INT IN [0..maxPinPerNet] DO nets[i] _ 0; fracL[i] _ 0; fracH[i] _ 0; varL[i] _ 0; varH[i] _ 0; sigmaL[i] _ 0; sigmaH[i] _ 0; spanX[i] _ 0; spanY[i] _ 0; varX[i] _ 0; varY[i] _ 0; sigmaX[i] _ 0; sigmaY[i] _ 0; ENDLOOP; [] _ EnumerateNetStats[table, NumNets]; [] _ EnumerateNetStats[table, Avg]; [] _ EnumerateNetStats[table, Var]; FOR i: NAT IN [0..maxPinPerNet] DO fracL[i] _ fracL[i] / totWidth; varL[i] _ varL[i] / totWidth / totWidth; sigmaL[i] _ Real.SqRt[varL[i]]; sigmaH[i] _ Real.SqRt[varH[i]]; spanX[i] _ spanX[i] / totWidth; varX[i] _ varX[i] / totWidth / totWidth; sigmaX[i] _ Real.SqRt[varX[i]]; sigmaY[i] _ Real.SqRt[varY[i]]; ENDLOOP; FOR i: NAT IN [0..maxPinPerNet] DO IF nets[i] # 0 THEN { TerminalIO.PutF[format: "\n\t\tnumPins: %g, \tnumNets: %g", v1: IO.int[i], v2: IO.int[nets[i]]]; TerminalIO.PutF[format: "\n\t\t\tfracL: %g, \tfracH: %g", v1: IO.real[fracL[i]], v2: IO.real[fracH[i]]]; TerminalIO.PutF[format: "\n\t\t\tsigmaL: %g, \tsigmaH: %g", v1: IO.real[sigmaL[i]], v2: IO.real[sigmaH[i]]]; TerminalIO.PutF[format: "\n\t\t\tspanX: %g, \tspanY: %g", v1: IO.real[spanX[i]], v2: IO.real[spanY[i]]]; TerminalIO.PutF[format: "\n\t\t\tsigmaX: %g, \tsigmaY: %g", v1: IO.real[sigmaX[i]], v2: IO.real[sigmaY[i]]];}; ENDLOOP; }; ReadStats: PUBLIC PROC [fileName: Rope.ROPE] RETURNS [stats: LIST OF SC.ChannelStats] ~ { }; END. πSCStatsImpl.mesa Copyright Σ 1988 by Xerox Corporation. All rights reserved. Last Edited by: Preas, September 5, 1985 10:39:21 am PDT Massoud Pedram March 23, 1989 10:29:42 am PST To print stats from SC placement and routing; set SCNewRouteImpl.keepStats _ TRUE to gather statistics outer list is of the channels next inner list is of the nets within this channel inner list is of the pins within the net within this channel inner list is of the pins within the net within this channel outer list is of the channels next inner list is of the nets within this channel inner list is of the pins within the net within this channel inner list is of the pins within the net within this channel PROC [key: Key, netStat: NetStat] RETURNS [quit: BOOLEAN _ FALSE] PROC [key: Key, netStat: NetStat] RETURNS [quit: BOOLEAN _ FALSE] PROC [key: Key, netStat: NetStat] RETURNS [quit: BOOLEAN _ FALSE] PROC [key: Key, netStat: NetStat] RETURNS [quit: BOOLEAN _ FALSE] read as stats file and make a data structure Κ ˜codešœ™Kšœ<™˜>Kšœ3˜3Kšœ-˜-Kšœ:˜:šœ œœ˜,Kšœ2˜2Kšœ/œ˜@Kšœ3œ9˜nKšœ˜—šœ œœ˜)Kšœ+˜+Kšœ+œ˜;Kšœ4œ%˜[Kšœ2œ˜IKšœ˜—šœ@˜@K˜K˜——šžœœœ œ ˜5Kšœœœœ˜.Kšœ2˜2šœ œ˜Jšœ™Kšœ œœœ!˜5Kšœ/œ˜Lšœ œ˜Jšœ2™2Kšœ œœœ$˜8Kšœ œœœ#˜6KšœKœ œ$œ!˜Άšœ œ˜Jšœ<™Kšœœ˜>Kšœ4˜4Kšœ˜šœ œœ˜Kšœ œ‚˜—šœ˜Kšœœ˜:Kšœœ˜:Kšœœ˜:Kšœœ˜:Kšœ-˜-Kšœ9˜9—Kšœœ˜8Kšœ0˜0Kšœ˜Kšœ˜—Kšœ˜Kšœ˜—Kšœ/˜/Kšœ8˜8K˜K˜—šžœœœ˜3K˜šž œ˜"Kšœœœœ™AKšœ=œœ˜qKš œHœœœœ˜ΐKšœJœœ˜†—šœ,˜,K˜——šžœœœ œ˜GK˜šžœ˜Kšœœœœ™AKšœœ˜Kšœœ˜*Kšœ˜Kšœ˜K˜—šžœ˜Kšœœœœ™AKšœœ˜Kšœœ˜*Kšœ'œœ<˜lKšœ'œœ<˜lKšœœ˜8Kšœœ˜5šœ œ˜Kšœ@˜@Kšœ=˜=KšœT˜TKšœX˜XKšœ˜—Kšœ˜—K˜šžœ˜Kšœœœœ™AKšœœ˜Kšœœ˜*šœ œ˜Kšœb˜bKšœ\˜\Kšœ†˜†Kšœ˜—Kšœ˜—K˜Kšœœ˜Kšœ œ˜Kšœ1œ˜5Kšœ1œ˜5Kšœœ ˜Kšœœ5˜@Kšœ#œ˜DKšœ œ ˜-Kšœœ˜$Kšœœ˜%Kšœœ˜%Kšœœ˜$Kšœœ˜$Kšœ œ˜&Kšœ œ˜&Kšœœ˜%Kšœœ˜%Kšœœ˜$Kšœœ˜$Kšœ œ˜&Kšœ œ˜&šœœœ˜"Jšœ ˜ JšœS˜SJšœS˜SJšœ˜—Jšœ'˜'Kšœ#˜#Kšœ#˜#šœœœ˜#Kšœ ˜ Kšœ(˜(Kšœ˜Kšœ˜Kšœ ˜ Kšœ(˜(Kšœ˜Kšœ˜Kšœ˜—šœœœ˜#šœ œ˜KšœAœ œ˜aKšœ>œœ˜hKšœ@œœ˜lKšœ>œœ˜hKšœ@œœ˜n—Kšœ˜—K˜˜K˜——šž œœœœœ œœœ˜YKšœ,™,K˜K˜—Kšœ˜—…—'Ζ6Θ