//routeNetRes.bcpl

// Resident stub that controls wire routing

// last modified by E. McCreight, July 20, 1981 10:50 AM
// Modified by Rumph, December 5, 1984 5:21 PM
// to change back the pin order if we decide against the 2nd routing attempt
// and zero the memotable betwee calls to Route() for the same net.

get "route.defs"

let RouteEarlyNets(net) be if net>>net.wireEarly then RouteNet(net)

and RouteNetIfExternal(net) be if HasExternalConnection(net) then RouteNet(net)

and RouteNet(net) be
[
static [ currentNet; crucialNet = -1; singleOutputInCenterOK = true ]

currentNet = net
if net eq crucialNet then CallSwat("Routing crucial net..")

if net>>net.isSame % net>>net.hasBeenRouted then return //net already done
if net>>net.isTraceWired then return // not suitable for routing

let lp = nil
let outnum = 0
let bothWays = RouteNetSwap(net, lv outnum, lv lp) // sets up swapZone too

if n gr 2 & n ls maxNets then
[
// First route the net as it is

forceFirstNodeToEnd = false
Route()
let btnl = bestTotalNetLength

//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.

if bothWays then
[
// force the single output to the end of the net.

MakeFirst(outnum, X, Y, pointV)

// clear the memoTable used by ArcLength
Zero(memoTable, memoTableEntries*(size MEMO/16))

let origPerm = Perm
forceFirstNodeToEnd = true
Route()

// if this routing is at most 20%+2" worse than the
// unconstrained routing, use it.

if singleOutputInCenterOK &
bestTotalNetLength gr (btnl+btnl/5+80) then
[
// put the output back where it was, restore the old Perm
MakeFirst(outnum, X, Y, pointV)
Perm = origPerm
]
]

//Reorder the list based on the permutation

net>>net.pinList = pointV!(Perm!1) //list head
for j = 1 to n-1 do @(pointV!(Perm!j)) = pointV!(Perm!(j+1))
@(pointV!(Perm!n)) = lp //last node
]
swapZone = empty
]

and Route() be
[
Perm = Allocate(swapZone, maxNets)
test n le exhaustThresh % clusterBaseVec ne empty
ifso CombinRoute()
ifnot
[
GenerateGoodPerm()
HeuristicImprove()
]
]