//routeb.bcpl
// Output module
// last modified by D. Rumph, March 8, 1985 6:09 PM
// to allow for splitting of the wirelist file
// modified by D. Rumph, March 7, 1985 12:02 PM
// to change AssignNet priorities (net length, not shortest arc)
// modified by E. McCreight, July 2, 1981 10:13 AM
get "route.defs"
static
[
netnumber = 0
outcount; nodecount; headingpresent; currentFile
baseNetNumber; netCount; netOffset
zeroPending; currentlevel; noseName
twPartNo
]
let MakeOutputFile(file, whichFile) be
[
baseNetNumber = 1
currentFile = file
PutTemplate(file, "$S*n", ZeroTablePoint(0))
if (whichFile eq isICFile) % (whichFile eq isWLFile) then
[
let comments = GetFile(nlFileName,".comments")
until Endofs(comments) do Puts(file, Gets(comments))
Closes(comments)
DoInSortOrder(typeIcinst, NameCompareFn, OutputUsedIC)
]
if (whichFile eq isICFile) then return
Wss(currentFile, "*n@")
currentlevel = 1
let levelName, pullComponents, wire = nil,nil,nil
while LevelTransform(currentlevel, 0, 0, 0, 0, lv levelName,
lv pullComponents, lv wire) do
[
zeroPending = true
noseName = "welder"
if (whichFile eq isADFile) then
[
if pullComponents then PullComponents()
if wire then
[
netCount = 0
DeleteNets()
baseNetNumber = baseNetNumber+netCount
]
]
zeroPending = true
noseName = "cutter"
test (whichFile eq isADFile)
ifso [ ReportPins(ReportRepairedPins); ReportPins(ReportNewCutPins) ]
ifnot ReportPins(ReportCutPins)
if wire then
[
zeroPending = true
noseName = "welder"
netCount = 0
twPartNo = 0
DoInSortOrder(typeNet, NameCompareFn,
((whichFile eq isADFile)? PrintNewNet, PrintNet))
baseNetNumber = baseNetNumber+netCount
]
currentlevel = currentlevel lshift 1
]
]
and ReportPins(Routine) be
[
headingpresent = false
DoInSortOrder(typeIcclass, NameCompareFn, Routine)
]
and NLCompFn(net1,net2) = valof //sort function for net routing. First nets wired
// are those that will appear in the .AD file. Within that, sort by "wireEarly".
// Within that, sort by net length. Within that, sort by shortest arcs.
[
if net1>>net.hasNetnum then resultis -1
if net2>>net.hasNetnum then resultis 1
// because AssignNetNumber
// clobbers the shortestarc field with the netnum field
// we have to give NextBatchToHeap some explicit help. The
// -1 says that net1 is already done. The 1 says that net1
// still needs doing.
let same1 = net1>>net.isSame
let same2 = net2>>net.isSame
if same1 ne same2 then resultis same1? 1, -1
let we1 = net1>>net.wireEarly
let we2 = net2>>net.wireEarly
if doMultiWire then if we1 ne we2 then resultis we1? -1, 1
let sa1 = net1>>net.netlength
let sa2 = net2>>net.netlength
if sa1 ne sa2 then resultis sa1-sa2
resultis net1>>net.shortestarc-net2>>net.shortestarc
]
and AssignNetNumber(net) be
[
net>>net.hasNetnum = true
let firstpin = net>>net.pinList
if @firstpin eq mark then return // empty pin list
netnumber = netnumber+1
net>>net.netnum = netnumber
]
and OutputUsedIC(icinst) be
[
WeAre(doingOutput)
unless Icclass(icinst)>>icclass.printUsedList do return
PutTemplate(OutFile, "*n$S: ($S) ; ", FindNameesString(icinst),
FindNameesString(icinst>>icinst.ictype))
let commaNeeded = false
let x,y = nil,nil
for pin=1 to Npins(icinst) do
[
if GetPinCoord(icinst, pin, lv x, lv y) &
icinst>>icinst.pin↑pin eq empty then
[
if commaNeeded then PutTemplate(OutFile, ",")
PutTemplate(OutFile, "$D", pin)
commaNeeded = true
]
]
]
and ZeroTheTable() be
[
unless zeroPending do return
zeroPending = false
let levelName = nil
let xtable = vec 5
let ytable = vec 5
let x, y = nil,nil
let cornertable = vec 5
for point = 1 to 4 do
[
GetPatternCoord(ZeroTablePoint(point), lv x, lv y)
LevelTransform(currentlevel, x, y, lv xtable!point, lv ytable!point,
lv levelName)
]
PermuteCorners(xtable, ytable, cornertable)
PutTemplate(currentFile, "*n*nCALIBRATE: <$D> ; INSTALL $S nose, board $S up ...", baseNetNumber, noseName, levelName)
baseNetNumber = baseNetNumber+1
outcount = 0
for corner = 1 to 4 do
[
let point = cornertable!corner
GetPatternCoord(ZeroTablePoint(point), lv x, lv y)
PrintBasicPin(ZeroTablePoint(point), x, y)
]
]
and PermuteCorners(xtable, ytable, cornertable) be
[
// find center of mass
let cx,cy = 0,0
for i=1 to 4 do
[
cx = cx+xtable!i
cy = cy+ytable!i
]
cx = cx/4
cy = cy/4
for corner = 1 to 4 do
[
for point = 1 to 4 do
[
// identify point toward origin from center of mass
if xtable!point ls cx & ytable!point ls cy then
cornertable!corner = point
// rotate point ccw 90 degrees about center of mass
let newx = cx-(ytable!point-cy)
ytable!point = cy+(xtable!point-cx)
xtable!point = newx
]
]
]
and ReportCutPins(icclass) be
[
unless icclass>>icclass.isTraceWired do return
let cutPins = icclass>>icclass.cutPins
if cutPins eq empty then CallSwat()
for i=1 to Npins(icclass) do
[
if GetBit(cutPins, i) eq 0 then loop
let x,y,info = nil,nil,nil
if (icclass>>icclass.PinOffset)(0, i, lv x, lv y, lv info) ne absolute then
CallSwat()
if (info<<info.level & currentlevel) eq 0 then loop
Heading("DISCONNECT")
PrintPin(icclass, i, currentFile)
]
]
and Heading(str) be
[
unless headingpresent & nodecount le 59 do
[
ZeroTheTable()
PutTemplate(currentFile, "*n*n$S: <$D>", str, baseNetNumber)
baseNetNumber = baseNetNumber+1
headingpresent = true
outcount = 0
nodecount = 0
]
]
and PrintNet(net, netnum; numargs na) be //print all nodes associated with net
[
DefaultArgs(lv na, -1, net>>net.netnum)
if (netnum le netOffset) then return
if (netnum+baseNetNumber-netOffset-1 gr outThreshold) then return
let pin = net>>net.pinList
if @pin eq mark then return
ZeroTheTable()
netCount = netCount+1
WeAre(currentFile eq OutFile? doingOutput, doingADFile)
let netName = vec 30
test net>>net.isPartialNet
ifso
[
ExpandTemplate(netName, "$S$D", FindNameesString(net),
twPartNo)
twPartNo = twPartNo+1
]
ifnot netName = FindNameesString(net)
PutTemplate(currentFile, "*n*n$S: <$D> ($D)", netName,
netnum+baseNetNumber-netOffset-1, net>>net.netlength)
outcount = 0
until @pin eq mark do
[
PrintPin(0, pin, currentFile)
pin = @pin
]
]
and PrintPin(icinst, pin, file, skipFormatting; numargs na) be //print a single pin
[
DefaultArgs(lv na, -2, currentFile, false)
if icinst eq 0 then
[
icinst = pin-offset icinst.pin↑1/16
pin = 1
while icinst>>icinst.type ne typeIcinst do
[
pin = pin+1
icinst = icinst-1
]
]
let x,y = nil,nil
GetPinCoord(icinst, pin, lv x, lv y)
let icclass = Icclass(icinst)
let pa = (icclass>>icclass.PinAttributes)(icinst,pin)
let iostr = ""
let ictype = icinst>>icinst.ictype
if ictype>>namee.type eq typeIctype then
iostr = pa<<pinattributes.isOutput? "o", "i"
let pnv = vec 40
ExpandTemplate(pnv, "$S$S$D$S",
FindNameesString(icinst),
(icclass>>icclass.isTraceWired%icclass>>icclass.isConnector? "", "."),
pin, iostr)
PrintBasicPin(pnv, x, y, file, skipFormatting)
]
and PrintBasicPin(pinstring, x, y, file, skipFormatting; numargs na) be
[
static [ lastPinLen ]
DefaultArgs(lv na, -3, currentFile, false)
LevelTransform(currentlevel, x, y, lv x, lv y)
unless skipFormatting do
[
test outcount eq 0 % outcount gr 3
ifso [ outcount = 0; Wss(file, "*n ") ]
ifnot for i=1 to 22-lastPinLen do Puts(file, $*s)
]
let pnv = vec 40
ExpandTemplate(pnv, "$S {$D,$D}", pinstring, x, y)
Wss(file, pnv)
lastPinLen = pnv>>str.length
outcount = outcount+1
nodecount = nodecount+1
]