prjxray/fuzzers/007-timing/timing_txt2scsv.py

168 lines
5.6 KiB
Python

#!/usr/bin/env python3
from timfuz import Benchmark, A_di2ds, sw_ei_vals2s, sw_eo_vals2s, sw_i_vals2s
from timing_txt2json import gen_timing4a, load_speed_json
import glob
import math
import json
import sys
from collections import OrderedDict
def gen_diffs(speed_json_f, fns_in):
print('Loading data')
_speedj, speed_i2s = load_speed_json(speed_json_f)
for fn_in in fns_in:
for val in gen_timing4a(fn_in, speed_i2s):
# diff to get site only delay
tsites = {}
for k in val['t'][0].keys():
v = val['t'][0][k] - val['t'][1][k]
assert v >= 0
tsites[k] = v
yield val, tsites
# XXX: move to json converter?
def sd_parts(sd):
'''Return site_type, site_pin, bel_type, bel_pin as non-prefixed strings'''
# IOB_X0Y106 IOB_X0Y106/INBUF_EN IOB_X0Y106/INBUF_EN/OUT
# print(sd['site'], sd['bel'], sd['bel_pin'])
site_type = sd['site_type']
site, bel_type, bel_pin = sd['bel_pin'].split('/')
assert sd['site'] == site
assert sd['bel'] == site + '/' + bel_type
site_pin_str = sd['site_pin']
if site_pin_str:
site, site_pin = sd['site_pin'].split('/')
assert sd['site_pin'] == sd['site'] + '/' + site_pin
else:
site_pin = None
return site_type, site_pin, bel_type, bel_pin
def run(speed_json_f, fout, fns_in, verbose=0, corner=None):
'''
instead of writing to a simplified csv, lets just go directly to a delay format identical to what fabric uses
Path types:
-inter site: think these are removed for now?
1 model
NOTE: be careful of a net that goes external and comes back in, which isn't inter site
definition is that it doesn't have any site pins
-intra site
2 models
'''
fout.write(
'ico,fast_max fast_min slow_max slow_min,src_site_type,src_site,src_bel,src_bel_pin,dst_site_type,dst_site,dst_bel,dst_bel_pin\n'
)
for val, tsites in gen_diffs(speed_json_f, fns_in):
def mkb(t):
return (t['fast_max'], t['fast_min'], t['slow_max'], t['slow_min'])
bstr = ' '.join([str(x) for x in mkb(tsites)])
# Identify inter site transaction (SITEI)
if not val['src']['site_pin'] and not val['dst']['site_pin']:
# add one delay model for the path
# XXX: can these be solved exactly?
# might still have fanout and such
src_site_type, _src_site_pin, src_bel_type, src_bel_pin = sd_parts(
val['src'])
dst_site_type, _dst_site_pin, dst_bel_type, dst_bel_pin = sd_parts(
val['dst'])
assert src_site_type == dst_site_type
assert (src_bel_type, src_bel_pin) != (dst_bel_type, dst_bel_pin)
k = sw_i_vals2s(
src_site_type, src_bel_type, src_bel_pin, dst_bel_type,
dst_bel_pin)
row_ds = {k: 1}
elif val['src']['site_pin'] and val['dst']['site_pin']:
# if it exits a site it should enter another (possibly the same site)
# site in (SITEI) or site out (SITEO)?
# nah, keep things simple and just call them SITEW
row_ds = {}
def add_dst_delay():
sd = val['dst']
site_type, src_site_pin, dst_bel, dst_bel_pin = sd_parts(sd)
k = sw_ei_vals2s(site_type, src_site_pin, dst_bel, dst_bel_pin)
assert k not in row_ds
row_ds[k] = 1
def add_src_delay():
sd = val['src']
site_type, dst_site_pin, src_bel, src_bel_pin = sd_parts(sd)
k = sw_eo_vals2s(site_type, src_bel, src_bel_pin, dst_site_pin)
assert k not in row_ds
row_ds[k] = 1
add_dst_delay()
add_src_delay()
else:
# dropped by the tcl script
raise Exception("FIXME: handle destination but no source")
row_ico = 0
items = [str(row_ico), bstr]
for k, v in sorted(row_ds.items()):
items.append('%u %s' % (v, k))
fout.write(','.join(items) + '\n')
print('done')
def main():
import argparse
parser = argparse.ArgumentParser(
description=
'Convert obscure timing4.txt into timing4s.csv (site delay variable occurances)'
)
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', 's.csv')
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()