prjxray/fuzzers/007-timing/timgrid_vc2v.py

145 lines
4.1 KiB
Python

#!/usr/bin/env python3
import sys
import os
import time
import json
from collections import OrderedDict
import timfuz
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('')
print('minmax: %u / %u pairs bad pairs adjusted' % (bad, checks))
timfuz.tilej_stats(tilej)
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 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)
if __name__ == '__main__':
main()