DIRECTORY Basics, CD, List, RouteChannel, RoutePrivate, RTBasic, SC, SCNetUtil, SCPrivate, SCRoutePinsUtil; SCRoutePinsUtilImpl: CEDAR PROGRAM IMPORTS List, RouteChannel, RTBasic, SC, SCNetUtil EXPORTS SCRoutePinsUtil SHARES SC = BEGIN last: INT _ LAST[INT]; InitGetChanPins: PUBLIC PROCEDURE [handle: SC.Handle] = { InitNet: SCNetUtil.EachNetProc = { net.netDat _ NIL}; [] _ SCNetUtil.EnumerateNets[handle, InitNet]}; TermGetChanPins: PUBLIC PROCEDURE [handle: SC.Handle] = { TermNet: SCNetUtil.EachNetProc = { netDat: SCRoutePinsUtil.NetDat _ NARROW[net.netDat]; IF netDat # NIL THEN { netDat.exits _ ALL[NIL]; netDat.chanPins _ ALL[NIL]; net.netDat _ NIL}}; [] _ SCNetUtil.EnumerateNets[handle, TermNet]}; EnterPin: PUBLIC PROCEDURE[rect: SC.Rect, position: CD.Position, netPin: SCPrivate.PinNet, side: SC.Side, cell: CD.Object] = { net: SCPrivate.Net _ netPin.net; netDat: SCRoutePinsUtil.NetDat _ NARROW[net.netDat]; chanPin: SCRoutePinsUtil.ChannelPin _ NEW[SCRoutePinsUtil.ChannelPinRec _ [rect: rect, position: position, netPin: netPin, cell: cell, side: side]]; IF netDat = NIL THEN { netDat _ NARROW[NEW[SCRoutePinsUtil.NetDatRec]]; net.netDat _ netDat}; netDat.pinCount _ netDat.pinCount + 1; netDat.chanPins[side] _ CONS[chanPin, netDat.chanPins[side]]}; EnterExit: PUBLIC PROCEDURE[exit: SCPrivate.Exit, side: SCPrivate.LRSide, cell: CD.Object] = { net: SCPrivate.Net _ exit.net; netDat: SCRoutePinsUtil.NetDat _ NARROW[net.netDat]; IF netDat = NIL THEN { netDat _ NARROW[NEW[SCRoutePinsUtil.NetDatRec]]; net.netDat _ netDat}; IF netDat.exits[side] # NIL THEN SC.Error[programmingError, "Call maintainer"]; netDat.pinCount _ netDat.pinCount + 1; netDat.exits[side] _ NEW[SCRoutePinsUtil.ExitPinRec _ [cell: cell, exit: exit]]}; EnterNetDat: PUBLIC PROCEDURE [handle: SC.Handle, chan: SCPrivate.ZMaxChanSr, pinProc: SCRoutePinsUtil.PinProc, exitProc: SCRoutePinsUtil.ExitProc, netProc: SCRoutePinsUtil.NetProc] = { DoExit: PROCEDURE[netDat: SCRoutePinsUtil.NetDat, side: SCPrivate.LRSide] = { exit: SCRoutePinsUtil.ExitPin _ netDat.exits[side]; IF exit # NIL THEN { pos: INT _ IF side = left THEN 0 ELSE lgRows.maxRowWidth; netDat.bounds1 _ MIN[netDat.bounds1, pos]; netDat.bounds2 _ MAX[netDat.bounds2, pos]; IF exitProc # NIL THEN exitProc[exit.exit, exit.cell, exit.exit.net.trunkWidth, side]}}; DoPin: CPProc = { netDat.bounds1 _ MIN[netDat.bounds1, cP.position.x]; netDat.bounds2 _ MAX[netDat.bounds2, cP.position.x]; IF pinProc # NIL THEN pinProc[cP.rect, cP.position, cP.netPin, cP.cell]}; DoAllPins: PROCEDURE[netDat: SCRoutePinsUtil.NetDat, side: SCPrivate.TBSide] = { EnumChanPins[netDat, netDat.chanPins[side], DoPin]}; DoFullMin: PROC [netDat: SCRoutePinsUtil.NetDat, fullSide, minSide: SCPrivate.TBSide] ~ { DoRange: CPProc = {fullRange _ RouteChannel.Span[fullRange, [cP.position.x, cP.position.x]]}; DoMinPins: CPProc = { trialRange: RoutePrivate.Range _ RouteChannel.Span[fullRange, [cP.position.x, cP.position.x]]; trialLength: SC.Number _trialRange.r - trialRange.l; IF trialLength < maxLength THEN { maxLength _ trialLength; minPin _ cP}}; fullRange: RoutePrivate.Range _ [last, -last]; maxLength: SC.Number _ last; minPin: SCRoutePinsUtil.ChannelPin _ NIL; IF netDat.chanPins[fullSide] # NIL AND netDat.chanPins[minSide] # NIL THEN { EnumChanPins[netDat, netDat.chanPins[fullSide], DoRange]; IF netDat.exits[left] # NIL THEN fullRange _ RouteChannel.Span[fullRange, [0, 0]]; IF netDat.exits[left] # NIL THEN fullRange _ RouteChannel.Span[fullRange, [lgRows.maxRowWidth, lgRows.maxRowWidth]]; EnumChanPins[netDat, netDat.chanPins[minSide], DoMinPins]}; IF minPin # NIL THEN DoPin[netDat, minPin]}; DoMinMin: PROC [netDat: SCRoutePinsUtil.NetDat] ~ { DoMinPins: CPProc = { rightPin _ cP; lastPin[cP.side] _ cP; IF lastPin[RTBasic.OtherSide[cP.side]] # NIL THEN { trialLength: SC.Number; trialRange: RoutePrivate.Range _ RouteChannel.Span[[lastPin[top].position.x, lastPin[top].position.x], [lastPin[bottom].position.x, lastPin[bottom].position.x]]; IF netDat.exits[left] # NIL THEN trialRange _ RouteChannel.Span[trialRange, [0, 0]]; IF netDat.exits[left] # NIL THEN trialRange _ RouteChannel.Span[trialRange, [lgRows.maxRowWidth, lgRows.maxRowWidth]]; trialLength _ trialRange.r - trialRange.l; IF trialLength < maxLength THEN { maxLength _ trialLength; minPin[top]_ lastPin[top]; minPin[bottom]_ lastPin[bottom]}}}; maxLength: SC.Number _ last; lastPin: ARRAY SCPrivate.TBSide OF SCRoutePinsUtil.ChannelPin _ [NIL, NIL]; minPin: ARRAY SCPrivate.TBSide OF SCRoutePinsUtil.ChannelPin _ [NIL, NIL]; sortedPinList: SCRoutePinsUtil.ChannelPinList _ SortPinLists[netDat.chanPins[top], netDat.chanPins[bottom]]; leftPin: SCRoutePinsUtil.ChannelPin _ sortedPinList.first; rightPin: SCRoutePinsUtil.ChannelPin; EnumChanPins[netDat, sortedPinList, DoMinPins]; IF minPin[top] # NIL THEN DoPin[netDat, minPin[top]]; IF minPin[bottom] # NIL THEN DoPin[netDat, minPin[bottom]]; IF netDat.exits[left] # NIL AND leftPin # minPin[top] AND leftPin # minPin[bottom] THEN DoPin[netDat, leftPin]; IF netDat.exits[right] # NIL AND rightPin # minPin[top] AND rightPin # minPin[bottom] THEN DoPin[netDat, rightPin]}; EachNet: SCNetUtil.EachNetProc = { netDat: SCRoutePinsUtil.NetDat _ NARROW[net.netDat]; IF netDat # NIL THEN { IF netDat.pinCount > 1 OR chan = 1 OR chan = layoutData.rowChans.count THEN { SELECT TRUE FROM chan = 0 => -- this is a side {DoExit[netDat, left]; DoExit[netDat, right]; DoAllPins[netDat, top]; DoAllPins[netDat, bottom]}; net.routeTopology[chan].upper = full AND net.routeTopology[chan].lower = full => {DoExit[netDat, left]; DoExit[netDat, right]; DoAllPins[netDat, top]; DoAllPins[netDat, bottom]}; net.routeTopology[chan].upper = full AND net.routeTopology[chan].lower = min => {DoExit[netDat, left]; DoExit[netDat, right]; DoFullMin[netDat, top, bottom]; DoAllPins[netDat, top]}; net.routeTopology[chan].upper = min AND net.routeTopology[chan].lower = full => {DoExit[netDat, left]; DoExit[netDat, right]; DoFullMin[netDat, bottom, top]; DoAllPins[netDat, bottom]}; net.routeTopology[chan].upper = min AND net.routeTopology[chan].lower = min => {DoExit[netDat, left]; DoExit[netDat, right]; DoMinMin[netDat]}; net.routeTopology[chan].upper = full => -- lower must be none {DoExit[netDat, left]; DoExit[netDat, right]; DoAllPins[netDat, top]}; net.routeTopology[chan].lower = full => -- upper must be none {DoExit[netDat, left]; DoExit[netDat, right]; DoAllPins[netDat, bottom]}; ENDCASE => IF netDat.exits[left] # NIL OR netDat.exits[right] # NIL THEN SC.Error[programmingError, "Unconnected exit; not suppose to happen"]; IF netProc # NIL THEN netProc[net]}}}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; [] _ SCNetUtil.EnumerateNets[handle, EachNet]}; CPProc: TYPE = PROC [netDat: SCRoutePinsUtil.NetDat, cP: SCRoutePinsUtil.ChannelPin]; EnumChanPins: PROC [netDat: SCRoutePinsUtil.NetDat, pList: SCRoutePinsUtil.ChannelPinList, cPProc: CPProc] ~ { FOR rList: SCRoutePinsUtil.ChannelPinList _ pList, rList.rest WHILE rList # NIL DO cP: SCRoutePinsUtil.ChannelPin _ rList.first; cPProc[netDat, cP]; ENDLOOP}; SortPinLists: PROC [topList, bottomList: SCRoutePinsUtil.ChannelPinList] RETURNS [sortedList: SCRoutePinsUtil.ChannelPinList] ~ { PinCompare: List.CompareProc = { p1: SC.Number _ NARROW[ref1, SCRoutePinsUtil.ChannelPin].position.x; p2: SC.Number _ NARROW[ref2, SCRoutePinsUtil.ChannelPin].position.x; RETURN[IF p1 < p2 THEN Basics.Comparison.less ELSE IF p1 = p2 THEN Basics.Comparison.equal ELSE Basics.Comparison.greater]}; topMungedPinList: List.LORA _ List.Sort[ConvertToLORA[topList], PinCompare]; bottomMungedPinList: List.LORA _ List.Sort[ConvertToLORA[bottomList], PinCompare]; sortedPinList: List.LORA _ List.Merge[bottomMungedPinList, topMungedPinList, PinCompare]; sortedList _ConvertFromLORA[sortedPinList]}; ConvertToLORA: PROC [list: SCRoutePinsUtil.ChannelPinList] RETURNS[val: List.LORA] = { val _ NIL; UNTIL list = NIL DO val _ CONS[list.first, val]; list _ list.rest; ENDLOOP; RETURN[val]; }; -- of ConvertToLORA ConvertFromLORA: PROC [list: List.LORA] RETURNS[val: SCRoutePinsUtil.ChannelPinList] = { val _ NIL; UNTIL list = NIL DO this: SCRoutePinsUtil.ChannelPin _ NARROW[list.first]; val _ CONS[this, val]; list _ list.rest; ENDLOOP; RETURN[val]; }; -- of ConvertFromLORA END. Ϊfile ///StdCell23/SCRoutePinsUtilImpl.mesa RoutePins utility routines -- InitGetChanPins - initialize for determining the width of a channel -- TermGetChanPins - terminate determining the width of a channel -- NewWsEntry - get a new wire segment entry and insert pos, return location -- EnterPin - enter a pin on a channel -- EnterExit - enter exit data for a channel -- EnterNetDat - minmium route channels need special processing to include the minimun number of wire segments of minimum length initialize for determining the width of a channel terminate determining the width of a channel enter a net on a channel into data structure enter exit data for a channel into routing data base check for unconnected exits Κθ˜Jšœ*™*J˜Jšœ™JšœΟnœ4™FJšœœ/™AJšœ œ?™LJšœœ™&Jšœ œ ™,šœ œ4™BJšœ=™=—J™šΟk ˜ J˜Jšžœ˜J˜J˜ J˜ J˜Jšžœ˜J˜ J˜ Jšœ˜J˜—šœžœž˜"Jšžœžœ ˜2Jšžœ˜Jšžœžœ˜ J˜Jšž˜Jšœžœžœžœ˜J˜Jšœ2™2šœžœž œ žœ ˜9J˜šœ˜"Jšœ žœ˜—J˜Jšœ/˜/J˜—Jšœ-™-šœžœž œ žœ ˜9J˜šœ˜"Jšœ!žœ ˜4šžœ žœžœ˜Jšœžœžœ˜Jšœžœžœ˜Jšœ žœ˜—J˜—Jšœ/˜/J˜—Jšœ-™-šœžœž œžœžœ+žœ žœ ˜~J˜ Jšœ!žœ ˜4Jšœ&žœk˜”šžœ žœžœ˜Jšœ žœžœ˜0Jšœ˜—Jšœ&˜&Jšœžœ"˜>—J™Jšœ5™5š œžœž œ5žœ ˜^J˜Jšœ˜Jšœ!žœ ˜4šžœ žœžœ˜Jšœ žœžœ˜0Jšœ˜—Jšžœžœžœžœ,˜OJšœ&˜&Jšœžœ9˜QJ˜—š œžœž œ žœ˜ΉJ˜šœž œ<˜MJ˜Jšœ3˜3šžœžœžœ˜Icodeš œžœžœ žœžœ˜9Jšœžœ˜*Jšœžœ˜*Jšžœ žœžœB˜X—J˜—šœ ˜J˜Jšœžœ ˜4Jšœžœ ˜4Jšžœ žœžœ4˜IJ˜—š œž œ<˜PJ˜Jšœ4˜4J˜—š œžœJ˜YJ˜JšœV˜]J˜š œ ˜Jšœ^˜^Jšœ žœ%˜4šžœžœ˜!Jšœ˜Jšœ˜——J˜Jšœ.˜.Jšœ žœ˜Jšœ%žœ˜)J˜š žœžœžœžœžœ˜LJšœ9˜9šžœžœž˜ Jšœ1˜1—šžœžœž˜ JšœS˜S—Jšœ;˜;Kšžœ žœžœ˜,—K˜—šœžœ%˜3J˜š œ ˜J˜J˜šžœ'žœžœ˜3Jšœ žœ˜Jšœ‘˜‘šžœžœž˜ Jšœ3˜3—šžœžœž˜ JšœU˜U—Jšœ*˜*šžœžœ˜!Jšœ˜Jšœ˜Jšœ#˜#—J˜——Jšœ žœ˜Jš œ žœžœžœžœ˜KJš œžœžœžœžœ˜JJšœl˜lJšœ:˜:Jšœ%˜%Jšœ/˜/Kšžœžœžœ˜5Kšžœžœžœ˜;š žœž œžœ žœžœž˜WKšœ˜—š žœž œžœ žœžœž˜ZKšœ˜——J˜šœ˜"Jšœ!žœ ˜4šžœ žœžœ˜šžœžœ žœ"žœ˜Mšžœžœž˜šœ Οc˜Kšœ-˜-Jšœ3˜3—šœ%žœ(˜PKšœ-˜-Jšœ3˜3—šœ%žœ'˜OKšœ-˜-Kšœ8˜8—šœ$žœ(˜OKšœ-˜-Kšœ;˜;—šœ$žœ'˜NKšœ@˜@—šœ(Ÿ˜=KšœF˜F—šœ(Ÿ˜=KšœI˜I—šžœ˜ Kšœ™š žœžœžœžœž˜=KšžœD˜F———Kšžœ žœžœ˜&—J˜——Jšœ#žœ˜=Jšœ-˜-Jšœ/˜/—J˜J˜KšœžœžœB˜Uš œžœ\˜nK˜šžœ;žœ žœž˜RJšœ-˜-Kšœ˜Jšžœ˜ ——J˜š œžœ7žœ1˜K˜š œ˜ Jšœžœ žœ.˜DJšœžœ žœ.˜Dšžœžœ žœ˜-Jšžœžœ žœ˜,Jšžœ˜!J˜——Jšœžœ1˜LJšœžœ4˜RJšœžœA˜YJšœ-˜-—š œžœ(žœ žœ˜VKšœžœ˜ šžœžœž˜Kšœžœ˜K˜Kšžœ˜—Kšžœ˜ KšœŸ˜K˜—šœžœ žœžœ)˜XKšœžœ˜ šžœžœž˜Kšœ#žœ ˜6Kšœžœ ˜K˜Kšžœ˜—Kšžœ˜ KšœŸ˜K˜—Jšžœ˜——…—  ,b