// NetDelaysBoard.bcpl
// last modified December 15, 1978

get "NetDelays.defs"


let DoBoardNets() be
[
Wss(screen,"*n*n")
FindFirstNet(0)
let nodestr = vec 20
let net = vec Lnet
[
Zero(net,Lnet)
let node = vec Lnode
FindNet(net); if Done then break
ReadInNet(net,node,0,nodestr)
if (net>>net.inputs eq 0)%(net>>net.mufpins gr 1) then
[ if Debug gr 0 then SendTab()
Msg(" $S - skipped*n",lv net>>net.name)
loop
]
if Debug ge 3 then Msg("$S,> ",nodestr)

ComputeOnBdDelays(net)
TotalDelay = TotalDelay + net>>net.Dly
TotalLength = TotalLength + net>>net.length.end/10
Nets = Nets + 1

if Debug gr 0 then SendTab()
ListOnBdDelays(net)
test screenEn
ifso unless Endofs(keys) do [ Gets(keys);if Gets(keys) eq DEL then Done=true ]
ifnot Puts(screen,$!)
if Done then break
] repeat
Closes(file)
]

and ReadInNet(net,node,Bd,nodestr) be
[
nodestr>>str.length = 0
file = fileVec!Bd
node>>node.NewX = -1 //set node to "first node in net"
[//find all pins on net
let type = FindNode(node,net,Bd,nodestr)
if type eq true then break//new net

ProcessNode(node,net,type)
] repeat

if WLout then if net>>net.edgechar do CopyToWLFile()
printedDly=false
if (net>>net.edgechar ne 0)&(EdgePins eq 0) then //make edgepin an input or output
test net>>net.outputs eq 0
ifso //make the edge pin an output
[
net>>net.outputs = 1
test net>>net.edgefirst eq 0
ifso //put edge pin at back of net
[
net>>net.length.Fout = net>>net.length.end
net>>net.pins.Fout = net>>net.pins.end
net>>net.length.Lout = net>>net.length.end
net>>net.pins.Lout = net>>net.pins.end
]
ifnot //put edge pin at front of net
[
net>>net.length.Fout = 0
net>>net.pins.Fout = 1
net>>net.length.Lout = 0
net>>net.pins.Lout = 1
]
]
ifnot //make the edge pin an input
[
net>>net.inputs = net>>net.inputs + 1
test net>>net.edgefirst eq 0 //put edge pin at back of net
ifso //put edge pin at end of net
[
net>>net.length.Lin = net>>net.length.end
net>>net.pins.Lin = net>>net.pins.end
if net>>net.inputs eq 1 then //this is the only input
[
net>>net.length.Fin = net>>net.length.end
net>>net.pins.Fin = net>>net.pins.end
]
]
ifnot //put edge pin at front of net
[
net>>net.length.Fin = 0
net>>net.pins.Fin = 1
if net>>net.inputs eq 1 then //this is the only input
[
net>>net.length.Lin = net>>net.length.end
net>>net.pins.Lin = net>>net.pins.end
]
]
]
]

and ProcessNode(node,net,type) be

[
let NetLength = net>>net.length.end + node>>node.Distance
net>>net.length.end = NetLength
net>>net.pins.end = net>>net.pins.end + 1
if net>>net.terms eq 0 then net>>net.stubl = node>>node.Distance
if type eq $t then net>>net.terms = net>>net.terms + 1
if type eq $m then net>>net.mufpins = net>>net.mufpins + 1
if (type eq $e)%(type eq $c) then
[
net>>net.edgechar = type
if net>>net.pins.end eq 1 then net>>net.edgefirst = true
]
if type eq $i then
[
if net>>net.pins.Fin eq 0 then
[
net>>net.length.Fin = NetLength
net>>net.pins.Fin = net>>net.pins.end
]
net>>net.length.Lin = NetLength
net>>net.pins.Lin = net>>net.pins.end
net>>net.inputs = net>>net.inputs+1
]
if type eq $o then
[
if net>>net.pins.Fout eq 0 then
[
net>>net.length.Fout = NetLength
net>>net.pins.Fout = net>>net.pins.end
]
net>>net.length.Lout = NetLength
net>>net.pins.Lout = net>>net.pins.end
net>>net.outputs = net>>net.outputs+1
if node>>node.Chip eq SE then net>>net.clocknet = true
]

]

and ComputeOnBdDelays(net) be

[
let L = net>>net.length.Lout - net>>net.length.Fout
let P = (net>>net.pins.Lout - net>>net.pins.Fout) + 1
let WOrDly = FindDelay(L, P,"w")
L = net>>net.length.Lin - net>>net.length.Fout
P = (net>>net.pins.Lin - net>>net.pins.Fout) + 1
let Dly = FindDelay(L, P,"f")+WOrDly
L = net>>net.length.Lout - net>>net.length.Fin
P = (net>>net.pins.Lout - net>>net.pins.Fin) + 1
let otherDly = FindDelay(L, P,"r")+WOrDly
if otherDly gr Dly then Dly = otherDly //use the greater
net>>net.WOrDly = WOrDly
net>>net.Dly = Dly
]

and ListOnBdDelays(net) be

[
let DlyInt, DlyFraction = net>>net.Dly/10, net>>net.Dly rem 10
let WOrInt, WOrFraction = net>>net.WOrDly/5, (net>>net.WOrDly*2) rem 10//2*WOrDly
DlyTable!DlyInt = DlyTable!DlyInt+1
let Fok = true
if Fok then if (net>>net.clocknet) & (WOrInt ge 1) then [ Msg("$Dwc", WOrInt); Fok=0 ]
if Fok then if WOrInt ge 3 then [ Msg("$Dw ", WOrInt); Fok=0 ]
if Fok then if (net>>net.clocknet) & (DlyInt ge 2) then [ Msg("$Ddc", DlyInt); Fok=0 ]
if Fok then if DlyInt ge 5 then [ Msg("$Dd ", DlyInt); Fok=0 ]
if Fok then Msg(" ")
Msg("$S($D)",lv net>>net.name,net>>net.number); SendTab()
Msg ("Dly=$D.$D; ",DlyInt, DlyFraction)
Msg ("L=$D; ",net>>net.inputs + net>>net.mufpins)
Msg ("T=$D",net>>net.terms)
if net>>net.outputs gr 1 then Msg ("; WO=$D.$D",WOrInt, WOrFraction)
Msg("*n")
]

and FindNet(net) be
[
FilePos(file,Fposn)
let str = lv net>>net.name
str>>str.length = 0
[ let char = Char()
if char eq $: then break
if char ne $*n then AppendC(lv net>>net.name,char)
if Done then return
] repeat
if StEq(str,"CALIBRATE") % StEq(str,"DISCARD") % StEq(str,"DISCONNECT") % StEq(str,"GND") % StEq(str,"VCC") % StEq(str,"VEE") % StEq(str,"VTT") % StEq(str,"VDD") % StEq(str,"VBB") then
[
[ FindChar($*n); if Char() eq $*n then break ] repeat
if Debug ge 3 then [ SendTab(); Msg(" $S - skipped*n",str) ]
loop
]
FindChar($<)
let num = GetNum()
FindChar($*n)
net>>net.number = num
return
] repeat


and FindNode(node,net,BdNum,nodestr) = valof
[ let newLine = false; let alpha = nil; let type = 0
[
alpha = Char()
if alpha eq $E then [ type = $e; break ]
if alpha eq $C then [ type = $c; break ]
if (alpha ge $a) & (alpha le $z) then break
if alpha eq $*n then newLine = newLine+1; if newLine ge 2 then resultis -1
] repeat
let num = GetNum()
if (type ne $e)&(type ne $c) then
[
[ type = Char(); if (type eq $i) % (type eq $o) then break; if type le #40 then resultis -1 ] repeat
node>>node.Chip = WhatICtype(alpha,num,BdNum)
if node>>node.Chip eq Term then type = $t
if node>>node.Chip eq MU then type = $m
]
//append the node type such that a backpanel terminator is
//before the first last pin or after the last edge pin
if net>>net.pins.end ne 0 then AppendC(nodestr,type)
if EdgePins do
if ((type eq $e)%(type eq $c)) & EdgePinTermination(type,num,BdNum) then
[ net>>net.terms=net>>net.terms+1; AppendC(nodestr,$t) ] //backpanel terminator
if net>>net.pins.end eq 0 then AppendC(nodestr,type)

FindChar(${)
node>>node.OldX = node>>node.NewX; node>>node.OldY = node>>node.NewY
node>>node.NewX = GetNum(); node>>node.NewY = GetNum()
FindDistance(node)
resultis type
]