//routetwassign.bcpl

// Trace-wired net assignment module.

// last modified by E. McCreight, October 30, 1981 2:35 PM

get "route.defs"

static [ currentTWNet; currentTWNetName ]

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 CompareSperges(i, j) = TWspergevec!i-TWspergevec!j
let TWFindSperge(i) = TWspergevec!(TWperm!i)

currentTWNet = net
currentTWNetName = FindNameesName(net)
let netString = FindNameesString(net)
let netMark = lv FindNameesName(net)>>name.mark
let icclass = DefineNamee(netString, typeIcclass, CallSwat)
let orignpins = Npins(icclass)
let partnetString = vec 20
let pin = net>>net.pinList
if @pin eq mark then
[
let hasPart = false
for i=1 to orignpins do
if TryFindingNamee(
ExpandTemplate(partnetString, "$S$D", netname, i),
typeNet) ne empty then hasPart = true
if not hasPart then return // empty net
]

NewSwapZone(2*orignpins+100)
let icinst = DefineNamee(netString, typeIcinst, 0, orignpins-1)
icinst>>icinst.ictype = icclass
let cutPins = icclass>>icclass.cutPins
TWperm = Allocate(swapZone, orignpins+1)
TWspergevec = Allocate(swapZone, orignpins+1)
let nelements = 0
let x,y,pinInfo = nil,nil,nil
for i=1 to orignpins do
[
WeAre(doingTraces)
let pinCut = GetBit(cutPins, i) ne 0
(icclass>>icclass.PinOffset)(icinst, i, lv x, lv y, lv pinInfo)

let partnet = TryFindingNamee(ExpandTemplate(partnetString,
"$S$D", netname, i), typeNet)
if partnet ne empty then test pinCut
ifso
[
Serious("*n$S$D has been cut, can’t be used for connecting to $S.")
]
ifnot
[ // Move the pin list from the net to the TW pin
icinst>>icinst.pin↑i = partnet>>net.pinList
partnet>>net.pinList = netMark
]

unless pinCut%((not doMultiWire)&(not doPC)&
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
[ // assign each pin to the closest TW pin
WeAre(doingTraces)
let x,y = nil,nil
GetPinCoord(0, pin, lv x, lv y)
let curPin = pin
pin = @pin
let nearest = TWperm!FindNearest(x, y, nelements, TWFindSperge)
@curPin = (icinst>>icinst.pin↑nearest eq empty)? netMark,
icinst>>icinst.pin↑nearest
icinst>>icinst.pin↑nearest = curPin
]

net>>net.pinList = netMark
Free(swapZone, TWperm)
Free(swapZone, TWspergevec)

for i=1 to orignpins do
[
if icinst>>icinst.pin↑i ne empty then
[
WeAre(doingTraces)
let hasOtherPin, hasTWPin = false,false
let TWx,TWy = nil,nil
GetPinCoord(0, lv icinst>>icinst.pin↑i, lv TWx, lv TWy)
let pin = icinst>>icinst.pin↑i
while @pin ne mark do
[
GetPinCoord(0, pin, lv x, lv y)
test (TWx eq x) & (TWy eq y)
ifso hasTWPin = true // by another preferred name
ifnot hasOtherPin = true
pin = @pin
]
if hasOtherPin then
[
let partNet = TryFindingNamee(
ExpandTemplate(partnetString,
"$S$D", netname, i), typeNet)
if partNet eq empty then
[
partNet = DefineNamee(ExpandTemplate(
partnetString, "$S-", netname),
typeNet, NewPartNet, 0, true)
partNet>>net.isPartialNet = true
]
partNet>>net.pinList
= hasTWPin?
icinst>>icinst.pin↑i, lv icinst>>icinst.pin↑i
]
]
swapZone = empty
]
]

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