//routenetswap.bcpl
// Analyzes nets and prepares them for permutation
// last modified by E. McCreight, July 27, 1981 6:04 PM
get "route.defs"
static [ pointV ]
let RouteNetSwap(net, poutnum, plp) = valof
[
WeAre(doingRouting)
net>>net.hasBeenRouted = true
NewSwapZone((5+4)*maxNets+memoTableEntries*(size MEMO/16)+100)
X = Allocate(swapZone, maxNets)
Y = Allocate(swapZone, maxNets)
Perm = Allocate(swapZone, maxNets)
pointV = Allocate(swapZone, maxNets)
let lp = net>>net.pinList
let nnodes = 0
let epcount = 0
let outcount = 0
let isOutput = Allocate(swapZone, maxNets)
let eclPins = false
let eclOutputs = false
let hasTWPin = false
let nterm = 0
let netString = FindNameesString(net)
let cbv = Allocate(swapZone, maxNets+1)
cbv!0 = maxNets
ComputeClusters(cbv, net)
let singleCluster = cbv!0 eq 1
until (@lp) eq mark do
[
//set up argument vectors for the router
if nnodes ge maxNets then
[
Warning("*nNet $S has too many nodes to route.",
netString)
n = nnodes
resultis false
]
nnodes = nnodes+1
pointV!nnodes = lp
isOutput!nnodes = false
let icinst, pin = nil,lp
FindIcinst(lv icinst, lv pin)
GetPinCoord(icinst, pin, lv X!nnodes, lv Y!nnodes)
let icclass = Icclass(icinst)
let pinAttributes = (icclass>>icclass.PinAttributes)(icinst, pin)
if pinAttributes<<pinattributes.isTerminator then nterm = nterm+1
if pinAttributes<<pinattributes.isEcl then
[
eclPins = true
if pinAttributes<<pinattributes.isOutput then eclOutputs = true
]
if pinAttributes<<pinattributes.isOutput then
[
if epcount eq 0 then @poutnum = nnodes
isOutput!nnodes = true
outcount = outcount+1
]
if icclass>>icclass.isConnector then
[
epcount = epcount+1
@poutnum = 1
if singleCluster then
MakeFirst(nnodes, X, Y, pointV, isOutput)
]
let twclass, twpin = empty,nil
let index = FindIndexFromCoord(X!nnodes, Y!nnodes, lv twclass, lv twpin)
if index ne 0 & twclass ne empty &
GetBit(twclass>>icclass.cutPins, twpin) eq 0 then
hasTWPin = true
lp = @lp
]
//do a little checking on the validity of the net
unless hasTWPin do
[
let incount = nnodes-outcount-epcount
if (incount eq 0)&(epcount eq 0) then
[
Warning( "*nNet $S consists of outputs exclusively.",netString)
]
if (outcount eq 0)&(epcount eq 0) then
[
Warning( "*nNet $S consists of inputs exclusively.",netString)
]
if (outcount eq 0)&(incount eq 0) then
[
Warning( "*nNet $S consists of edge pins exclusively.",netString)
]
if epcount gr 1 then
[
Warning( "*nNet *"$S*" has more than one off-board connector pin",
netString)
]
]
if nnodes le 0 then
[
unless net>>net.isTraceWired % net eq dontCareNet do
Serious("*nEmpty net: *"$S*"", netString)
]
if nnodes eq 1 then
[
Warning("*nSingle Node Net: *"$S*"", netString)
]
// Set up for the wire routers...
n = nnodes
forceFirstNodeToEnd = epcount ne 0
DistFn = StandardMetric
clusterBaseVec = singleCluster? empty, cbv
@plp = lp // tell caller where net ends
// set up for the memo-using arc-length function
memoTable = Allocate(swapZone, memoTableEntries*(size MEMO/16))
Zero(memoTable, memoTableEntries*(size MEMO/16))
Free(swapZone, isOutput)
//for ECL nets, if outcount = 1 and epcount = 0,
//we route the net two ways, one with the output forced to the
//end of the net, once with it unconstrained. If the constrained
//length is less then 1.2x the unconstrained length+2", the constrained
//form of the net is used. This puts the output at the end of the net.
resultis (outcount eq 1)&(epcount eq 0)& eclPins & singleCluster
]
and HasExternalConnection(net) = valof
[
let lp = net>>net.pinList
until (@lp) eq mark do
[
let icinst, pin = nil,lp
FindIcinst(lv icinst, lv pin)
if Icclass(icinst)>>icclass.isConnector then resultis true
lp = @lp
]
resultis false
]
and MakeFirst(i, v0, v1, v2, v3, v4, v5; numargs na) be
[
for j=0 to na-2 do
[
let v = (lv v0)!j
let t = v!1
v!1 = v!i
v!i = t
]
]