//routetwassign.bcpl

// Trace-wired net assignment module.

// last modified by E. McCreight, November 10, 1978 12:22 AM

get "route.defs"

static [ currentTWNet ]

let AssignTWNet(net) be
[ // Reassign all pins connected to trace-wired nets to small trace-wired nets
// containing one trace-wired pin (the closest one).
let netname = FindNameesString(net)

static [ TWperm; TWspergevec ]

unless net>>net.isTraceWired do return
let pin = net>>net.pinList
if @pin eq mark then return // empty net

let CompareSperges(i, j) = TWspergevec!i-TWspergevec!j
let TWFindSperge(i) = TWspergevec!(TWperm!i)

currentTWNet = net
let netString = FindNameesString(net)
let netMark = lv FindNameesName(net)>>name.mark
let icclass = DefineNamee(netString, typeIcclass, CallSwat)
let orignpins = Npins(icclass)
let icinst = DefineNamee(netString, typeIcinst, 0, orignpins-1)
icinst>>icinst.ictype = icclass
let cutPins = icclass>>icclass.cutPins
TWperm = Allocate(SilZone, orignpins+1)
TWspergevec = Allocate(SilZone, orignpins+1)
let partnetString = vec 20
let nelements = 0
let x,y,pinInfo = nil,nil,nil
for i=1 to orignpins do
[
let partnet = TryFindingNamee(ExpandTemplate(partnetString,
"$S$D", netname, i), typeNet)
let pinCut = GetBit(cutPins, i) ne 0
(icclass>>icclass.PinOffset)(icinst, i, lv x, lv y, lv pinInfo)

if partnet ne empty then test pinCut
ifso
[
Serious("*n$S$D has been cut, can’t be used for connecting to $S.")
]
ifnot
[ // mark the net as a partition of a trace-wired net, and add the TW pin
let ppin = lv partnet>>net.pinList
while @@ppin ne mark do ppin = @ppin
@ppin = lv icinst>>icinst.pin↑i
icinst>>icinst.pin↑i = netMark
]

unless pinCut%((not doMultiWire)&pinInfo<<info.usedForDecoupling) do
[
nelements = nelements+1
TWperm>>permutation.element↑nelements = i
TWspergevec!i = Sperge(x, y)
]
]
TWperm>>permutation.nelements = nelements
TWspergevec!0 = nelements

Sort(TWperm, CompareSperges)

while @pin ne mark do
[
WeAre(doingTraces)
let x,y = nil,nil
GetPinCoord(0, pin, lv x, lv y)
let nearestIndex = FindNearest(x, y, nelements, TWFindSperge)
let curPin = pin
pin = @pin
test Sperge(x, y) eq TWFindSperge(nearestIndex)
ifso
[ // the two pins are the same...
@curPin = netMark
]
ifnot
[ // the two pins are not the same...
let nearest = TWperm!nearestIndex
if icinst>>icinst.pin↑nearest eq empty then
[
let partnet = DefineNamee(ExpandTemplate(partnetString, "$S$D",
netname,nearest), typeNet, NewPartNet)
icinst>>icinst.pin↑nearest = partnet>>net.pinList
partnet>>net.pinList = lv icinst>>icinst.pin↑nearest
]
@curPin = icinst>>icinst.pin↑nearest
icinst>>icinst.pin↑nearest = curPin
]
]
net>>net.pinList = netMark
Free(SilZone, TWperm)
Free(SilZone, TWspergevec)
]

and NewPartNet(net) be
[
NewNet(net)
net>>net.pinList = lv FindNameesName(net)>>name.mark
]