mirror of https://github.com/openXC7/prjxray.git
timfuz: timing.txt "," delim, line_net procs (cleanup + bug fix)
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
f023e0dcf0
commit
f4faa27243
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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('')
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
'''
|
||||
|
|
|
|||
Loading…
Reference in New Issue