DIRECTORY CDBasics, CoreRouteFlat, CoreRouteFlatProcs, Imager USING [Context, PathProc, SetGray, SetXY, ShowRope, MaskBox, MaskStroke], IO, IP, IPConstants, IPBasicOps, IPToolBox, IPChipRose, IPCTG, IPNetTab, Rope, Set USING [Handle, New, Put, Enumerate], SymTab; IPNetTabImpl: CEDAR PROGRAM IMPORTS CDBasics, CoreRouteFlatProcs, IO, Imager, IP, IPChipRose, IPBasicOps, IPToolBox, IPCTG, IPNetTab, Rope, Set, SymTab EXPORTS IPNetTab = BEGIN OPEN TB: IPToolBox, CR: IPChipRose, BO: IPBasicOps, IPNetTab; SimpleChNetFactorEstimator: PUBLIC ChNetFactorEstimator ={horFactor _ (netBRect.x2 - netBRect.x1); verFactor _ (netBRect.y2 - netBRect.y1)}; --SimpleChNetFactorEstimator Create: PUBLIC PROC[chipRose: CR.Ref] RETURNS [Ref] = { eachNet: CR.EachNetAction ={ [] _ nets.Store[net, NEW[NetRep _ [name: net]]]; }; --eachNet nets: SymTab.Ref _ SymTab.Create[]; chipRose.Nets[eachNet]; RETURN [NEW[Rep _ [nets]]]; }; --Create CreateFromStructure: PUBLIC PROC[structure: CoreRouteFlat.Structure] RETURNS [Ref] = { EachNet: CoreRouteFlatProcs.EachNetAction ={ -- PROC [net: CoreRouteFlat.Net] RETURNS [quit: BOOLEAN _ FALSE]; [] _ SymTab.Store[nets, net.name, NEW[NetRep _ [name: net.name]]]; }; --eachNet nets: SymTab.Ref _ SymTab.Create[]; [] _ CoreRouteFlatProcs.EnumerateNets[structure, EachNet]; RETURN [NEW[Rep _ [nets]]]; }; --Create FetchNet: PUBLIC PROC[netTab: Ref, name: Rope.ROPE, raiseError: BOOL] RETURNS [Net] ={ found: BOOL; val: REF; [found, val] _ netTab.nets.Fetch[name]; IF found THEN RETURN [NARROW[val]]; IF raiseError THEN ERROR IP.Error[missingRegistration, Rope.Cat[name, " is not a net name"]] ELSE RETURN [NIL]; }; --FetchNet Size: PUBLIC PROC[netTab: Ref] RETURNS [INT] ={ RETURN [SymTab.GetSize[netTab.nets]]}; --Size Nets: PUBLIC PROC[netTab: Ref, action: EachNetAction] ={ p: SymTab.EachPairAction = {RETURN[action[NARROW[val]]]};--p [] _ netTab.nets.Pairs[p]; }; --Nets TotalNetLength: PUBLIC PROC[netTab: Ref, netFactorProc: ChNetFactorEstimator] RETURNS [totalLength: INT _ 0] ={ eachNetProc: EachNetAction ={ totalLength _ totalLength + NetLength[net, netFactorProc]}; --eachNetProc Nets[netTab, eachNetProc]; }; --TotalNetLength CountNets: PUBLIC PROC[netTab: Ref] RETURNS [active, nonActive: INT _ 0] ={ eachNetProc: EachNetAction ={ IF NetActive[net] THEN active _ active.SUCC ELSE nonActive _ nonActive.SUCC; }; --eachNetProc Nets[netTab, eachNetProc]; }; --CountNets CountAllPins: PUBLIC PROC[netTab: Ref, activeNetsOnly: BOOL _ TRUE] RETURNS [active, nonActive: INT _ 0] ={ eachNetProc: EachNetAction ={ IF activeNetsOnly AND ~ NetActive[net] THEN NULL ELSE { aIncr, nIncr: INT; [aIncr, nIncr] _ CountPins[net]; active _ active + aIncr; nonActive _ nonActive + nIncr;};}; --eachNetProc Nets[netTab, eachNetProc]; }; --CountAllPins CheckSelf: PUBLIC PROC[netTab: Ref] ={NULL}; --CheckSelf DescribeSelf: PUBLIC PROC[netTab: Ref, stream: IO.STREAM, debug: BOOL] ={ pNet: EachNetAction ={ stream.PutF["%g: \t{", IO.rope[net.name]]; IF debug THEN { stream.PutF["pinNets: {"]; FOR l: PinNets _ net.pinNets, l.rest UNTIL l = NIL DO stream.PutF[" %g@%g", IO.rope[l.first.name], IO.rope[l.first.owner.name]] ENDLOOP; stream.PutF["}"]; }; --endIF stream.PutF["}\n"]; };--pNet stream.PutF["\nBeginNetTab\n"]; stream.PutF["\n%g \t--Number of Nets\n", IO.int[netTab.nets.GetSize[]]]; Nets[netTab, pNet]; stream.PutF["EndNetTab\n"]; }; --DescribeSelf ReconstructSelf: PUBLIC PROC[stream: IO.STREAM] RETURNS [Ref] ={ nets: SymTab.Ref _ SymTab.Create[]; THROUGH [0..stream.GetInt) DO name: Rope.ROPE; net: REF IP.NetRep; [name, net] _ GetNet[stream]; [] _ nets.Store[name, net]; ENDLOOP; IF stream.GetAtom[] # $EndNetTab THEN ERROR; RETURN [NEW[Rep _ [nets]]]; }; --ReconstructSelf NetLength: PUBLIC PROC[net: Net, netFactorProc: ChNetFactorEstimator] RETURNS [INT] ={ netBRect: Rect _ GetNetBRect[net]; IF NetActive[net] AND netFactorProc # NIL THEN { activePins, nonActivePins: INT; horFactor, verFactor: REAL; horChSum, verChSum: INT _ 0; chSet: Set.Handle _ Set.New[]; eachChAction: PROC[e: REF ANY] RETURNS [stop: BOOL _ FALSE] ={ ch: IPCTG.Channel _ NARROW[e]; chInt: INT _ ChAndRectOverlap[ch, netBRect]; chLength: INT _ IPCTG.Length[ch]; chStatIncr: REAL _ IF ch.type = hor THEN (horFactor * chInt * chInt) /(horChSum * chLength) ELSE (verFactor * chInt * chInt) /(verChSum * chLength); ch.statistics.netFactor _ ch.statistics.netFactor + chStatIncr; }; --eachChAction [activePins, nonActivePins] _ CountPins[net]; [horFactor, verFactor] _ netFactorProc[netBRect, activePins, nonActivePins]; FOR l: PinNets _ net.pinNets, l.rest UNTIL l = NIL DO comp: REF IP.ComponentRep _ l.first.owner; -- get the component coChAction: PROC[ch: IPCTG.Channel] RETURNS [quit: BOOL _ FALSE] ={ overLap: INT _ ChAndRectOverlap[ch, netBRect]; IF overLap > 0 THEN { SELECT ch.type FROM hor => horChSum _ horChSum + overLap; ver => verChSum _ verChSum + overLap; ENDCASE => ERROR; [] _ Set.Put[chSet, ch]}; }; --eachCoChAction IPToolBox.CoChannels[comp, coChAction]; ENDLOOP; [] _ Set.Enumerate[chSet, eachChAction]; }; --endIF RETURN [(netBRect.x2- netBRect.x1) + (netBRect.y2 - netBRect.y1)]; --This is the semi-perimeter of the net's bounding box }; --NetLength CountPins: PUBLIC PROC[net: Net] RETURNS [active, nonActive: INT _ 0] ={ FOR l: PinNets _ net.pinNets, l.rest UNTIL l = NIL DO FOR phyPins: PhysicalPins _ l.first.physicalPins, phyPins.rest UNTIL phyPins = NIL DO IF phyPins.first.active THEN active _ active.SUCC ELSE nonActive _ nonActive.SUCC; ENDLOOP; ENDLOOP; }; --CountPins PaintNet: PUBLIC PROC [net: Net, context: Imager.Context, xOffset, yOffset, scaleFactor: REAL, stipple: CARDINAL, showNetName: BOOL] ={ xMin, yMin, xMax, yMax: REAL; [[xMin, yMin, xMax, yMax]] _ GetNetBRect[net]; xMin _ xOffset + (xMin * scaleFactor); yMin _ yOffset + (yMin * scaleFactor); xMax _ xOffset + (xMax * scaleFactor); yMax _ yOffset + (yMax * scaleFactor); IF stipple = IPConstants.White THEN { path: Imager.PathProc ~ { moveTo[[xMin, yMin]]; lineTo[[xMax, yMin]]; lineTo[[xMax, yMax]]; lineTo[[xMin, yMax]]; lineTo[[xMin, yMin]];}; Imager.MaskStroke[context, path];} ELSE { Imager.SetGray[context, stipple]; Imager.MaskBox[context, [xMin, yMin, xMax, yMax]];}; IF showNetName THEN { Imager.SetXY[context, [(xMin + xMax)/2.0, (yMin + yMax)/2.0]]; --place at center Imager.ShowRope[context, net.name]}; };--PaintNet GetNet: PROC[stream: IO.STREAM] RETURNS [Rope.ROPE, REF IP.NetRep] ={ name: Rope.ROPE _ TB.GetIdRope[stream]; -- First get the name net: REF IP.NetRep _ NEW[IP.NetRep _ [name]]; TB.EnterBlock[stream]; UNTIL TB.ExitBlock[stream] DO token: ATOM _ TB.GetIdAtom[stream]; SELECT token FROM $pinNets => TB.RemoveBlock[stream]; --list of pinNet names, not used ENDCASE => ERROR; ENDLOOP; RETURN[name, net]; }; --GetNet ChAndRectOverlap: PROC[ch: IPCTG.Channel, rect: Rect] RETURNS [INT]= { chCoord: INT _ IPCTG.GetCoord[ch]; chNegBnd, chPosBnd, rectNegBnd, rectPosBnd: INT; [chNegBnd, chPosBnd] _ IPCTG.Bounds[ch]; SELECT ch.type FROM hor => IF chCoord < rect.y1 OR rect.y2 < chCoord THEN RETURN [0] ELSE {rectNegBnd _ rect.x1; rectPosBnd _ rect.x2}; ver => IF chCoord < rect.x1 OR rect.x2 < chCoord THEN RETURN [0] ELSE {rectNegBnd _ rect.y1; rectPosBnd _ rect.y2}; ENDCASE => ERROR; IF chNegBnd > rectPosBnd OR chPosBnd < rectNegBnd THEN RETURN [0] ELSE RETURN [1 + MIN[rectPosBnd, chPosBnd] - MAX[chNegBnd, rectNegBnd]] }; --ChAndRectOverlap GetNetBRect: PROC [net: Net] RETURNS [bRect: Rect _ [0, 0, 0, 0]] = { pinNets: PinNets _ net.pinNets; IF pinNets = NIL THEN RETURN; --No pinNets IF pinNets.rest = NIL THEN { -- ONE pinNet but need at least two FOR l: PhysicalPins _ pinNets.first.physicalPins, l.rest UNTIL l = NIL DO l.first.active _ FALSE ENDLOOP; RETURN}; BEGIN ctrMass: IP.IntVector _ FindPhyPinsCM[pinNets]; bRect _ FindInitialNetBRect[pinNets, ctrMass]; FOR l: PinNets _ pinNets, l.rest UNTIL l = NIL DO bRect _ NuBRectNActivatePin[l.first, bRect]; ENDLOOP; END; }; --GetNetBRect FindPhyPinsCM: PROC[pinNets: PinNets] RETURNS [IP.IntVector] ={ totalMass: IP.IntVector _ [0, 0]; totalPhyPins: NAT _ 0; WHILE pinNets # NIL DO incrMass: IP.IntVector _ [0, 0]; incrPhyPins: NAT _ 0; phyPinsOrigin: IP.IntVector _ IPToolBox.GetCoOrigin[pinNets.first.owner]; FOR l: PhysicalPins _ pinNets.first.physicalPins, l.rest UNTIL l = NIL DO incrPhyPins _ incrPhyPins.SUCC; incrMass _ CDBasics.AddPoints[incrMass, l.first.coord]; ENDLOOP; totalMass _ CDBasics.AddPoints[totalMass, incrMass]; totalMass _ CDBasics.AddPoints[totalMass, BO.IntVectorScale[phyPinsOrigin, incrPhyPins]]; totalPhyPins _ totalPhyPins + incrPhyPins; pinNets _ pinNets.rest ENDLOOP; RETURN [BO.IntVectorDivide[totalMass, totalPhyPins]]; }; --FindPhyPinsCM FindInitialNetBRect: PROC[pinNets: PinNets, target: IP.IntVector] RETURNS [Rect] ={ bestPosition: IP.IntVector _ [0, 0]; bestDist: INT _ LAST[INT]; WHILE pinNets # NIL DO coOrigin: IP.IntVector _ IPToolBox.GetCoOrigin[pinNets.first.owner]; nTarget: IP.IntVector _ CDBasics.SubPoints[target, coOrigin]; FOR l: PhysicalPins _ pinNets.first.physicalPins, l.rest UNTIL l = NIL DO newDist: INT _ BO.IntVectorMDistance[nTarget, l.first.coord]; IF newDist < bestDist THEN {bestDist _ newDist; bestPosition _ CDBasics.AddPoints[l.first.coord, coOrigin]}; ENDLOOP; pinNets _ pinNets.rest ENDLOOP; RETURN [Rect[bestPosition.x, bestPosition.y, bestPosition.x, bestPosition.y]] }; --FindInitialNetBRect NuBRectNActivatePin: PROC[pinNet: REF IP.PinNetRep, bRect: Rect] RETURNS [Rect] ={ bestP: REF IP.PhysicalPinRep _ NIL; bestCoord: IP.IntVector; bestDistFromRect: INT _ LAST[INT]; coOrigin: IP.IntVector _ IPToolBox.GetCoOrigin[pinNet.owner]; FOR l: PhysicalPins _ pinNet.physicalPins, l.rest UNTIL l = NIL DO newCoord: IP.IntVector _ CDBasics.AddPoints[l.first.coord, coOrigin]; newDistFromRect: INT _ BO.RectMDistanceToPt[bRect, newCoord]; l.first.active _ FALSE; IF newDistFromRect <= 0 THEN { bestP _ l.first; bestP.active _ TRUE; FOR ll: PhysicalPins _ l.rest, ll.rest UNTIL ll = NIL DO ll.first.active _ FALSE; ENDLOOP; RETURN [bRect]; }; IF newDistFromRect < bestDistFromRect THEN { bestP _ l.first; bestDistFromRect _ newDistFromRect; bestCoord _ newCoord; }; ENDLOOP; IF bestP # NIL THEN { bestP.active _ TRUE; bRect _ BO.RectExtendToPt[bRect, bestCoord]; }; RETURN [bRect]; }; --NuBRectNActivatePin END. 0--File: IPNetTabImpl.mesa Last Edited by: CSChow, February 2, 1985 2:15:11 am PST Preas, August 26, 1986 6:57:48 pm PDT changed definition of ChAndRectOverlap November 30, 1987 2:42:26 pm PST --(1) Print net name --(2) Print pinNet: NOT used, for debugging --Print out @ -- netFactorProc # NIL => assign channel.statistics.netFactor (for all relevant channel) --(a) Calculate horFactor and verFactor for net --(b) Find relevant channel and calculate horChSum and verChSum --(c) Assign ch.statistics.netFactor for each channel in chSet --###Private Types & Procedures####-- --I used format to impl GetNet to make it more general/extensible -- Related to computing channel's netFactor --Related to computing bounding of net and deciding pin active/nonActive --Have two pinNets can do something --The algorithm is: -- (1) Find center of mass (ctrMass) of all physical pins --(2) Use ctrMass to find the closest physical pin's coord and use that as -- the starting Net Bounding Rect.(set to xMin, yMin, xMax yMax) --(3) With the starting Bounding Rect chose a physicalPin representative -- from each pinNet (and set that active.) This physical Pin is chosen -- so that it will increase the Bounding Rect minimally (increase is 0 if it lies -- inside Rect.) The pin is inside the rectangle, so if it is the first, then it is the best Set the "best" pin to active Set all of the other pins to be NOT active This pin is outside the rectangle, and better than any we have seen before A non-empty pin list Set the "best" pin to active Κp˜J™™7Icode™%KšœΟnœ!™G—J™J™šΟk ˜ K˜ K˜K˜KšœžœC˜PKšžœ˜Kšžœ˜Kšœ ˜ K˜ Kšœ ˜ Kšœ ˜ Kšžœ˜Kšœ ˜ K˜Kšœžœ˜(Kšœ˜—K˜šœžœžœ˜Kšžœžœ žœ%žœ˜{Kš žœ žœžœžœ žœžœ˜VK˜K˜KšœžœkΟc˜©K˜š œžœžœ žœžœ ˜7šœ žœ˜Kšœžœ˜0KšœŸ ˜ —K˜Kšœ#˜#Kšœ˜Kšžœžœ˜KšœŸ˜ —K˜šœžœžœ%žœ ˜VK˜šœ%˜,Kš œžœžœžœžœ˜AKšœ"žœ˜BKšœŸ ˜ —K˜Kšœ#˜#Kšœ:˜:Kšžœžœ˜KšœŸ˜ K˜—š œžœžœžœ žœžœ ˜VKšœžœ˜ Kšœžœ˜ Kšœ'˜'Kšžœžœžœžœ˜#šžœ ž˜Kšž œžœA˜NKšžœžœžœ˜—KšœŸ ˜ —K˜š œžœžœžœžœ˜/Kšžœ!Ÿ˜-—K˜šœžœžœ'˜8Kšœžœžœ Ÿ˜Kšœžœ žœ˜Kšœžœ"˜,Kšœ žœžœ ˜!šœ žœžœ˜$Kšžœ3˜7Kšžœ4˜8—Kšœ?˜?KšœŸ˜—K™Kšœ/™/Kšœ-˜-KšœL˜LK˜Kšœ?™?šžœ"žœžœž˜5KšœžœžœŸ˜?š œ žœžœ žœžœžœ˜CKšœ žœ"˜.šžœ žœ˜šžœ ž˜Kšœ%˜%Kšœ%˜%Kšžœžœ˜—Kšœ˜—KšœŸ˜—Kšœ'˜'Kšž˜—K˜KšŸ?™?Kšœ(˜(KšœŸ˜ —K˜Kšžœ=Ÿ6˜yKšœŸ ˜—K˜š  œžœžœ žœžœ˜Hšžœ"žœžœž˜5šžœ<žœ žœž˜Ušžœ˜Kšžœžœ˜Kšžœžœ˜ —Kšžœ˜—Kšžœ˜—KšœŸ ˜—K˜š œžœžœDžœ žœžœ˜‡Kšœžœ˜Kšœ.˜.Kšœ&˜&Kšœ&˜&Kšœ&˜&Kšœ&˜&K˜šžœ˜šžœ˜K˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ"˜"—šžœ˜Kšœ"˜"Kšœ4˜4——šžœ ˜šžœ˜Kšœ?Ÿ˜PKšœ$˜$——K˜KšœŸ ˜ —K˜K™%K˜šœžœ žœžœžœžœžœžœ ˜EKšœ žœžœŸ˜>Kš œžœžœ žœžœ˜.Kšžœ˜šžœžœž˜Kšœžœžœ˜#šžœž˜Kšœœ#™BKšœ žœŸ ˜DKšžœžœ˜—Kšžœ˜—Kšžœ ˜KšœŸ˜ —K˜K˜K™-K˜š œžœžœžœžœ˜FKšœ žœžœ˜"Kšœ,žœ˜0Kšœžœ ˜(šžœ ž˜šœžœžœ˜1Kšžœžœ˜Kšžœ.˜2—šœžœžœ˜1Kšžœžœ˜Kšžœ.˜2—Kšžœžœ˜—šžœžœ˜2Kšžœžœ˜Kšžœžœžœžœ˜G—KšœŸ˜—K˜K™K™Hš œžœ žœ!˜EKšœ˜Kšžœ žœžœžŸ ˜*šžœžœžœŸ#˜@šžœ7žœžœž˜JKšœž˜Kšžœ˜—Kšžœ˜—K™K™#K™K™9K™LK™FK™IK™IK™RK™šž˜Kšœ žœ$˜/Kšœ.˜.šžœžœžœž˜1Kšœ,˜,Kšžœ˜—Kšžœ˜—KšœŸ ˜—K˜K˜š œžœžœžœ˜?Kšœ žœ˜!Kšœžœ˜šžœ žœž˜Kšœ žœ˜ Kšœ žœ˜Kšœžœ8˜Išžœ6žœžœž˜IKšœžœ˜Kšœ7˜7Kšžœ˜—Kšœ4˜4Kšœ*žœ-˜YKšœ*˜*K˜Kšœ˜Kšžœ˜—Kšžœžœ+˜5KšœŸ˜—K˜šœžœžœ žœ ˜SKšœžœ˜$Kšœ žœžœžœ˜šžœ žœž˜Kšœ žœ9˜EKšœ žœ3˜>šžœ6žœžœž˜IKšœ žœžœ,˜=šžœ˜KšžœR˜V—Kšžœ˜—Kšœ˜Kšžœ˜—KšžœG˜MKšœŸ˜—K•StartOfExpansion[]˜š œžœ žœžœžœ ˜RKšœžœžœžœ˜#K˜Kšœžœžœžœ˜"Kšœ žœ1˜=šžœ/žœžœž˜BKšœ žœ9˜EKšœžœžœ$˜=Kšœžœ˜šžœžœ˜KšœK™KKšœ˜šœžœ˜Kšœ™—š žœ$žœžœžœžœžœ˜ZKšœ*™*—Kšžœ ˜K˜—šžœ$žœ˜,KšœJ™JKšœ˜Kšœ#˜#Kšœ˜Kšœ˜—Kšžœ˜—šžœ žœ˜K™šœžœ˜Kšœ™—Kšœžœ"˜,K˜—Kšžœ ˜KšœŸ˜—K˜Kšžœ˜——…—(X<ψ