timfuz: timing.txt "," delim, line_net procs (cleanup + bug fix)

Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
John McMaster 2018-10-03 16:27:07 -07:00
parent f023e0dcf0
commit f4faa27243
4 changed files with 77 additions and 86 deletions

View File

@ -37,11 +37,32 @@ proc list_format {l delim} {
}
return $ret
}
proc line_net_external {fp net src_site src_site_type src_site_pin src_bel src_bel_pin dst_site dst_site_type dst_site_pin dst_bel dst_bel_pin ico fast_max fast_min slow_max slow_min pips_out nodes_out wires_out} {
puts $fp "NET,$net,$src_site,$src_site_type,$src_site_pin,$src_bel,$src_bel_pin,$dst_site,$dst_site_type,$dst_site_pin,$dst_bel,$dst_bel_pin,$ico,$fast_max,$fast_min,$slow_max,$slow_min,$pips_out,$nodes_out,$wires_out"
}
proc line_net_internal {fp net site site_type src_bel src_bel_pin dst_bel dst_bel_pin ico fast_max fast_min slow_max slow_min} {
set src_site $site
set src_site_type $site_type
set src_site_pin ""
set dst_site $site
set dst_site_type $site_type
set dst_site_pin ""
set pips_out ""
set nodes_out ""
set wires_out ""
puts $fp "NET,$net,$src_site,$src_site_type,$src_site_pin,$src_bel,$src_bel_pin,$dst_site,$dst_site_type,$dst_site_pin,$dst_bel,$dst_bel_pin,$ico,$fast_max,$fast_min,$slow_max,$slow_min,$pips_out,$nodes_out,$wires_out"
}
proc write_info4 {} {
set outdir "."
set fp [open "$outdir/timing4.txt" w]
# bel as site/bel, so don't bother with site
puts $fp "linetype net src_site src_site_type src_site_pin src_bel src_bel_pin dst_site dst_site_type dst_site_pin dst_bel dst_bel_pin ico fast_max fast_min slow_max slow_min pips inodes wires"
puts $fp "linetype,net,src_site,src_site_type,src_site_pin,src_bel,src_bel_pin,dst_site,dst_site_type,dst_site_pin,dst_bel,dst_bel_pin,ico,fast_max,fast_min,slow_max,slow_min,pips,inodes,wires"
set TIME_start [clock clicks -milliseconds]
set equations 0
@ -52,6 +73,7 @@ proc write_info4 {} {
set neti 0
set nets [get_nets -hierarchical]
#set nets [get_nets clk]
#set nets [get_nets roi/counter[0]_i_2_n_0]
set nnets [llength $nets]
foreach net $nets {
incr neti
@ -105,7 +127,7 @@ proc write_info4 {} {
# only increment on one of the paths
set equations [expr "$equations + [llength $delays]"]
}
puts $fp "GROUP $ico [llength $delays]"
puts $fp "GROUP,$ico,[llength $delays]"
foreach delay $delays {
#set delaystr [get_property NAME $delay]
@ -128,10 +150,19 @@ proc write_info4 {} {
# No fabric on this net?
# don't try querying sites and such
if {[get_nodes -of_objects $net] eq ""} {
if {$src_site ne $dst_site} {
puts "ERROR: site mismatch"
return
}
if {$src_site_type ne $dst_site_type} {
puts "ERROR: site mismatch"
return
}
# Already have everything we could query
# Just output
incr lines_no_int
puts $fp "NET $net $src_site $src_site_type $src_site_pin $src_bel $src_bel_pin $dst_site $dst_site_type $dst_site_pin $dst_bel $dst_bel_pin $ico $fast_max $fast_min $slow_max $slow_min $pips_out $nodes_out $wires_out"
line_net_internal $fp $net $src_site $src_site_type $src_bel $src_bel_pin $dst_bel $dst_bel_pin $ico $fast_max $fast_min $slow_max $slow_min
# At least some fabric exists
# Does dest BEL exist but not source BEL?
} elseif {$src_bel eq ""} {
@ -139,7 +170,7 @@ proc write_info4 {} {
return
# Ideally query from and to cell pins
} else {
# Nested list delimination precedence: " |:"
# Nested list delimination precedence: ",|:"
# Pips in between
# Walk net, looking for interesting elements in between
@ -176,7 +207,7 @@ proc write_info4 {} {
set wires_out [list_format "$wires_out" "|"]
incr lines_some_int
puts $fp "NET $net $src_site $src_site_type $src_site_pin $src_bel $src_bel_pin $dst_site $dst_site_type $dst_site_pin $dst_bel $dst_bel_pin $ico $fast_max $fast_min $slow_max $slow_min $pips_out $nodes_out $wires_out"
line_net_external $fp $net $src_site $src_site_type $src_site_pin $src_bel $src_bel_pin $dst_site $dst_site_type $dst_site_pin $dst_bel $dst_bel_pin $ico $fast_max $fast_min $slow_max $slow_min $pips_out $nodes_out $wires_out
}
}
}
@ -193,3 +224,7 @@ proc write_info4 {} {
puts " Has interconnect: $lines_some_int"
}
# for debugging
# source ../project.tcl
# write_info4

View File

@ -220,7 +220,9 @@ def derive_eq_by_col(Ads, b_ub, verbose=0, keep_orig=True):
# iteratively increasing column limit until all columns are added
def massage_equations(Ads, b, verbose=False, corner=None):
def massage_equations(
Ads, b, verbose=False, corner=None, iter_lim=1, col_lim=100000):
#col_lim = 15
'''
Subtract equations from each other to generate additional constraints
Helps provide additional guidance to solver for realistic delays
@ -262,7 +264,6 @@ def massage_equations(Ads, b, verbose=False, corner=None):
# Each iteration one more column is allowed until all columns are included
# (and the system is stable)
col_lim = 15
di = 0
while True:
print
@ -298,13 +299,13 @@ def massage_equations(Ads, b, verbose=False, corner=None):
col_dist(Ads, 'derive done iter %d, lim %d' % (di, col_lim), lim=12)
rows = len(Ads)
di += 1
dend = len(b)
# possible that a new equation was generated and taken away, but close enough
if n_orig == len(b) and col_lim >= cols:
if n_orig == len(b) and col_lim >= cols or di >= iter_lim:
break
col_lim += col_lim / 5
di += 1
dend = len(b)
print('')
print('Derive net: %d => %d' % (dstart, dend))
print('')

View File

@ -150,7 +150,10 @@ def solve_save(outfn, xvals, names, corner, save_zero=True, verbose=False):
print(
'Wrote: %u / %u constrained delays, %u zeros' %
(nonzeros, len(names), zeros))
assert nonzeros, 'Failed to estimate delay'
# max only...min corner seems to like 0
# see https://github.com/SymbiFlow/prjxray/issues/136
if 'max' in corner:
assert nonzeros, 'Failed to estimate delay'
def run(

View File

@ -23,11 +23,23 @@ def parse_pip(s, speed_i2s):
return site, instance, speed_i2s[int(speed_index)]
def parse_pips(pips, speed_i2s):
if not pips:
return []
return [parse_pip(pip, speed_i2s) for pip in pips.split('|')]
def parse_node(s):
node, nwires = s.split(':')
return node, int(nwires)
def parse_nodes(nodes):
if not nodes:
return []
return [parse_node(node) for node in nodes.split('|')]
def parse_wire(s, speed_i2s):
# CLBLM_R_X3Y80/CLBLM_M_D6:952
wirestr, speed_index = s.split(':')
@ -35,10 +47,16 @@ def parse_wire(s, speed_i2s):
return site, instance, speed_i2s[int(speed_index)]
def parse_wires(wires, speed_i2s):
if not wires:
return []
return [parse_wire(wire, speed_i2s) for wire in wires.split('|')]
def gen_timing4(fn, speed_i2s):
f = open(fn, 'r')
header_want = 'linetype net src_site src_site_type src_site_pin src_bel src_bel_pin dst_site dst_site_type dst_site_pin dst_bel dst_bel_pin ico fast_max fast_min slow_max slow_min pips inodes wires'
ncols = len(header_want.split())
header_want = "linetype,net,src_site,src_site_type,src_site_pin,src_bel,src_bel_pin,dst_site,dst_site_type,dst_site_pin,dst_bel,dst_bel_pin,ico,fast_max,fast_min,slow_max,slow_min,pips,inodes,wires"
ncols = len(header_want.split(','))
# src_bel dst_bel ico fast_max fast_min slow_max slow_min pips
header_got = f.readline().strip()
@ -52,17 +70,15 @@ def gen_timing4(fn, speed_i2s):
for l in f:
def group_line():
ncols = len('lintype ico delays'.split())
ncols = len('lintype,ico,delays'.split(','))
assert len(parts) == ncols
_lintype, ico, delays = parts
return int(ico), int(delays)
def net_line():
assert len(parts) == ncols
assert len(parts) == ncols, "Expected %u parts, got %u" % (
ncols, len(parts))
_lintype, net, src_site, src_site_type, src_site_pin, src_bel, src_bel_pin, dst_site, dst_site_type, dst_site_pin, dst_bel, dst_bel_pin, ico, fast_max, fast_min, slow_max, slow_min, pips, nodes, wires = parts
pips = pips.split('|')
nodes = nodes.split('|')
wires = wires.split('|')
return {
'net': net,
'src': {
@ -87,16 +103,16 @@ def gen_timing4(fn, speed_i2s):
'slow_min': int(slow_min),
},
'ico': int(ico),
'pips': [parse_pip(pip, speed_i2s) for pip in pips],
'nodes': [parse_node(node) for node in nodes],
'wires': [parse_wire(wire, speed_i2s) for wire in wires],
'pips': parse_pips(pips, speed_i2s),
'nodes': parse_nodes(nodes),
'wires': parse_wires(wires, speed_i2s),
'line': l,
}
l = l.strip()
if not l:
continue
parts = l.split(' ')
parts = l.split(',')
lintype = parts[0]
val = {
@ -180,67 +196,3 @@ def load_speed_json(f):
if i != SI_NONE:
speed_i2s[i] = k
return j, speed_i2s
'''
def run(speed_json_f, fout, fns_in, verbose=0, corner=None):
print('Loading data')
_speedj, speed_i2s = load_speed_json(speed_json_f)
fnout = open(fout, 'w')
vals = []
for fn_in in fns_in:
for j in load_timing4(fn_in, speed_i2s):
fnout.write(json.dumps(j) + '\n')
def main():
import argparse
parser = argparse.ArgumentParser(
description=
'Convert obscure timing4.txt into more readable but roughly equivilent timing4.json'
)
parser.add_argument('--verbose', type=int, help='')
# made a bulk conversion easier...keep?
parser.add_argument(
'--auto-name', action='store_true', help='timing4.txt => timing4i.csv')
parser.add_argument(
'--speed-json',
default='build_speed/speed.json',
help='Provides speed index to name translation')
parser.add_argument('--out', default=None, help='Output timing4i.csv file')
parser.add_argument('fns_in', nargs='+', help='Input timing4.txt files')
args = parser.parse_args()
bench = Benchmark()
fnout = args.out
if fnout is None:
if args.auto_name:
assert len(args.fns_in) == 1
fnin = args.fns_in[0]
fnout = fnin.replace('.txt', '.json')
assert fnout != fnin, 'Expect .txt in'
else:
# practically there are too many stray prints to make this work as expected
assert 0, 'File name required'
fnout = '/dev/stdout'
print("Writing to %s" % fnout)
fout = open(fnout, 'w')
fns_in = args.fns_in
if not fns_in:
fns_in = glob.glob('specimen_*/timing4.txt')
run(
speed_json_f=open(args.speed_json, 'r'),
fout=fout,
fns_in=fns_in,
verbose=args.verbose)
if __name__ == '__main__':
main()
'''