mirror of https://github.com/openXC7/prjxray.git
timfuz: build all four corners
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
2dbe379200
commit
e148ed5f91
|
|
@ -0,0 +1,42 @@
|
||||||
|
# Run corner specific calculations
|
||||||
|
|
||||||
|
TIMFUZ_DIR=$(XRAY_DIR)/fuzzers/007-timing
|
||||||
|
CORNER=slow_max
|
||||||
|
|
||||||
|
all: build/$(CORNER)/tilea.json
|
||||||
|
|
||||||
|
run:
|
||||||
|
$(MAKE) clean
|
||||||
|
$(MAKE) all
|
||||||
|
touch run.ok
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf specimen_[0-9][0-9][0-9]/ seg_clblx.segbits __pycache__ run.ok
|
||||||
|
rm -rf vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit
|
||||||
|
rm -rf build
|
||||||
|
|
||||||
|
.PHONY: all run clean
|
||||||
|
|
||||||
|
build/$(CORNER):
|
||||||
|
mkdir build/$(CORNER)
|
||||||
|
|
||||||
|
build/$(CORNER)/leastsq.csv: build/sub.json build/grouped.csv build/checksub build/$(CORNER)
|
||||||
|
# Create a rough timing model that approximately fits the given paths
|
||||||
|
python3 $(TIMFUZ_DIR)/solve_leastsq.py --sub-json build/sub.json build/grouped.csv --corner $(CORNER) --out build/$(CORNER)/leastsq.csv.tmp
|
||||||
|
mv build/$(CORNER)/leastsq.csv.tmp build/$(CORNER)/leastsq.csv
|
||||||
|
|
||||||
|
build/$(CORNER)/linprog.csv: build/$(CORNER)/leastsq.csv build/grouped.csv
|
||||||
|
# Tweak rough timing model, making sure all constraints are satisfied
|
||||||
|
python3 $(TIMFUZ_DIR)/solve_linprog.py --sub-json build/sub.json --sub-csv build/$(CORNER)/leastsq.csv --massage build/grouped.csv --corner $(CORNER) --out build/$(CORNER)/linprog.csv.tmp
|
||||||
|
mv build/$(CORNER)/linprog.csv.tmp build/$(CORNER)/linprog.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 build/$(CORNER)/linprog.csv build/$(CORNER)/flat.csv.tmp
|
||||||
|
mv build/$(CORNER)/flat.csv.tmp build/$(CORNER)/flat.csv
|
||||||
|
|
||||||
|
build/$(CORNER)/tilea.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
|
||||||
|
|
||||||
|
|
@ -1,11 +1,30 @@
|
||||||
|
# project.mk: build specimens (run vivado), compute rref
|
||||||
|
# corner.mk: run corner specific calculations
|
||||||
|
|
||||||
N := 1
|
N := 1
|
||||||
SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N)))
|
SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N)))
|
||||||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||||
CSVS := $(addsuffix /timing3.csv,$(SPECIMENS))
|
CSVS := $(addsuffix /timing3.csv,$(SPECIMENS))
|
||||||
TIMFUZ_DIR=$(XRAY_DIR)/fuzzers/007-timing
|
TIMFUZ_DIR=$(XRAY_DIR)/fuzzers/007-timing
|
||||||
CORNER=slow_max
|
RREF_CORNER=slow_max
|
||||||
|
|
||||||
all: build/tilea.json
|
TILEA_JSONS=build/fast_max/tilea.json build/fast_min/tilea.json build/slow_max/tilea.json build/slow_min/tilea.json
|
||||||
|
|
||||||
|
all: $(TILEA_JSONS)
|
||||||
|
|
||||||
|
# make build/checksub first
|
||||||
|
build/fast_max/tilea.json: build/checksub
|
||||||
|
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=fast_max
|
||||||
|
build/fast_min/tilea.json: build/checksub
|
||||||
|
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=fast_min
|
||||||
|
build/slow_max/tilea.json: build/checksub
|
||||||
|
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=slow_max
|
||||||
|
build/slow_min/tilea.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):
|
$(SPECIMENS_OK):
|
||||||
bash generate.sh $(subst /OK,,$@)
|
bash generate.sh $(subst /OK,,$@)
|
||||||
|
|
@ -21,13 +40,15 @@ clean:
|
||||||
rm -rf vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit
|
rm -rf vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit
|
||||||
rm -rf build
|
rm -rf build
|
||||||
|
|
||||||
.PHONY: database pushdb run clean
|
.PHONY: all run clean
|
||||||
|
|
||||||
|
# rref should be the same regardless of corner
|
||||||
|
|
||||||
build/sub.json: $(SPECIMENS_OK)
|
build/sub.json: $(SPECIMENS_OK)
|
||||||
mkdir -p build
|
mkdir -p build
|
||||||
# Discover which variables can be separated
|
# Discover which variables can be separated
|
||||||
# This is typically the longest running operation
|
# This is typically the longest running operation
|
||||||
python3 $(TIMFUZ_DIR)/rref.py --corner $(CORNER) --simplify --out build/sub.json.tmp $(CSVS)
|
python3 $(TIMFUZ_DIR)/rref.py --corner $(RREF_CORNER) --simplify --out build/sub.json.tmp $(CSVS)
|
||||||
mv build/sub.json.tmp build/sub.json
|
mv build/sub.json.tmp build/sub.json
|
||||||
|
|
||||||
build/grouped.csv: $(SPECIMENS_OK) build/sub.json
|
build/grouped.csv: $(SPECIMENS_OK) build/sub.json
|
||||||
|
|
@ -40,23 +61,3 @@ build/checksub: build/grouped.csv build/sub.json
|
||||||
python3 $(TIMFUZ_DIR)/checksub.py --sub-json build/sub.json build/grouped.csv
|
python3 $(TIMFUZ_DIR)/checksub.py --sub-json build/sub.json build/grouped.csv
|
||||||
touch build/checksub
|
touch build/checksub
|
||||||
|
|
||||||
build/leastsq.csv: build/sub.json build/grouped.csv build/checksub
|
|
||||||
# Create a rough timing model that approximately fits the given paths
|
|
||||||
python3 $(TIMFUZ_DIR)/solve_leastsq.py --sub-json build/sub.json build/grouped.csv --corner $(CORNER) --out build/leastsq.csv.tmp
|
|
||||||
mv build/leastsq.csv.tmp build/leastsq.csv
|
|
||||||
|
|
||||||
build/linprog.csv: build/leastsq.csv build/grouped.csv
|
|
||||||
# Tweak rough timing model, making sure all constraints are satisfied
|
|
||||||
python3 $(TIMFUZ_DIR)/solve_linprog.py --sub-json build/sub.json --sub-csv build/leastsq.csv --massage build/grouped.csv --corner $(CORNER) --out build/linprog.csv.tmp
|
|
||||||
mv build/linprog.csv.tmp build/linprog.csv
|
|
||||||
|
|
||||||
build/flat.csv: build/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 build/linprog.csv build/flat.csv.tmp
|
|
||||||
mv build/flat.csv.tmp build/flat.csv
|
|
||||||
|
|
||||||
build/tilea.json: build/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/flat.csv build/tilea.json
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import os
|
||||||
import time
|
import time
|
||||||
import timfuz_solve
|
import timfuz_solve
|
||||||
|
|
||||||
def save(outfn, res, names, corner):
|
def save(outfn, xvals, names, corner):
|
||||||
# ballpark minimum actual observed delay is around 7 (carry chain)
|
# ballpark minimum actual observed delay is around 7 (carry chain)
|
||||||
# anything less than one is probably a solver artifact
|
# anything less than one is probably a solver artifact
|
||||||
delta = 0.5
|
delta = 0.5
|
||||||
|
|
@ -24,7 +24,7 @@ def save(outfn, res, names, corner):
|
||||||
# write as one variable per line
|
# write as one variable per line
|
||||||
# this natively forms a bound if fed into linprog solver
|
# this natively forms a bound if fed into linprog solver
|
||||||
fout.write('ico,fast_max fast_min slow_max slow_min,rows...\n')
|
fout.write('ico,fast_max fast_min slow_max slow_min,rows...\n')
|
||||||
for xval, name in zip(res.x, names):
|
for xval, name in zip(xvals, names):
|
||||||
row_ico = 1
|
row_ico = 1
|
||||||
|
|
||||||
# FIXME: only report for the given corner?
|
# FIXME: only report for the given corner?
|
||||||
|
|
@ -40,6 +40,12 @@ def save(outfn, res, names, corner):
|
||||||
print('Wrote: zeros %u => %u / %u constrained delays' % (zeros, len(names) - zeros, len(names)))
|
print('Wrote: zeros %u => %u / %u constrained delays' % (zeros, len(names) - zeros, len(names)))
|
||||||
|
|
||||||
def run_corner(Anp, b, names, corner, verbose=False, opts={}, meta={}, outfn=None):
|
def run_corner(Anp, b, names, corner, verbose=False, opts={}, meta={}, outfn=None):
|
||||||
|
if len(Anp) == 0:
|
||||||
|
print('WARNING: zero equations')
|
||||||
|
if outfn:
|
||||||
|
save(outfn, [], [], corner)
|
||||||
|
return
|
||||||
|
|
||||||
# Given timing scores for above delays (-ps)
|
# Given timing scores for above delays (-ps)
|
||||||
assert type(Anp[0]) is np.ndarray, type(Anp[0])
|
assert type(Anp[0]) is np.ndarray, type(Anp[0])
|
||||||
assert type(b) is np.ndarray, type(b)
|
assert type(b) is np.ndarray, type(b)
|
||||||
|
|
@ -126,7 +132,7 @@ def run_corner(Anp, b, names, corner, verbose=False, opts={}, meta={}, outfn=Non
|
||||||
print('Delay on %d / %d' % (nonzeros, len(res.x)))
|
print('Delay on %d / %d' % (nonzeros, len(res.x)))
|
||||||
|
|
||||||
if outfn:
|
if outfn:
|
||||||
save(outfn, res, names, corner)
|
save(outfn, res.x, names, corner)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
import argparse
|
import argparse
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,10 @@ corner_s2i = OrderedDict([
|
||||||
('slow_min', 3),
|
('slow_min', 3),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
# Equations are filtered out until nothing is left
|
||||||
|
class SimplifiedToZero(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
def print_eqns(A_ubd, b_ub, verbose=0, lim=3, label=''):
|
def print_eqns(A_ubd, b_ub, verbose=0, lim=3, label=''):
|
||||||
rows = len(b_ub)
|
rows = len(b_ub)
|
||||||
|
|
||||||
|
|
@ -172,6 +176,8 @@ def simplify_rows(Ads, b_ub, remove_zd=False, corner=None):
|
||||||
eqns[rowt] = minmax(eqns.get(rowt, 0), b)
|
eqns[rowt] = minmax(eqns.get(rowt, 0), b)
|
||||||
|
|
||||||
print(' done')
|
print(' done')
|
||||||
|
if len(eqns) == 0:
|
||||||
|
raise SimplifiedToZero()
|
||||||
|
|
||||||
#A_ub_ret = eqns.keys()
|
#A_ub_ret = eqns.keys()
|
||||||
A_ubd_ret, b_ub_ret = Ab_ub_dt2d(eqns)
|
A_ubd_ret, b_ub_ret = Ab_ub_dt2d(eqns)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.linprog.html
|
# https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.linprog.html
|
||||||
from scipy.optimize import linprog
|
from scipy.optimize import linprog
|
||||||
from timfuz import Benchmark, Ar_di2np, Ar_ds2t, A_di2ds, A_ds2di, simplify_rows, loadc_Ads_b, index_names, A_ds2np, load_sub, run_sub_json, A_ub_np2d, print_eqns, print_eqns_np, Ads2bounds, instances
|
from timfuz import Benchmark, simplify_rows, loadc_Ads_b, index_names, A_ds2np, run_sub_json, print_eqns, Ads2bounds, instances, SimplifiedToZero
|
||||||
from timfuz_massage import massage_equations
|
from timfuz_massage import massage_equations
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import glob
|
import glob
|
||||||
|
|
@ -139,7 +139,12 @@ def run(fns_in, corner, run_corner, sub_json=None, sub_csv=None, dedup=True, mas
|
||||||
This creates derived constraints to provide more realistic results
|
This creates derived constraints to provide more realistic results
|
||||||
'''
|
'''
|
||||||
if massage:
|
if massage:
|
||||||
Ads, b = massage_equations(Ads, b, corner=corner)
|
try:
|
||||||
|
Ads, b = massage_equations(Ads, b, corner=corner)
|
||||||
|
except SimplifiedToZero:
|
||||||
|
print('WARNING: simplified to zero equations')
|
||||||
|
Ads = []
|
||||||
|
b = []
|
||||||
|
|
||||||
print('Converting to numpy...')
|
print('Converting to numpy...')
|
||||||
names, Anp = A_ds2np(Ads)
|
names, Anp = A_ds2np(Ads)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue