mirror of https://github.com/openXC7/prjxray.git
timfuz: combine tile process corners
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
2a28dabf02
commit
c104e70724
|
|
@ -1,5 +1,26 @@
|
|||
all:
|
||||
cd speed && make
|
||||
cd timgrid && make
|
||||
cd projects && make
|
||||
# for now hammering on just picorv32
|
||||
# consider instead aggregating multiple projects
|
||||
PRJ?=picorv32
|
||||
PRJN?=8
|
||||
|
||||
all: build/tilea.json
|
||||
|
||||
clean:
|
||||
rm -rf build
|
||||
cd speed && $(MAKE) clean
|
||||
cd timgrid && $(MAKE) clean
|
||||
cd projects && $(MAKE) clean
|
||||
|
||||
speed/build/speed.json:
|
||||
cd speed && $(MAKE)
|
||||
|
||||
timgrid/build/timgrid.json:
|
||||
cd timgrid && $(MAKE)
|
||||
|
||||
build/tilea.json: projects/$(PRJ)/build/tilea.json
|
||||
mkdir -p build
|
||||
cp projects/$(PRJ)/build/tilea.json build/tilea.json
|
||||
|
||||
projects/$(PRJ)/build/tilea.json: speed/build/speed.json timgrid/build/timgrid.json
|
||||
cd projects/$(PRJ) && $(MAKE) N=$(PRJN)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,19 +13,11 @@ Currently this document focuses exclusively on fabric timing delays.
|
|||
## Quick start
|
||||
|
||||
```
|
||||
pushd speed
|
||||
make
|
||||
popd
|
||||
|
||||
pushd timgrid
|
||||
make
|
||||
popd
|
||||
|
||||
pushd projects/placelut
|
||||
make N=1
|
||||
popd
|
||||
```
|
||||
|
||||
This will take a relatively long time (say 45 min) and generate build/tilea.json
|
||||
|
||||
|
||||
## Vivado background
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ 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
|
||||
|
||||
all: $(TILEA_JSONS)
|
||||
all: build/tilea.json
|
||||
|
||||
# make build/checksub first
|
||||
build/fast_max/tilea.json: build/checksub
|
||||
|
|
@ -76,3 +76,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)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,123 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
|
||||
corner_s2i = OrderedDict([
|
||||
('fast_max', 0),
|
||||
('fast_min', 1),
|
||||
('slow_max', 2),
|
||||
('slow_min', 3),
|
||||
])
|
||||
|
||||
corner2minmax = {
|
||||
'fast_max': max,
|
||||
'fast_min': min,
|
||||
'slow_max': max,
|
||||
'slow_min': min,
|
||||
}
|
||||
|
||||
def build_tilejo(fnins):
|
||||
'''
|
||||
{
|
||||
"tiles": {
|
||||
"BRKH_B_TERM_INT": {
|
||||
"pips": {},
|
||||
"wires": {
|
||||
"B_TERM_UTURN_INT_ER1BEG0": [
|
||||
null,
|
||||
null,
|
||||
93,
|
||||
null
|
||||
],
|
||||
'''
|
||||
|
||||
tilejo = {"tiles": {}}
|
||||
for fnin in fnins:
|
||||
tileji = json.load(open(fnin, 'r'))
|
||||
for tilek, tilevi in tileji['tiles'].items():
|
||||
# No previous data? Copy
|
||||
tilevo = tilejo['tiles'].get(tilek, None)
|
||||
if tilevo is None:
|
||||
tilejo['tiles'][tilek] = tilevi
|
||||
# Otherwise combine
|
||||
else:
|
||||
def process_type(etype):
|
||||
for pipk, pipvi in tilevi[etype].items():
|
||||
pipvo = tilevo[etype][pipk]
|
||||
for cornerk, corneri in corner_s2i.items():
|
||||
cornervo = pipvo[corneri]
|
||||
cornervi = pipvi[corneri]
|
||||
# no new data
|
||||
if cornervi is None:
|
||||
pass
|
||||
# no previous data
|
||||
elif cornervo is None:
|
||||
pipvo[corneri] = cornervi
|
||||
# combine
|
||||
else:
|
||||
minmax = corner2minmax[cornerk]
|
||||
pipvo[corneri] = minmax(cornervi, cornervo)
|
||||
process_type('pips')
|
||||
process_type('wires')
|
||||
return tilejo
|
||||
|
||||
def check_corner_minmax(tilej, verbose=False):
|
||||
# Post processing pass looking for min/max inconsistencies
|
||||
# Especially an issue due to complexities around under-constrained elements
|
||||
# (ex: pivots set to 0 delay)
|
||||
print('Checking for min/max consistency')
|
||||
checks = 0
|
||||
bad = 0
|
||||
for tilev in tilej['tiles'].values():
|
||||
def process_type(etype):
|
||||
nonlocal checks
|
||||
nonlocal bad
|
||||
|
||||
for pipk, pipv in tilev[etype].items():
|
||||
for corner in ('slow', 'fast'):
|
||||
mini = corner_s2i[corner + '_min']
|
||||
minv = pipv[mini]
|
||||
maxi = corner_s2i[corner + '_max']
|
||||
maxv = pipv[maxi]
|
||||
if minv is not None and maxv is not None:
|
||||
checks += 1
|
||||
if minv > maxv:
|
||||
if verbose:
|
||||
print('WARNING: element %s %s min/max adjusted on corner %s' % (etype, pipk, corner))
|
||||
bad += 1
|
||||
pipv[mini] = maxv
|
||||
pipv[maxi] = minv
|
||||
|
||||
process_type('pips')
|
||||
process_type('wires')
|
||||
print('minmax: %u / %u bad' % (bad, checks))
|
||||
|
||||
def check_corners_minmax(tilej, verbose=False):
|
||||
# TODO: check fast vs slow
|
||||
pass
|
||||
|
||||
def run(fnins, fnout, verbose=False):
|
||||
tilejo = build_tilejo(fnins)
|
||||
check_corner_minmax(tilejo)
|
||||
check_corners_minmax(tilejo)
|
||||
json.dump(tilejo, open(fnout, 'w'), sort_keys=True, indent=4, separators=(',', ': '))
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
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')
|
||||
args = parser.parse_args()
|
||||
|
||||
run(args.fnins, args.out, verbose=False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Reference in New Issue