DIRECTORY Rope, Imager USING [Context, PathProc, SetGray, SetXY, ShowRope, MaskBox, MaskStroke], IO, SymTab, Set USING [Handle, New, Put, Enumerate], CDBasics, IP, IPConstants, IPBasicOps, IPToolBox, IPChipRose, IPCTG, IPNetTab; IPNetTabImpl: CEDAR PROGRAM IMPORTS IO, Imager, SymTab, Rope, Set, CDBasics, IP, IPChipRose, IPBasicOps, IPToolBox, IPCTG, IPNetTab 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] = { nets: SymTab.Ref _ SymTab.Create[]; eachNet: CR.EachNetAction ={ [] _ nets.Store[net, NEW[NetRep _ [name: net]]]; }; --eachNet chipRose.Nets[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 [NAT]= { 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. θ--File: IPNetTabImpl.mesa Last Edited by: CSChow, February 2, 1985 2:15:11 am PST Preas, August 2, 1986 11:15:44 am PDT --(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 Κ δ˜J™™7Icode™%—J™J™šΟk ˜ K˜KšœœC˜PKšœ˜Kšœ˜Kšœœ˜(K˜ Kšœ˜Kšœ ˜ K˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ ˜ —K˜šœœœ˜Kšœœ'œ%œ ˜gKš œ œœœ œœ˜VK˜K˜KšœœkΟc˜©K˜š Οnœœœ œœ ˜7Kšœ#˜#šœ œ˜Kšœœ˜0Kšœž ˜ —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šœ˜——…—&€:L