DIRECTORY Basics, CD, Convert, List, Rope, RoutePrivate, RTBasic, SC, SCNetUtil, SCPrivate, SCRoutePinsUtil; SCRoutePinsUtilImpl: CEDAR PROGRAM IMPORTS Convert, List, Rope, 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[min, max, depth: SC.Number, netPin: SCPrivate.PinNet, side: SC.Side, alwaysUse: BOOLEAN] = { net: SCPrivate.Net _ netPin.net; netDat: SCRoutePinsUtil.NetDat _ NARROW[net.netDat]; chanPin: SCRoutePinsUtil.ChannelPin _ NEW[SCRoutePinsUtil.ChannelPinRec _ [min: min, max: max, depth: depth, netPin: netPin, 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] = { 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[SCPrivate.ExitRec _ [net: exit.net, pos: exit.pos, pinInChan: NIL, layer: exit.layer]]}; 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: SCPrivate.Exit _ netDat.exits[side]; IF exit # NIL THEN { pos: INT _ IF side = left THEN lgRows.horzRowOrg ELSE lgRows.horzRowOrg + lgRows.maxRowWidth; netDat.bounds1 _ MIN[netDat.bounds1, pos]; netDat.bounds2 _ MAX[netDat.bounds2, pos]; IF exitProc # NIL THEN exitProc[exit, side]; numPins _ numPins + 1}}; DoPin: CPProc = { IF netDat.pinCount > 1 OR cP.alwaysUse THEN { netDat.bounds1 _ MIN[netDat.bounds1, cP.min]; netDat.bounds2 _ MAX[netDat.bounds2, cP.max]; IF pinProc # NIL THEN pinProc[cP.min, cP.max, cP.depth, cP.netPin, cP.side]; 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 _ RTBasic.Span[fullRange, [cP.min, cP.max]]}; DoMinPins: CPProc = { trialRange: RTBasic.Range _ RTBasic.Span[fullRange, [cP.min, cP.max]]; trialLength: SC.Number _trialRange.r - trialRange.l; IF trialLength < maxLength THEN {maxLength _ trialLength; minPin _ cP}}; maxLength: SC.Number _ last; minPin: SCRoutePinsUtil.ChannelPin _ NIL; fullRange: RTBasic.Range _ [last, -last]; IF netDat.chanPins[fullSide] # NIL THEN EnumChanPins[netDat, netDat.chanPins[fullSide], DoRange]; IF netDat.exits[left] # NIL THEN { min: SC.Number _ lgRows.horzRowOrg; fullRange _ RTBasic.Span[fullRange, [min, min]]}; IF netDat.exits[right] # NIL THEN { max: SC.Number _ lgRows.horzRowOrg + lgRows.maxRowWidth; fullRange _ RTBasic.Span[fullRange, [max, max]]}; 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: RTBasic.Range _ RTBasic.Span[[lastPin[top].min, lastPin[top].max], [lastPin[bottom].min, lastPin[bottom].max]]; IF netDat.exits[left] # NIL THEN { min: SC.Number _ lgRows.horzRowOrg; trialRange _ RTBasic.Span[trialRange, [min, min]]}; IF netDat.exits[right] # NIL THEN { max: SC.Number _ lgRows.horzRowOrg + lgRows.maxRowWidth; trialRange _ RTBasic.Span[trialRange, [max, max]]}; 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].min; p2: SC.Number _ NARROW[ref2, SCRoutePinsUtil.ChannelPin].min; 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 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 PROC [netDat: SCRoutePinsUtil.NetDat, cP: SCRoutePinsUtil.ChannelPin] PROC [netDat: SCRoutePinsUtil.NetDat, cP: SCRoutePinsUtil.ChannelPin] compute span of pins that must be connected check for unconnected exits Κ ˜codešœ™Kšœ Οmœ1™—K™Kšœ5™5š  œžœž œ2˜MK˜Kšœ˜Kšœ!žœ ˜4šžœ žœžœ˜Kšœ žœžœ˜0Kšœ˜—Kšžœžœžœžœ,˜OKšœ&˜&Kšœq˜qK˜—š  œžœž œ žœ˜ΉK˜š œž œ<˜MK˜Kšœ*˜*šžœžœžœ˜Kš œžœžœ žœžœ(˜]Kšœžœ˜*Kšœžœ˜*Kšžœ žœžœ˜,Kšœ˜—K˜—š œ ˜KšœE™EK˜šžœžœžœ˜-Kšœžœ˜-Kšœžœ˜-Kšžœ žœžœ7˜LKšœ˜—K˜—š  œž œ<˜PK˜Kšœ4˜4K˜—š  œžœJ˜YK˜Kš œC˜JK˜š  œ ˜KšœE™EK˜KšœF˜FKšœ žœ%˜4Kšžœžœ)˜H—K˜Kšœ žœ˜Kšœ%žœ˜)K˜Kšœ+™+Kšœ)˜)šžœžœž˜'Kšœ9˜9—šžœžœž˜"Kšœžœ˜#Kšœ1˜1—šžœžœž˜#Kšœžœ1˜8Kšœ1˜1K˜—šžœžœžœžœ˜IKšœ;˜;Kšžœ žœžœ˜,—K˜—š œžœ%˜3K˜š  œ ˜K˜K˜šžœ'žœžœ˜3Kšœ žœ˜Kšœ{˜{šžœžœž˜"Kšœžœ˜#Kšœ3˜3—šžœžœž˜#Kšœžœ1˜8Kšœ3˜3—Kšœ*˜*šžœžœ˜!Kšœ˜Kšœ˜Kšœ#˜#—K˜——Kšœ žœ˜Kš œ žœžœžœžœ˜KKš œžœžœžœžœ˜JKšœl˜lKšœ:˜:Kšœ%˜%Kšœ/˜/Kšžœžœžœ˜5Kšžœžœžœ˜;š žœžœžœžœž˜WKšœ˜—š žœžœžœžœž˜ZKšœ˜——K˜š œ˜"Kšœ!žœ ˜4K˜ šžœ žœžœ˜šžœžœž˜šœ Ÿ˜Kšœ-˜-Kšœ3˜3—šœ%žœ(˜PKšœ-˜-Kšœ3˜3—šœ%žœ'˜OKšœ-˜-Kšœ8˜8—šœ$žœ(˜OKšœ-˜-Kšœ;˜;—šœ$žœ'˜NKšœ@˜@—šœ(Ÿ˜=KšœF˜F—šœ(Ÿ˜=KšœI˜I—šžœ˜ Kšœ™š žœžœžœžœž˜=Kšžœ`˜b———Kšžœ žœžœ˜#Kš žœ žœ žœ"žœžœs˜»K˜——Kšœ#žœ˜=Kšœ-˜-Jšœ žœ˜ Kšœ/˜/—K˜K˜KšœžœžœB˜Uš  œžœ\˜nK˜šžœ;žœ žœž˜RKšœ-˜-Kšœ˜Kšžœ˜ ——K˜š  œžœ7žœ1˜K˜š  œ˜ Kšœžœ žœ'˜=Kšœžœ žœ'˜=šžœžœ žœ˜-Kšžœžœ žœ˜,Kšžœ˜!K˜——Kšœžœ1˜LKšœžœ4˜RKšœžœA˜YKšœ-˜-—š  œžœ(žœ žœ˜VKšœžœ˜ šžœžœž˜Kšœžœ˜K˜Kšžœ˜—Kšžœ˜ KšœŸ˜K˜—š œžœ žœžœ)˜XKšœžœ˜ šžœžœž˜Kšœ#žœ ˜6Kšœžœ ˜K˜Kšžœ˜—Kšžœ˜ KšœŸ˜K˜—Kšžœ˜——…—!ή.ο