DIRECTORY Basics, CD, Convert, List, Rope, RouteChannel, RoutePrivate, RTBasic, SC, SCNetUtil, SCPrivate, SCRoutePinsUtil; SCRoutePinsUtilImpl: CEDAR PROGRAM IMPORTS Convert, List, Rope, 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, alwaysUse: BOOLEAN] = { 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, alwaysUse: alwaysUse]]; 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]; numPins _ numPins + 1}}; DoPin: CPProc = { -- PROC [netDat: SCRoutePinsUtil.NetDat, cP: SCRoutePinsUtil.ChannelPin] IF netDat.pinCount > 1 OR cP.alwaysUse THEN { 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]; numPins _ numPins + 1}}; 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 = { -- PROC [netDat: SCRoutePinsUtil.NetDat, cP: SCRoutePinsUtil.ChannelPin] 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}}; maxLength: SC.Number _ last; minPin: SCRoutePinsUtil.ChannelPin _ NIL; fullRange: RoutePrivate.Range _ [last, -last]; IF netDat.chanPins[fullSide] # NIL THEN EnumChanPins[netDat, netDat.chanPins[fullSide], DoRange]; IF netDat.exits[left] # NIL THEN fullRange _ RouteChannel.Span[fullRange, [0, 0]]; IF netDat.exits[right] # NIL THEN fullRange _ RouteChannel.Span[fullRange, [lgRows.maxRowWidth, lgRows.maxRowWidth]]; IF (fullRange.l <= fullRange.r) AND netDat.chanPins[minSide] # NIL THEN { 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]; numPins _ 0; IF netDat # NIL 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.Signal[callingError, "Unconnected public wire; make sure all publics hanve more than one pin"]; IF netProc # NIL THEN netProc[net]; IF numPins = 1 AND chan # 1 AND chan # layoutData.rowChans.count THEN SC.Signal[callingError, Rope.Cat["Too few pins for wire: ", net.name, " on channel: ", Convert.RopeFromInt[chan]]] }}; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; numPins: INT; [] _ 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. ffile SCRoutePinsUtilImpl.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Bryan Preas, December 31, 1986 11:43:34 am PST 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 compute span of pins that must be connected check for unconnected exits Κ R˜šœ™Icodešœ Οmœ1™—J™Jšœ5™5š  œžœž œ5žœ ˜^J˜Jšœ˜Jšœ!žœ ˜4šžœ žœžœ˜Jšœ žœžœ˜0Jšœ˜—Jšžœžœžœžœ,˜OJšœ&˜&Jšœžœ9˜QJ˜—š  œžœž œ žœ˜ΉJ˜š œž œ<˜MJ˜Jšœ3˜3šžœžœžœ˜Kš œžœžœ žœžœ˜9Jšœžœ˜*Jšœžœ˜*Jšžœ žœžœ@˜VJšœ˜—J˜—š œ ˜JšœžœA˜HJ˜šžœžœ žœ˜-Jšœžœ ˜4Jšœžœ ˜4Jšžœ žœžœ3˜HJšœ˜—J˜—š  œž œ<˜PJ˜Jšœ4˜4J˜—š  œžœJ˜YJ˜Jš œV˜]J˜š  œ ˜JšœžœA˜HJ˜Jšœ^˜^Jšœ žœ%˜4šžœžœ˜!Jšœ˜Jšœ˜——J˜Jšœ žœ˜Jšœ%žœ˜)J˜Kšœ+™+Jšœ.˜.šžœžœž˜'Kšœ9˜9—šžœžœž˜ Jšœ1˜1—šžœžœž˜!JšœS˜SJ˜—šžœžœžœžœ˜IJšœ;˜;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šœ!žœ ˜4J˜ šžœ žœžœ˜šžœžœž˜šœ Ÿ˜Kšœ-˜-Jšœ3˜3—šœ%žœ(˜PKšœ-˜-Jšœ3˜3—šœ%žœ'˜OKšœ-˜-Kšœ8˜8—šœ$žœ(˜OKšœ-˜-Kšœ;˜;—šœ$žœ'˜NKšœ@˜@—šœ(Ÿ˜=KšœF˜F—šœ(Ÿ˜=KšœI˜I—šžœ˜ Kšœ™š žœžœžœžœž˜=Kšžœ`˜b———Kšžœ žœžœ˜#Kš žœ žœ žœ"žœžœp˜ΈKšœ˜J˜——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šžœ˜——…—"’/Z