misc cleanup

Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
John McMaster 2018-09-17 15:40:27 -07:00
parent d5c9f1d857
commit b6b9d9a661
15 changed files with 114 additions and 96 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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='')

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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__':

View File

@ -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))

View File

@ -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

View File

@ -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)

View File

@ -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