mirror of https://github.com/openXC7/prjxray.git
misc cleanup
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
d5c9f1d857
commit
b6b9d9a661
|
|
@ -3,13 +3,13 @@
|
|||
PRJ?=picorv32
|
||||
PRJN?=8
|
||||
|
||||
all: build/tilea.json
|
||||
all: build/timgrid-v.json
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
cd speed && $(MAKE) clean
|
||||
cd timgrid && $(MAKE) clean
|
||||
cd projects && $(MAKE) clean
|
||||
cd projects/$(PRJ) && $(MAKE) clean
|
||||
|
||||
speed/build/speed.json:
|
||||
cd speed && $(MAKE)
|
||||
|
|
@ -17,10 +17,10 @@ speed/build/speed.json:
|
|||
timgrid/build/timgrid.json:
|
||||
cd timgrid && $(MAKE)
|
||||
|
||||
build/tilea.json: projects/$(PRJ)/build/tilea.json
|
||||
build/timgrid-v.json: projects/$(PRJ)/build/timgrid-v.json
|
||||
mkdir -p build
|
||||
cp projects/$(PRJ)/build/tilea.json build/tilea.json
|
||||
cp projects/$(PRJ)/build/timgrid-v.json build/timgrid-v.json
|
||||
|
||||
projects/$(PRJ)/build/tilea.json: speed/build/speed.json timgrid/build/timgrid.json
|
||||
projects/$(PRJ)/build/timgrid-v.json: speed/build/speed.json timgrid/build/timgrid.json
|
||||
cd projects/$(PRJ) && $(MAKE) N=$(PRJN)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,15 @@ Currently this document focuses exclusively on fabric timing delays.
|
|||
## Quick start
|
||||
|
||||
```
|
||||
make
|
||||
make -j$(nproc)
|
||||
```
|
||||
|
||||
This will take a relatively long time (say 45 min) and generate build/tilea.json
|
||||
This will take a relatively long time (say 45 min) and generate build/timgrid-v.json.
|
||||
You can do a quicker test run (say 3 min) using:
|
||||
|
||||
```
|
||||
make PRJ=oneblinkw PRJN=1 -j$(nproc)
|
||||
```
|
||||
|
||||
|
||||
## Vivado background
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ def pds(Ads, s):
|
|||
|
||||
|
||||
def run(fns_in, sub_json=None, verbose=False):
|
||||
assert len(fn_ins) > 0
|
||||
assert len(fns_in) > 0
|
||||
# arbitrary corner...data is thrown away
|
||||
Ads, b = loadc_Ads_b(fns_in, "slow_max", ico=True)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ def main():
|
|||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Substitute .csv to group correlated symbols')
|
||||
description='Substitute .csv to group correlated variables')
|
||||
|
||||
parser.add_argument('--verbose', action='store_true', help='')
|
||||
parser.add_argument('--strict', action='store_true', help='')
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
from timfuz import Benchmark, loadc_Ads_bs, load_sub, Ads2bounds, corners2csv, corner_s2i
|
||||
|
||||
|
||||
def gen_flat(fnin, sub_json, corner=None):
|
||||
Ads, bs = loadc_Ads_bs([fnin], ico=True)
|
||||
def gen_flat(fns_in, sub_json, corner=None):
|
||||
Ads, bs = loadc_Ads_bs(fns_in, ico=True)
|
||||
bounds = Ads2bounds(Ads, bs)
|
||||
zeros = set()
|
||||
nonzeros = set()
|
||||
|
|
@ -49,20 +49,19 @@ def run(fns_in, fnout, sub_json, corner=None, sort=False, verbose=False):
|
|||
|
||||
with open(fnout, 'w') as fout:
|
||||
fout.write('ico,fast_max fast_min slow_max slow_min,rows...\n')
|
||||
for fnin in fns_in:
|
||||
#for name, corners in sortf(gen_flat(fnin, sub_json)):
|
||||
for name, corners in gen_flat(fnin, sub_json, corner=corner):
|
||||
row_ico = 1
|
||||
items = [str(row_ico), corners2csv(corners)]
|
||||
items.append('%u %s' % (1, name))
|
||||
fout.write(','.join(items) + '\n')
|
||||
#for name, corners in sortf(gen_flat(fnin, sub_json)):
|
||||
for name, corners in gen_flat(fns_in, sub_json, corner=corner):
|
||||
row_ico = 1
|
||||
items = [str(row_ico), corners2csv(corners)]
|
||||
items.append('%u %s' % (1, name))
|
||||
fout.write(','.join(items) + '\n')
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Substitute .csv to ungroup correlated symbols')
|
||||
description='Substitute .csv to ungroup correlated variables')
|
||||
|
||||
parser.add_argument('--verbose', action='store_true', help='')
|
||||
#parser.add_argument('--sort', action='store_true', help='')
|
||||
|
|
@ -75,7 +74,7 @@ def main():
|
|||
parser.add_argument('--out', default=None, help='output timing delay .csv')
|
||||
parser.add_argument(
|
||||
'fns_in',
|
||||
default=None,
|
||||
nargs='+',
|
||||
help='input timing delay .csv (NOTE: must be single column)')
|
||||
args = parser.parse_args()
|
||||
# Store options in dict to ease passing through functions
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ CORNER=slow_max
|
|||
ALLOW_ZERO_EQN?=N
|
||||
BADPRJ_OK?=N
|
||||
|
||||
all: build/$(CORNER)/tilea.json
|
||||
all: build/$(CORNER)/timgrid-s.json
|
||||
|
||||
run:
|
||||
$(MAKE) clean
|
||||
|
|
@ -37,11 +37,11 @@ build/$(CORNER)/linprog.csv: build/$(CORNER)/leastsq.csv build/grouped.csv
|
|||
|
||||
build/$(CORNER)/flat.csv: build/$(CORNER)/linprog.csv
|
||||
# Take separated variables and back-annotate them to the original timing variables
|
||||
python3 $(TIMFUZ_DIR)/csv_group2flat.py --sub-json build/sub.json --corner $(CORNER) --sort --out build/$(CORNER)/flat.csv.tmp build/$(CORNER)/linprog.csv
|
||||
python3 $(TIMFUZ_DIR)/csv_group2flat.py --sub-json build/sub.json --corner $(CORNER) --out build/$(CORNER)/flat.csv.tmp build/$(CORNER)/linprog.csv
|
||||
mv build/$(CORNER)/flat.csv.tmp build/$(CORNER)/flat.csv
|
||||
|
||||
build/$(CORNER)/tilea.json: build/$(CORNER)/flat.csv
|
||||
build/$(CORNER)/timgrid-s.json: build/$(CORNER)/flat.csv
|
||||
# Final processing
|
||||
# Insert timing delays into actual tile layouts
|
||||
python3 $(TIMFUZ_DIR)/tile_annotate.py --tile-json $(TIMFUZ_DIR)/timgrid/build/timgrid.json build/$(CORNER)/flat.csv build/$(CORNER)/tilea.json
|
||||
python3 $(TIMFUZ_DIR)/tile_annotate.py --timgrid-s $(TIMFUZ_DIR)/timgrid/build/timgrid-s.json --out build/$(CORNER)/timgrid-vc.json build/$(CORNER)/flat.csv
|
||||
|
||||
|
|
|
|||
|
|
@ -10,23 +10,19 @@ RREF_CORNER=slow_max
|
|||
ALLOW_ZERO_EQN?=N
|
||||
BADPRJ_OK?=N
|
||||
|
||||
TILEA_JSONS=build/fast_max/tilea.json build/fast_min/tilea.json build/slow_max/tilea.json build/slow_min/tilea.json
|
||||
TIMGRID_VCS=build/fast_max/timgrid-vc.json build/fast_min/timgrid-vc.json build/slow_max/timgrid-vc.json build/slow_min/timgrid-vc.json
|
||||
|
||||
all: build/tilea.json
|
||||
all: build/timgrid-v.json
|
||||
|
||||
# make build/checksub first
|
||||
build/fast_max/tilea.json: build/checksub
|
||||
build/fast_max/timgrid-vc.json: build/checksub
|
||||
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=fast_max
|
||||
build/fast_min/tilea.json: build/checksub
|
||||
build/fast_min/timgrid-vc.json: build/checksub
|
||||
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=fast_min
|
||||
build/slow_max/tilea.json: build/checksub
|
||||
build/slow_max/timgrid-vc.json: build/checksub
|
||||
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=slow_max
|
||||
build/slow_min/tilea.json: build/checksub
|
||||
build/slow_min/timgrid-vc.json: build/checksub
|
||||
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=slow_min
|
||||
fast_max: build/fast_max/tilea.json
|
||||
fast_min: build/fast_min/tilea.json
|
||||
slow_max: build/slow_max/tilea.json
|
||||
slow_min: build/slow_min/tilea.json
|
||||
|
||||
$(SPECIMENS_OK):
|
||||
bash generate.sh $(subst /OK,,$@) || (if [ "$(BADPRJ_OK)" != 'Y' ] ; then exit 1; fi; exit 0)
|
||||
|
|
@ -76,6 +72,6 @@ build/checksub: build/grouped.csv build/sub.json
|
|||
python3 $(TIMFUZ_DIR)/checksub.py --sub-json build/sub.json build/grouped.csv
|
||||
touch build/checksub
|
||||
|
||||
build/tilea.json: $(TILEA_JSONS)
|
||||
python3 $(TIMFUZ_DIR)/tile_combine.py --out build/tilea.json $(TILEA_JSONS)
|
||||
build/timgrid-v.json: $(TIMGRID_VCS)
|
||||
python3 $(TIMFUZ_DIR)/timgrid_vc2v.py --out build/timgrid-v.json $(TIMGRID_VCS)
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class State(object):
|
|||
# known zero delay elements
|
||||
self.drop_names = set(drop_names)
|
||||
# active names in rows
|
||||
# includes sub symbols, excludes symbols that have been substituted out
|
||||
# includes sub variables, excludes variables that have been substituted out
|
||||
self.base_names = set(self.names)
|
||||
self.names = set(self.base_names)
|
||||
# List of variable substitutions
|
||||
|
|
@ -173,10 +173,10 @@ def state_rref(state, verbose=False):
|
|||
rowdsf = row_sym2dsf(rowsym, names)
|
||||
|
||||
state.subs[group_name] = rowdsf
|
||||
# Add the new symbol
|
||||
# Add the new variables
|
||||
state.names.add(group_name)
|
||||
# Remove substituted symbols
|
||||
# Note: symbols may appear multiple times
|
||||
# Remove substituted variables
|
||||
# Note: variables may appear multiple times
|
||||
state.names.difference_update(set(rowdsf.keys()))
|
||||
pivot_name = names[row_pivot]
|
||||
state.pivots[group_name] = pivot_name
|
||||
|
|
|
|||
|
|
@ -160,11 +160,15 @@ def main():
|
|||
parser.add_argument('--corner', required=True, default="slow_max", help='')
|
||||
parser.add_argument(
|
||||
'--out', default=None, help='output timing delay .json')
|
||||
parser.add_argument('fns_in', nargs='+', 'timing3.csv input files')
|
||||
parser.add_argument('fns_in', nargs='+', help='timing3.csv input files')
|
||||
args = parser.parse_args()
|
||||
# Store options in dict to ease passing through functions
|
||||
bench = Benchmark()
|
||||
|
||||
fns_in = args.fns_in
|
||||
if not fns_in:
|
||||
fns_in = glob.glob('specimen_*/timing3.csv')
|
||||
|
||||
sub_json = None
|
||||
if args.sub_json:
|
||||
sub_json = load_sub(args.sub_json)
|
||||
|
|
@ -173,7 +177,7 @@ def main():
|
|||
timfuz_solve.run(
|
||||
run_corner=run_corner,
|
||||
sub_json=sub_json,
|
||||
fns_in=args.fns_in,
|
||||
fns_in=fns_in,
|
||||
corner=args.corner,
|
||||
massage=args.massage,
|
||||
outfn=args.out,
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ def main():
|
|||
run_corner=run_corner,
|
||||
sub_json=sub_json,
|
||||
sub_csv=args.sub_csv,
|
||||
fn_in=fn_in,
|
||||
fns_in=fns_in,
|
||||
corner=args.corner,
|
||||
massage=args.massage,
|
||||
outfn=args.out,
|
||||
|
|
|
|||
|
|
@ -9,50 +9,24 @@ import time
|
|||
import json
|
||||
|
||||
|
||||
def run(fnin, fnout, tile_json_fn, verbose=False):
|
||||
def run(fns_in, fnout, tile_json_fn, verbose=False):
|
||||
# modified in place
|
||||
tilej = json.load(open(tile_json_fn, 'r'))
|
||||
|
||||
Ads, bs = loadc_Ads_bs([fnin], ico=True)
|
||||
bounds = Ads2bounds(Ads, bs)
|
||||
for fnin in fns_in:
|
||||
Ads, bs = loadc_Ads_bs([fnin], ico=True)
|
||||
bounds = Ads2bounds(Ads, bs)
|
||||
|
||||
pipn_net = 0
|
||||
pipn_solved = [0, 0, 0, 0]
|
||||
pipn_covered = [0, 0, 0, 0]
|
||||
wiren_net = 0
|
||||
wiren_solved = [0, 0, 0, 0]
|
||||
wiren_covered = [0, 0, 0, 0]
|
||||
for tile in tilej['tiles'].values():
|
||||
pips = tile['pips']
|
||||
for k, v in pips.items():
|
||||
pips[k] = bounds.get('PIP_' + v, [None, None, None, None])
|
||||
|
||||
for tile in tilej['tiles'].values():
|
||||
pips = tile['pips']
|
||||
for k, v in pips.items():
|
||||
pips[k] = bounds.get('PIP_' + v, [None, None, None, None])
|
||||
pipn_net += 1
|
||||
for i in range(4):
|
||||
if pips[k][i]:
|
||||
pipn_solved[i] += 1
|
||||
if pips[k][i] is not None:
|
||||
pipn_covered[i] += 1
|
||||
wires = tile['wires']
|
||||
for k, v in wires.items():
|
||||
wires[k] = bounds.get('WIRE_' + v, [None, None, None, None])
|
||||
|
||||
wires = tile['wires']
|
||||
for k, v in wires.items():
|
||||
wires[k] = bounds.get('WIRE_' + v, [None, None, None, None])
|
||||
wiren_net += 1
|
||||
for i in range(4):
|
||||
if wires[k][i]:
|
||||
wiren_solved[i] += 1
|
||||
if wires[k][i] is not None:
|
||||
wiren_covered[i] += 1
|
||||
|
||||
for corner, corneri in timfuz.corner_s2i.items():
|
||||
print('Corner %s' % corner)
|
||||
print(
|
||||
' Pips: %u / %u solved, %u / %u covered' %
|
||||
(pipn_solved[corneri], pipn_net, pipn_covered[corneri], pipn_net))
|
||||
print(
|
||||
' Wires: %u / %u solved, %u / %u covered' % (
|
||||
wiren_solved[corneri], wiren_net, wiren_covered[corneri],
|
||||
wiren_net))
|
||||
timfuz.tilej_stats(tilej)
|
||||
|
||||
json.dump(
|
||||
tilej,
|
||||
|
|
@ -68,13 +42,19 @@ def main():
|
|||
parser = argparse.ArgumentParser(
|
||||
description=
|
||||
'Substitute timgrid timing model names for real timing values')
|
||||
parser.add_argument('--tile-json', default='tiles.json', help='')
|
||||
parser.add_argument(
|
||||
'fnin', default=None, help='Input flattened timing csv (flat.json)')
|
||||
parser.add_argument('fnout', default=None, help='output tile .json')
|
||||
'--timgrid-s',
|
||||
default='../../timgrid/build/timgrid-s.json',
|
||||
help='tilegrid timing delay symbolic input (timgrid-s.json)')
|
||||
parser.add_argument(
|
||||
'--out',
|
||||
default='build/timgrid-vc.json',
|
||||
help='tilegrid timing delay values at corner (timgrid-vc.json)')
|
||||
parser.add_argument(
|
||||
'fn_ins', nargs='+', help='Input flattened timing csv (flat.json)')
|
||||
args = parser.parse_args()
|
||||
|
||||
run(args.fnin, args.fnout, args.tile_json, verbose=False)
|
||||
run(args.fn_ins, args.out, args.timgrid_s, verbose=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
|
|
@ -665,20 +665,20 @@ def load_sub(fn):
|
|||
return j
|
||||
|
||||
|
||||
def row_sub_syms(row, sub_json, strict=False, verbose=False):
|
||||
def row_sub_vars(row, sub_json, strict=False, verbose=False):
|
||||
if 0 and verbose:
|
||||
print("")
|
||||
print(row.items())
|
||||
|
||||
delsyms = 0
|
||||
delvars = 0
|
||||
for k in sub_json['drop_names']:
|
||||
try:
|
||||
del row[k]
|
||||
delsyms += 1
|
||||
delvars += 1
|
||||
except KeyError:
|
||||
pass
|
||||
if verbose:
|
||||
print("Deleted %u symbols" % delsyms)
|
||||
print("Deleted %u variables" % delvars)
|
||||
|
||||
if verbose:
|
||||
print('Checking pivots')
|
||||
|
|
@ -750,7 +750,7 @@ def run_sub_json(Ads, sub_json, strict=False, verbose=False):
|
|||
print('Row %u w/ %u elements' % (rowi, len(row)))
|
||||
|
||||
row_orig = dict(row)
|
||||
row_sub_syms(row, sub_json, strict=strict, verbose=verbose)
|
||||
row_sub_vars(row, sub_json, strict=strict, verbose=verbose)
|
||||
nrows += 1
|
||||
if row_orig != row:
|
||||
nsubs += 1
|
||||
|
|
@ -817,3 +817,33 @@ def corners2csv(bs):
|
|||
assert len(bs) == 4
|
||||
corners = ["None" if b is None else str(b) for b in bs]
|
||||
return ' '.join(corners)
|
||||
|
||||
|
||||
def tilej_stats(tilej):
|
||||
stats = {}
|
||||
for etype in ('pips', 'wires'):
|
||||
tm = stats.setdefault(etype, {})
|
||||
tm['net'] = 0
|
||||
tm['solved'] = [0, 0, 0, 0]
|
||||
tm['covered'] = [0, 0, 0, 0]
|
||||
|
||||
for tile in tilej['tiles'].values():
|
||||
for etype in ('pips', 'wires'):
|
||||
pips = tile[etype]
|
||||
for k, v in pips.items():
|
||||
stats[etype]['net'] += 1
|
||||
for i in range(4):
|
||||
if pips[k][i]:
|
||||
stats[etype]['solved'][i] += 1
|
||||
if pips[k][i] is not None:
|
||||
stats[etype]['covered'][i] += 1
|
||||
|
||||
for corner, corneri in corner_s2i.items():
|
||||
print('Corner %s' % corner)
|
||||
for etype in ('pips', 'wires'):
|
||||
net = stats[etype]['net']
|
||||
solved = stats[etype]['solved'][corneri]
|
||||
covered = stats[etype]['covered'][corneri]
|
||||
print(
|
||||
' %s: %u / %u solved, %u / %u covered' %
|
||||
(etype, solved, net, covered, net))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ build/timgrid.txt: generate.tcl
|
|||
cd build && vivado -mode batch -source ../generate.tcl
|
||||
|
||||
build/timgrid.json: build/timgrid.txt
|
||||
cd build && python3 ../tile_txt2json.py --speed-json ../../speed/build/speed.json timgrid.txt timgrid.json
|
||||
cd build && python3 ../tile_txt2json.py --speed-json ../../speed/build/speed.json timgrid.txt timgrid-s.json
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import os
|
|||
import time
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
import timfuz
|
||||
|
||||
corner_s2i = OrderedDict(
|
||||
[
|
||||
|
|
@ -77,6 +78,7 @@ def check_corner_minmax(tilej, verbose=False):
|
|||
print('Checking for min/max consistency')
|
||||
checks = 0
|
||||
bad = 0
|
||||
|
||||
for tilev in tilej['tiles'].values():
|
||||
|
||||
def process_type(etype):
|
||||
|
|
@ -102,7 +104,10 @@ def check_corner_minmax(tilej, verbose=False):
|
|||
|
||||
process_type('pips')
|
||||
process_type('wires')
|
||||
print('minmax: %u / %u bad' % (bad, checks))
|
||||
|
||||
print('')
|
||||
print('minmax: %u / %u pairs bad pairs adjusted' % (bad, checks))
|
||||
timfuz.tilej_stats(tilej)
|
||||
|
||||
|
||||
def check_corners_minmax(tilej, verbose=False):
|
||||
|
|
@ -127,8 +132,9 @@ def main():
|
|||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Combine multiple tile corners into one .json file')
|
||||
parser.add_argument('--out', required=True, help='Combined .json file')
|
||||
parser.add_argument('fnins', nargs='+', help='Input .json files')
|
||||
parser.add_argument(
|
||||
'--out', required=True, help='Combined timgrid-v.json files')
|
||||
parser.add_argument('fnins', nargs='+', help='Input timgrid-vc.json files')
|
||||
args = parser.parse_args()
|
||||
|
||||
run(args.fnins, args.out, verbose=False)
|
||||
|
|
@ -1,11 +1,9 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from timfuz import Benchmark, A_di2ds
|
||||
import numpy as np
|
||||
import glob
|
||||
import math
|
||||
import json
|
||||
import sympy
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue