DIRECTORY DABasics, Convert, Rope, RTBasic, SC, SCNetUtil, SCPrivate, SCNewRoutePinsUtil; SCNewRoutePinsUtilImpl: CEDAR PROGRAM IMPORTS Convert, Rope, RTBasic, SC, SCNetUtil EXPORTS SCNewRoutePinsUtil SHARES SC = { InitGetChanPins: PUBLIC PROCEDURE [handle: SC.Handle, rowChan: SCPrivate.RowChan] = { InitNet: SCNetUtil.EachNetProc = {net.netDat _ NIL}; chanDat: SCNewRoutePinsUtil.ChanDat _ NEW[SCNewRoutePinsUtil.ChanDatRec]; chanDat.head _ chanDat.tail _ NEW[SCNewRoutePinsUtil.PinInChanRec _ [min: FIRST[INT], max: FIRST[INT], depth: 0, layer: 0]]; rowChan.chanDat _ chanDat; rowChan.wireLength _ rowChan.chanDensity _ rowChan.chanWidth _ 0; [] _ SCNetUtil.EnumerateNets[handle, InitNet]}; TermGetChanPins: PUBLIC PROCEDURE [handle: SC.Handle, rowChan: SCPrivate.RowChan] = { TermNet: SCNetUtil.EachNetProc = { netDat: SCNewRoutePinsUtil.NetDat _ NARROW[net.netDat]; IF netDat # NIL THEN { chanNetDat: SCNewRoutePinsUtil.ChanNetDat _ netDat[rowChan.chanNum]; IF chanNetDat # NIL THEN chanNetDat.firstPin _ chanNetDat.lastPin _ chanNetDat.leftmost _ chanNetDat.rightmost _ chanNetDat.exits[left] _ chanNetDat.exits[right] _ NIL; net.netDat _ NIL}}; EachPin: SCNewRoutePinsUtil.EachPinProc = { pin.prevPinInChan _ pin.nextPinInNet _ NIL}; EnumPinsInChan[rowChan, EachPin]; [] _ SCNetUtil.EnumerateNets[handle, TermNet]; rowChan.chanDat _ NIL}; EnterPin: PUBLIC PROCEDURE[rowChan: SCPrivate.RowChan, min, max, depth: SC.Number, layer: SC.Layer, net: SCPrivate.Net, side: DABasics.TBSide, alwaysUse: BOOLEAN] RETURNS[pinInChan: SCNewRoutePinsUtil.PinInChan] = { chanDat: SCNewRoutePinsUtil.ChanDat _ NARROW[rowChan.chanDat]; tail: SCNewRoutePinsUtil.PinInChan _ chanDat.tail; chanDat.tail _ tail.nextPinInChan _ pinInChan _ NEW[SCNewRoutePinsUtil.PinInChanRec _ [ layer: layer, net: net, chanNet: NIL, min: min, max: max, depth: depth, pinClass: isPin, chanSide: side, nextPinInChan: NIL, prevPinInChan: tail, pinConn: unconnected, nextPinInNet: NIL, prevPinInNet: NIL, localDensity: 0 , alwaysUse: alwaysUse, chanNum: rowChan.chanNum]]; rowChan.chanDat _ chanDat}; EnterExit: PUBLIC PROCEDURE[rowChan: SCPrivate.RowChan, pos: SC.Number, layer: SC.Layer, net: SCPrivate.Net, side: DABasics.LRSide] RETURNS[pinInChan: SCNewRoutePinsUtil.PinInChan] = { chanDat: SCNewRoutePinsUtil.ChanDat _ NARROW[rowChan.chanDat]; tail: SCNewRoutePinsUtil.PinInChan _ chanDat.tail; chanDat.tail _ tail.nextPinInChan _ pinInChan _ NEW[SCNewRoutePinsUtil.PinInChanRec _ [ layer: layer, net: net, chanNet: NIL, min: pos, max: pos, depth: 0, pinClass: isExit, chanSide: side, nextPinInChan: NIL, prevPinInChan: tail, pinConn: unconnected, nextPinInNet: NIL, prevPinInNet: NIL, localDensity: 0 , alwaysUse: TRUE, chanNum: rowChan.chanNum]]; rowChan.chanDat _ chanDat}; NoChange: PROCEDURE[mpin, pin: SCNewRoutePinsUtil.PinInChan] RETURNS[yes: BOOLEAN _ FALSE] = { IF mpin.nextPinInNet # NIL THEN yes _ (mpin.nextPinInNet.min = pin.min) AND (mpin.nextPinInNet.pinConn #unconnected); IF mpin.prevPinInNet # NIL THEN yes _ yes OR (mpin.prevPinInNet.min = pin.min) AND (mpin.prevPinInNet.pinConn # unconnected) }; MoveAPinInChan: PUBLIC PROCEDURE[rowChan: SCPrivate.RowChan, pin: SCNewRoutePinsUtil.PinInChan, deltaX: SC.Number] RETURNS[scan: BOOLEAN _ FALSE] = { next: SCNewRoutePinsUtil.PinInChan _ pin; prev: SCNewRoutePinsUtil.PinInChan _ pin; origX, currX, dX: SC.Number; origX _ currX _ pin.min; pin.min _ pin.min + deltaX; pin.max _ pin.max + deltaX; IF pin.min = rowChan.chanDensity THEN scan _ TRUE; IF deltaX > 0 THEN { prev _ pin.prevPinInChan; IF (prev # NIL) AND (prev.min = currX) AND (pin.pinConn = left) THEN prev.localDensity _ prev.localDensity - 1; WHILE (pin.nextPinInChan # NIL) AND (pin.nextPinInChan.min <= pin.min) DO next _ pin.nextPinInChan; IF next.localDensity = rowChan.chanDensity THEN scan _ TRUE; dX _ next.min - currX; currX _ next.min; SwapTwoPins[pin, next]; SELECT pin.pinConn FROM left => { IF pin.net = next.net THEN { SELECT next.pinConn FROM interior => { pin.pinConn _ interior; next.pinConn _ left; pin.chanNet.leftmost _ next}; right => { pin.pinConn _ right; next.pinConn _ left; pin.chanNet.leftmost _ next; pin.chanNet.rightmost _ pin}; ENDCASE}; rowChan.wireLength _ rowChan.wireLength - dX}; interior => { IF pin.net = next.net THEN IF next.pinConn = right THEN { next.pinConn _ interior; pin.pinConn _ right; pin.chanNet.rightmost _ pin}}; right => { rowChan.wireLength _ rowChan.wireLength + dX}; ENDCASE; IF pin.net = next.net THEN SwapTwoPinsInNet[pin, next]; ENDLOOP; dX _ pin.min - currX; IF pin.pinConn = right THEN rowChan.wireLength _ rowChan.wireLength + dX; IF pin.pinConn = left THEN rowChan.wireLength _ rowChan.wireLength - dX; next _ pin.nextPinInChan} ELSE IF deltaX < 0 THEN { next _ pin.nextPinInChan; IF (next # NIL) AND (next.min = currX) AND (pin.pinConn = right) THEN next.localDensity _ next.localDensity - 1; WHILE (pin.prevPinInChan # NIL) AND (pin.prevPinInChan.min >= pin.min) DO prev _ pin.prevPinInChan; IF prev.localDensity = rowChan.chanDensity THEN scan _ TRUE; dX _ currX - prev.min; currX _ prev.min; SwapTwoPins[prev, pin]; SELECT pin.pinConn FROM right => { IF pin.net = prev.net THEN { SELECT prev.pinConn FROM interior => { pin.pinConn _ interior; prev.pinConn _ right; pin.chanNet.rightmost _ prev}; left => { pin.pinConn _ left; prev.pinConn _ right; pin.chanNet.leftmost _ pin; pin.chanNet.rightmost _ prev}; ENDCASE}; rowChan.wireLength _ rowChan.wireLength - dX}; interior => { IF pin.net = prev.net THEN IF prev.pinConn = left THEN { prev.pinConn _ interior; pin.pinConn _ left; pin.chanNet.leftmost _ pin}}; left => { rowChan.wireLength _ rowChan.wireLength + dX}; ENDCASE; IF pin.net = prev.net THEN SwapTwoPinsInNet[prev, pin]; ENDLOOP; dX _ currX - pin.min; IF pin.pinConn = left THEN rowChan.wireLength _ rowChan.wireLength + dX; IF pin.pinConn = right THEN rowChan.wireLength _ rowChan.wireLength - dX}}; SortPins: PROCEDURE[chanDat: SCNewRoutePinsUtil.ChanDat] = { stop: BOOLEAN _ FALSE; temp: SCNewRoutePinsUtil.PinInChan; head: SCNewRoutePinsUtil.PinInChan _ chanDat.head; WHILE ~stop DO rList: SCNewRoutePinsUtil.PinInChan _ head; stop _ TRUE; WHILE rList.nextPinInChan # NIL DO temp _ rList.nextPinInChan; IF rList.min > temp.min THEN { stop _ FALSE; SwapTwoPins[rList, temp]}; rList _ temp; ENDLOOP; ENDLOOP}; SwapTwoPins: PROCEDURE[pin1, pin2: SCNewRoutePinsUtil.PinInChan] = { IF pin2.nextPinInChan # NIL THEN pin2.nextPinInChan.prevPinInChan _ pin1; IF pin1.prevPinInChan # NIL THEN pin1.prevPinInChan.nextPinInChan _ pin2; pin1.nextPinInChan _ pin2.nextPinInChan; pin2.prevPinInChan _ pin1.prevPinInChan; pin1.prevPinInChan _ pin2; pin2.nextPinInChan _ pin1}; SwapTwoPinsInNet: PROCEDURE[pin1, pin2: SCNewRoutePinsUtil.PinInChan] = { chanNetDat: SCNewRoutePinsUtil.ChanNetDat _ pin1.chanNet; IF pin2.nextPinInNet # NIL THEN pin2.nextPinInNet.prevPinInNet _ pin1; IF pin1.prevPinInNet # NIL THEN pin1.prevPinInNet.nextPinInNet _ pin2; pin1.nextPinInNet _ pin2.nextPinInNet; pin2.prevPinInNet _ pin1.prevPinInNet; pin1.prevPinInNet _ pin2; pin2.nextPinInNet _ pin1; IF chanNetDat.firstPin = pin1 THEN chanNetDat.firstPin _ pin2; IF chanNetDat.lastPin = pin2 THEN chanNetDat.lastPin _ pin1}; EnumPinsInChan: PUBLIC PROCEDURE[rowChan: SCPrivate.RowChan, doEachPin: SCNewRoutePinsUtil.EachPinProc] = { chanDat: SCNewRoutePinsUtil.ChanDat _ NARROW[rowChan.chanDat]; IF chanDat # NIL THEN { head: SCNewRoutePinsUtil.PinInChan _ chanDat.head; FOR chanPin: SCNewRoutePinsUtil.PinInChan _ head.nextPinInChan, chanPin.nextPinInChan WHILE chanPin # NIL DO doEachPin[rowChan, chanPin]; ENDLOOP}}; EnumAllPinsInNetChan: PUBLIC PROCEDURE[chanNetDat: SCNewRoutePinsUtil.ChanNetDat, doEachNetPin: SCNewRoutePinsUtil.EachNetPinProc] = { IF chanNetDat # NIL THEN { FOR chanPin: SCNewRoutePinsUtil.PinInChan _ chanNetDat.firstPin, chanPin.nextPinInNet WHILE chanPin # NIL DO doEachNetPin[chanNetDat, chanPin]; ENDLOOP}}; EnumPinsInNetChan: PUBLIC PROCEDURE[chanNetDat: SCNewRoutePinsUtil.ChanNetDat, side: DABasics.Side, doEachNetPin: SCNewRoutePinsUtil.EachNetPinProc] = { IF chanNetDat # NIL THEN { FOR chanPin: SCNewRoutePinsUtil.PinInChan _ chanNetDat.firstPin, chanPin.nextPinInNet WHILE chanPin # NIL DO IF chanPin.chanSide = side OR chanPin.pinClass = isExit THEN doEachNetPin[chanNetDat, chanPin]; ENDLOOP}}; CreateNetDat: PUBLIC PROCEDURE[handle: SC.Handle, rowChan: SCPrivate.RowChan] = { DoEachPin: SCNewRoutePinsUtil.EachPinProc = { net: SCPrivate.Net _ pin.net; netDat: SCNewRoutePinsUtil.NetDat _ NARROW[net.netDat]; chanNum: NAT _ rowChan.chanNum; chanNetDat: SCNewRoutePinsUtil.ChanNetDat _ NIL; IF netDat = NIL THEN net.netDat _ netDat _ NARROW[NEW[SCNewRoutePinsUtil.NetDatRec _ ALL[NIL]]]; IF netDat[chanNum] = NIL THEN netDat[chanNum] _ NEW[SCNewRoutePinsUtil.ChanNetDatRec]; chanNetDat _ netDat[chanNum]; IF pin.pinClass = isExit THEN { IF chanNetDat.exits[pin.chanSide] # NIL THEN SC.Error[programmingError, "More than two exits for a net one side of a channel"] ELSE chanNetDat.exits[pin.chanSide] _ pin}; IF chanNetDat.firstPin = NIL THEN { chanNetDat.firstPin _ (chanNetDat.lastPin _ pin); chanNetDat.net _ net} ELSE { pin.prevPinInNet _ chanNetDat.lastPin; chanNetDat.lastPin.nextPinInNet _ pin; chanNetDat.lastPin _ pin}; chanNetDat.pinCount _ chanNetDat.pinCount + 1; pin.chanNet _ chanNetDat}; SortPins[NARROW[rowChan.chanDat]]; EnumPinsInChan[rowChan, DoEachPin]}; GetANetSegInChan: PUBLIC PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan, net: SCPrivate.Net, segProc: SCNewRoutePinsUtil.SegProc, pinProc: SCNewRoutePinsUtil.PinProc, exitProc: SCNewRoutePinsUtil.ExitProc] ~ { DoExit: PROCEDURE[chanNetDat: SCNewRoutePinsUtil.ChanNetDat, side: DABasics.LRSide] = { exit: SCNewRoutePinsUtil.PinInChan _ chanNetDat.exits[side]; IF exit # NIL THEN { IF side = left THEN exit.pinConn _ interior ELSE IF side = right THEN exit.pinConn _ interior; IF exitProc # NIL THEN exitProc[side, exit.layer, exit.net]; numPinsUsed _ numPinsUsed + 1}}; DoPin: SCNewRoutePinsUtil.EachNetPinProc = { IF (chanNetDat.pinCount > 1 OR pin.alwaysUse) AND pin.pinClass = isPin THEN { pin.pinConn _ interior; IF pinProc # NIL THEN pinProc[pin.min, pin.max, pin.depth, pin.chanSide, pin.layer, pin.net]; numPinsUsed _ numPinsUsed + 1}}; DoAllPins: PROCEDURE[chanNetDat: SCNewRoutePinsUtil.ChanNetDat, side: DABasics.TBSide] = { EnumPinsInNetChan[chanNetDat, side, DoPin]}; DoFullMin: PROC [chanNetDat: SCNewRoutePinsUtil.ChanNetDat, fullSide, minSide: DABasics.TBSide] ~ { DoRange: SCNewRoutePinsUtil.EachNetPinProc = {fullRange _ RTBasic.Span[fullRange, [pin.min, pin.max]]}; DoMinPins: SCNewRoutePinsUtil.EachNetPinProc = { IF pin.pinClass = isPin THEN { trialRange: RTBasic.Range _ RTBasic.Span[fullRange, [pin.min, pin.max]]; trialLength: SC.Number _ trialRange.r - trialRange.l; IF trialLength < maxLength THEN {maxLength _ trialLength; minPin _ pin}}}; maxLength: SC.Number _ LAST[INT]; minPin: SCNewRoutePinsUtil.PinInChan _ NIL; fullRange: RTBasic.Range _ [LAST[INT], FIRST[INT]]; EnumPinsInNetChan[chanNetDat, fullSide, DoRange]; IF fullRange.l <= fullRange.r THEN { EnumPinsInNetChan[chanNetDat, minSide, DoMinPins]; IF minPin # NIL THEN DoPin[chanNetDat, minPin]}}; DoMinMin: PROC [chanNetDat: SCNewRoutePinsUtil.ChanNetDat] ~ { DoMinPins: SCNewRoutePinsUtil.EachNetPinProc = { IF pin.pinClass = isPin THEN { IF leftPin = NIL THEN leftPin _ pin; rightPin _ pin; lastPin[pin.chanSide] _ pin; IF lastPin[RTBasic.OtherSide[pin.chanSide]] # NIL THEN { trialLength: SC.Number; trialRange: RTBasic.Range _ RTBasic.Span[[lastPin[top].min, lastPin[top].max], [lastPin[bottom].min, lastPin[bottom].max]]; IF chanNetDat.exits[left] # NIL THEN { min: SC.Number _ lgRows.horzRowOrg; trialRange _ RTBasic.Span[trialRange, [min, min]]}; IF chanNetDat.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[INT]; lastPin: ARRAY DABasics.TBSide OF SCNewRoutePinsUtil.PinInChan _ [NIL, NIL]; minPin: ARRAY DABasics.TBSide OF SCNewRoutePinsUtil.PinInChan _ [NIL, NIL]; leftPin: SCNewRoutePinsUtil.PinInChan _ NIL; rightPin: SCNewRoutePinsUtil.PinInChan _ NIL; didLeftPin: BOOL _ FALSE; EnumAllPinsInNetChan[chanNetDat, DoMinPins]; IF minPin[top] # NIL THEN DoPin[chanNetDat, minPin[top]]; IF minPin[bottom] # NIL THEN DoPin[chanNetDat, minPin[bottom]]; IF chanNetDat.exits[left] # NIL AND leftPin # minPin[top] AND leftPin # minPin[bottom] THEN {DoPin[chanNetDat, leftPin]; didLeftPin _ TRUE}; IF chanNetDat.exits[right] # NIL AND rightPin # minPin[top] AND rightPin # minPin[bottom] AND ~didLeftPin THEN DoPin[chanNetDat, rightPin]}; ClearPin: SCNewRoutePinsUtil.EachNetPinProc = { pin.pinConn _ unconnected}; FixUpAndCheck: SCNewRoutePinsUtil.EachNetPinProc = { pinState _ pin.pinConn _ NextPinState[pinState, pin]; IF pinState = left THEN chanNetDat.leftmost _ pin; IF pinState = interior THEN lastConnectedPin _ pin}; numPinsUsed: INT _ 0; layoutData: SCPrivate.LayoutData _ NARROW[handle.layoutData]; lgRows: SCPrivate.LgRows _ layoutData.lgRows; netDat: SCNewRoutePinsUtil.NetDat _ NARROW[net.netDat]; chan: SCPrivate.ZMaxChanSr _ rowChan.chanNum; chanNetDat: SCNewRoutePinsUtil.ChanNetDat _ netDat[chan]; pinState: SCNewRoutePinsUtil.ConnectionType _ unconnected; lastConnectedPin: SCNewRoutePinsUtil.PinInChan _ NIL; EnumAllPinsInNetChan[chanNetDat, ClearPin]; IF chanNetDat # NIL THEN { SELECT TRUE FROM chan = 0 => -- this is a side {DoAllPins[chanNetDat, top]; DoAllPins[chanNetDat, bottom]}; net.routeTopology[chan].upper = full AND net.routeTopology[chan].lower = full => {DoExit[chanNetDat, left]; DoExit[chanNetDat, right]; DoAllPins[chanNetDat, top]; DoAllPins[chanNetDat, bottom]}; net.routeTopology[chan].upper = full AND net.routeTopology[chan].lower = min => {DoExit[chanNetDat, left]; DoExit[chanNetDat, right]; DoFullMin[chanNetDat, top, bottom]; DoAllPins[chanNetDat, top]}; net.routeTopology[chan].upper = min AND net.routeTopology[chan].lower = full => {DoExit[chanNetDat, left]; DoExit[chanNetDat, right]; DoFullMin[chanNetDat, bottom, top]; DoAllPins[chanNetDat, bottom]}; net.routeTopology[chan].upper = min AND net.routeTopology[chan].lower = min => {DoExit[chanNetDat, left]; DoExit[chanNetDat, right]; DoMinMin[chanNetDat]}; net.routeTopology[chan].upper = full => -- lower must be none {DoExit[chanNetDat, left]; DoExit[chanNetDat, right]; DoAllPins[chanNetDat, top]}; net.routeTopology[chan].lower = full => -- upper must be none {DoExit[chanNetDat, left]; DoExit[chanNetDat, right]; DoAllPins[chanNetDat, bottom]}; chanNetDat.exits[left] # NIL AND chanNetDat.exits[right] # NIL => {DoExit[chanNetDat, left]; DoExit[chanNetDat, right]}; ENDCASE => IF chanNetDat.exits[left] # NIL OR chanNetDat.exits[right] # NIL THEN SC.Signal[callingError, "Unconnected public wire; make sure all publics hanve more than one pin"]; EnumAllPinsInNetChan[chanNetDat, FixUpAndCheck]; IF lastConnectedPin # NIL THEN {lastConnectedPin.pinConn _ right; chanNetDat.rightmost _ lastConnectedPin}; IF numPinsUsed = 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]]]}}; GetAllNetSegInChan: PUBLIC PROC [handle: SC.Handle, rowChan: SCPrivate.RowChan, segProc: SCNewRoutePinsUtil.SegProc, pinProc: SCNewRoutePinsUtil.PinProc, exitProc: SCNewRoutePinsUtil.ExitProc] ~ { EachNet: SCNetUtil.EachNetProc ~ { IF net.netDat # NIL THEN GetANetSegInChan[handle, rowChan, net, segProc, pinProc, exitProc]}; [] _ SCNetUtil.EnumerateNets[handle, EachNet]}; NextPinState: PROC [pinState: SCNewRoutePinsUtil.ConnectionType, pin: SCNewRoutePinsUtil.PinInChan] RETURNS [newPinState: SCNewRoutePinsUtil.ConnectionType] ~ { IF pin.pinConn = unconnected THEN { -- this pin is unconnected newPinState _ unconnected; IF pin.pinClass = isExit THEN SC.Signal[programmingError, Rope.Cat["Exit is unconnected for wire: ", pin.net.name, ". Call maintainer"]]} ELSE IF pin.pinConn = interior THEN { -- this pin is unconnected; determine which type IF pinState = unconnected THEN -- fitst pin we have come to newPinState _ left ELSE newPinState _ interior}}; PosOfPin: PROC [chanPin: SCNewRoutePinsUtil.PinInChan] RETURNS [INT] ~ INLINE{ RETURN[(chanPin.min+chanPin.max)/2]}; }. 8SCNewRoutePinsUtilImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Jason Cong, August 22, 1987 10:54:38 am PDT last edited by Preas, August 4, 1987 10:59:25 am PDT Bryan Preas August 14, 1987 3:21:11 pm PDT Jean-Marc Frailong October 11, 1987 10:14:56 pm PDT initialize for determining the width of a channel terminate determining the width of a channel PROC[rowChan: SCPrivate.RowChan, pin: PinInChan]; enter a net on a channel into data structure enter exit data for a channel into routing data base enumerate all the pins on this channel (all nets) enumerate the pins on this net on this channel (including exits) enumerate the pins on this net on this channel on side (including exits) initialize the data for a channel EachPinProc: TYPE = PROC[rowChan: SCPrivate.RowChan, pin:PinInChan]; main body of 'CreateNetDat' enter a net segment into chanNetDat, and enter pin connection info in pin. process an exit pin process an channel pin that is to be connected PROC[chanNetDat: ChanNetDat, pin: PinInChan]; process all channel pin that are to be connected that are on side enter at most one pin from minSide; that pin ads the shortest wire segment to the pins on the fullside find the range of pins on fullSide PROC[chanNetDat: ChanNetDat, pin: PinInChan]; find the pin on minSide that adds smallest length to fullSide PROC[chanNetDat: ChanNetDat, pin: PinInChan]; compute span of pins that must be connected enter at most one pin from both channel sides; those pins define the shortest segment that crosses the channel PROC[chanNetDat: ChanNetDat, pin: PinInChan]; clear connections for this net PROC[chanNetDat: ChanNetDat, pin: PinInChan]; set connections for this net PROC[chanNetDat: ChanNetDat, pin: PinInChan]; main body of GetANetSegInChan check for unconnected exits fix up the net connections; make sure left and right pins are done correctly enter all net segment into the netDats, and enter pin connection info. PROC [net: SCPrivate.Net] RETURNS [quit: BOOL _ FALSE]; compute connection of this pin as a function of its position and the previous state Κz˜codešœ™Kšœ<™œœ-˜ΧKšœ&œ˜>Kšœ2˜2šœ0œ$˜WKšœ ˜ J˜ Jšœ œ˜ Jšœ!˜!Jšœ˜Jšœ˜Jšœœ˜Jšœ˜J˜Jšœœœ˜'Jšœ˜Jšœ˜Jšœ˜—Kšœ˜—K™Kšœ5™5š ž œœ œ"œœ3œ-˜ΈK˜Kšœ&œ˜>Kšœ2˜2šœ0œ$˜WKšœ ˜ J˜ Jšœ œ˜ Jšœ˜Jšœ˜Jšœ˜Jšœœ˜Jšœ˜J˜Jšœœœ˜'Jšœ˜Jšœ œ˜Jšœ˜—Kšœ˜K˜—š žœ œ*œœœ˜^šœœ˜Kšœ(œ*˜U—šœœ˜Kšœ œ#œ-˜`—K˜—šžœœ œHœ œœœ˜–K˜Kšœ)˜)Kšœ)˜)Kšœœ˜K˜K˜K˜K˜Kšœœœ˜2šœ œ˜K˜š œ œœœœ˜FK˜*—šœœœ$˜IK˜Kšœ)œœ˜K˜Kšœœœ˜Kšœ#˜#Kšœ2˜2K˜šœ˜Kšœ+˜+Kšœœ˜ šœœ˜"K˜šœœ˜Kšœœ˜ Kšœ˜—K˜ Kšœ˜—Kšœ˜ K˜——šž œ œ.˜Dšœœ˜!K˜(—šœœ˜ K˜(—K˜(K˜(K˜K˜K˜—šžœ œ.˜IK˜9šœœ˜ K˜&—šœœ˜K˜&—K˜&K˜&K˜K˜Kšœœ˜>Kšœœ˜=K˜K™—Kšœ1™1šžœœ œK˜kK˜Kšœ&œ˜>šœ œœ˜Kšœ2˜2šœSœ œ˜lKšœ˜Kšœ˜ ——K˜—Kšœ@™@šžœœ œ`˜†K˜šœœœ˜šœSœ œ˜lKšœ"˜"Kšœ˜ ——K˜—KšœH™Hšžœœ œu˜˜K˜šœœœ˜šœSœ œ˜lKšœœœ#˜_Kšœ˜ ——K˜—Kšœ!™!šž œœ œ œ(˜QK˜šž œ%˜.Kšœ œœ,™DK™K˜Kšœ$œ ˜7Kšœ œ˜Kšœ,œ˜0šœ œ˜Kš œœœ œœ˜K—šœœ˜Kšœœ#˜8—Kšœ˜šœœ˜šœ"œ˜,KšœO˜Q—Kšœ'˜+—šœœœ˜#K˜1K˜—šœ˜K˜&K˜&K˜—K˜.K˜—K˜Kšœ™Kšœ œ˜"K˜$K˜—J™Jšžœœœ œ­˜ΧK™Kšœ™šžœ œF˜WK˜Kšœ<˜<šœœœ˜Kšœ œ˜+Kšœœœ˜2Kšœ œœ&˜K˜šž œ'˜0Kšœ)™-šœœ˜Kšœ œœ˜$Kšœ˜Kšœ˜šœ,œœ˜8Kšœ œ˜Kšœ{˜{šœœœ˜&Kšœœ˜#Kšœ3˜3—šœœœ˜'Kšœœ1˜8Kšœ3˜3—Kšœ*˜*šœœ˜!Kšœ˜Kšœ˜Kšœ$˜$—K˜———Kšœ œ œœ˜!Kš œ œœ!œœ˜LKš œœœ!œœ˜KKšœ(œ˜,Kšœ)œ˜-Kšœ œœ˜Kšœ,˜,Kšœœœ ˜9Kšœœœ#˜?š œœœœ˜[Kšœ*œ˜0—š œœœœœ ˜nKšœ˜K˜——Kšœ™šžœ'˜/Kšœ)™-K˜—K˜Kšœ™šž œ'˜4Kšœ)™-Kšœ5˜5Kšœœ˜2Kšœœ˜4K˜—Kšœ™Kšœ œ˜Kšœ#œ˜=Kšœ-˜-Kšœ$œ ˜7Kšœ-˜-Kšœ9˜9Kšœ:˜:Kšœ5˜5Kšœ+˜+šœœœ˜šœœ˜šœ Οc˜Kšœ<˜<—šœ%œ(˜PKšœ5˜5Kšœ;˜;—šœ%œ'˜OKšœ5˜5Kšœ@˜@—šœ$œ(˜OKšœ5˜5KšœC˜C—šœ$œ'˜NKšœL˜L—šœ(Ÿ˜=KšœR˜R—šœ(Ÿ˜=KšœU˜U—šœœœœ˜AKšœ6˜6—šœ˜ Kšœ™š œœœœ˜EKšœ`˜b———K˜KšœL™LKšœ0˜0šœ˜KšœL˜LK˜—Kš œœ œ"œœs˜ΏK˜——šžœœœ œ™˜ΔK˜J™Fšžœ˜"Kšœœœœ™7šœœ˜KšœD˜D—K˜—Kšœ/˜/K˜—šž œœRœ5˜ KšœS™Sšœœ˜?Kšœ˜šœ˜Kšœj˜l——šœœœ3˜Všœœ˜