From 822a61e2f6885f574dbbd3c18e1b2d6eea7703f5 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Thu, 13 Feb 2020 16:35:58 -0800 Subject: [PATCH 01/10] Do not sort already ordered data. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- utils/xjson.py | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/utils/xjson.py b/utils/xjson.py index 4e670be7..d5b38c4c 100755 --- a/utils/xjson.py +++ b/utils/xjson.py @@ -5,7 +5,6 @@ import re import sys from collections import OrderedDict -from ordered_set import OrderedSet def extract_numbers(s): @@ -40,15 +39,15 @@ def sort(data): ... }) >>> for t in o: ... print(t+':', o[t]) - t1: OrderedSet(['b', 'c']) + t1: ('b', 'c') t2: ('a2', 'a10', 'e') - t3: (2, 3, 5) - t4: OrderedDict([('a2', ('c0', 'c1', 'c2', 'c10')), ('a4', ('b2', 'b3'))]) - t5: ('a1b1', 'a1b5', 'a2b1') + t3: (5, 3, 2) + t4: OrderedDict([('a2', ('c1', 'c2', 'c0', 'c10')), ('a4', ('b2', 'b3'))]) + t5: ('a1b5', 'a2b1', 'a1b1') Don't mangle "pairs" >>> sort([('b', 'c'), ('2', '1')]) - [('b', 'c'), ('2', '1')] + (('b', 'c'), ('2', '1')) """ # FIXME: We assume that a list is a tileconn.json format... if isinstance(data, list) and len(data) > 0 and 'wire_pairs' in data[0]: @@ -88,29 +87,9 @@ def sort(data): return new_dict elif isinstance(o, set): - nitems = [] - for k in o: - nitems.append((key(k), k)) - nitems.sort(key=lambda n: n[0]) - - new_set = OrderedSet() - for _, k in nitems: - new_set.add(k) - return new_set - + return tuple(sorted(o)) elif isinstance(o, (tuple, list)): - if len(o) == 2: - return o - - nlist = [] - for i in o: - nlist.append((key(i), rsorter(i))) - nlist.sort(key=lambda n: n[0]) - - new_list = [] - for _, i in nlist: - new_list.append(i) - return tuple(new_list) + return tuple(o) else: return o From 26d80244024ca7727a9225026d665e911b9df2d6 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Thu, 13 Feb 2020 17:11:29 -0800 Subject: [PATCH 02/10] Use sort key for sets. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- utils/xjson.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/xjson.py b/utils/xjson.py index d5b38c4c..43be703e 100755 --- a/utils/xjson.py +++ b/utils/xjson.py @@ -87,7 +87,7 @@ def sort(data): return new_dict elif isinstance(o, set): - return tuple(sorted(o)) + return tuple(sorted(o, key=key)) elif isinstance(o, (tuple, list)): return tuple(o) else: From 89761c11022bdf27ac53294a57bd577c95d6e3bd Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 14 Feb 2020 09:29:29 -0800 Subject: [PATCH 03/10] Add some sorting to JSON outputs. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/074-dump_all/generate_grid.py | 7 +++++++ fuzzers/074-dump_all/reduce_tile_types.py | 4 ++++ minitests/roi_harness/create_design_json.py | 9 ++++++--- utils/xjson.py | 4 ++-- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/fuzzers/074-dump_all/generate_grid.py b/fuzzers/074-dump_all/generate_grid.py index 32f78ec6..bb90476b 100644 --- a/fuzzers/074-dump_all/generate_grid.py +++ b/fuzzers/074-dump_all/generate_grid.py @@ -605,6 +605,13 @@ def main(): tileconn, raw_node_data = generate_tileconn( pool, node_tree, nodes, wire_map, grid) + for data in tileconn: + data['wire_pairs'] = tuple(sorted(data['wire_pairs'])) + + tileconn = tuple( + sorted( + tileconn, key=lambda x: (x['tile_types'], x['grid_deltas']))) + print('{} Writing tileconn'.format(datetime.datetime.now())) with open(tileconn_file, 'w') as f: json.dump(tileconn, f, indent=2, sort_keys=True) diff --git a/fuzzers/074-dump_all/reduce_tile_types.py b/fuzzers/074-dump_all/reduce_tile_types.py index f99b16bc..5b73460d 100644 --- a/fuzzers/074-dump_all/reduce_tile_types.py +++ b/fuzzers/074-dump_all/reduce_tile_types.py @@ -365,6 +365,10 @@ def main(): tile_type, site_types[site_type]['type'])), 'w') as f: json.dump(site_types[site_type], f, indent=2, sort_keys=True) + reduced_tile['sites'] = sorted( + reduced_tile['sites'], + key=lambda site: '{}_{}'.format(site['name'], site['prefix'])) + with open(tile_type_file, 'w') as f: json.dump(reduced_tile, f, indent=2, sort_keys=True) diff --git a/minitests/roi_harness/create_design_json.py b/minitests/roi_harness/create_design_json.py index ac336fa5..0c5e8770 100644 --- a/minitests/roi_harness/create_design_json.py +++ b/minitests/roi_harness/create_design_json.py @@ -11,7 +11,7 @@ from prjxray.util import get_db_root, get_part def set_port_wires(ports, name, pin, wires_outside_roi): for port in ports: if name == port['name']: - port['wires_outside_roi'] = wires_outside_roi + port['wires_outside_roi'] = sorted(wires_outside_roi) assert port['pin'] == pin return @@ -104,8 +104,11 @@ def main(): if not_in_roi: required_features.append(fasm_line) - design_json['required_features'] = fasm.fasm_tuple_to_string( - required_features, canonical=True).split('\n') + design_json['required_features'] = sorted( + fasm.fasm_tuple_to_string(required_features, + canonical=True).split('\n')) + + design_json['ports'].sort(key=lambda x: x['name']) xjson.pprint(sys.stdout, design_json) diff --git a/utils/xjson.py b/utils/xjson.py index 43be703e..03be3ace 100755 --- a/utils/xjson.py +++ b/utils/xjson.py @@ -87,9 +87,9 @@ def sort(data): return new_dict elif isinstance(o, set): - return tuple(sorted(o, key=key)) + return tuple(sorted((rsorter(v) for v in o), key=key)) elif isinstance(o, (tuple, list)): - return tuple(o) + return tuple(rsorter(v) for v in o) else: return o From 222eefcece77bd9f4fb8f4e9ea4e04bbe5e5bfa9 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 18 Feb 2020 06:43:53 -0800 Subject: [PATCH 04/10] Use extract_numbers for sort keys to preserve previous DB output. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/074-dump_all/reduce_tile_types.py | 4 +- minitests/roi_harness/create_design_json.py | 9 +- prjxray/xjson.py | 107 +++++++++++++++++++ utils/xjson.py | 110 +------------------- 4 files changed, 118 insertions(+), 112 deletions(-) create mode 100644 prjxray/xjson.py diff --git a/fuzzers/074-dump_all/reduce_tile_types.py b/fuzzers/074-dump_all/reduce_tile_types.py index 5b73460d..f8aaec4d 100644 --- a/fuzzers/074-dump_all/reduce_tile_types.py +++ b/fuzzers/074-dump_all/reduce_tile_types.py @@ -18,6 +18,7 @@ import multiprocessing import os import functools import json +from prjxray.xjson import extract_numbers def check_and_strip_prefix(name, prefix): @@ -367,7 +368,8 @@ def main(): reduced_tile['sites'] = sorted( reduced_tile['sites'], - key=lambda site: '{}_{}'.format(site['name'], site['prefix'])) + key=lambda site: extract_numbers( + '{}_{}'.format(site['name'], site['prefix']))) with open(tile_type_file, 'w') as f: json.dump(reduced_tile, f, indent=2, sort_keys=True) diff --git a/minitests/roi_harness/create_design_json.py b/minitests/roi_harness/create_design_json.py index 0c5e8770..1c30fbdf 100644 --- a/minitests/roi_harness/create_design_json.py +++ b/minitests/roi_harness/create_design_json.py @@ -6,12 +6,14 @@ import fasm from prjxray.db import Database from prjxray.roi import Roi from prjxray.util import get_db_root, get_part +from prjxray.xjson import extract_numbers def set_port_wires(ports, name, pin, wires_outside_roi): for port in ports: if name == port['name']: - port['wires_outside_roi'] = sorted(wires_outside_roi) + port['wires_outside_roi'] = sorted( + wires_outside_roi, key=extract_numbers) assert port['pin'] == pin return @@ -106,9 +108,10 @@ def main(): design_json['required_features'] = sorted( fasm.fasm_tuple_to_string(required_features, - canonical=True).split('\n')) + canonical=True).split('\n'), + key=extract_numbers) - design_json['ports'].sort(key=lambda x: x['name']) + design_json['ports'].sort(key=lambda x: extract_numbers(x['name'])) xjson.pprint(sys.stdout, design_json) diff --git a/prjxray/xjson.py b/prjxray/xjson.py new file mode 100644 index 00000000..6bdd3e19 --- /dev/null +++ b/prjxray/xjson.py @@ -0,0 +1,107 @@ +import io +import json +import re + +from collections import OrderedDict + + +def extract_numbers(s): + """ + >>> extract_numbers("CLK_HROW_WR10END2_3") + ('CLK_HROW_WR', 10, 'END', 2, '_', 3) + >>> extract_numbers("VBRK_WR1END2") + ('VBRK_WR', 1, 'END', 2) + """ + bits = [] + for m in re.finditer("([^0-9]*)([0-9]*)", s): + if m.group(1): + bits.append(m.group(1)) + if m.group(2): + bits.append(int(m.group(2))) + return tuple(bits) + + +def sort(data): + """Sort data types via "natural" numbers. + + Supports all the basic Python data types. + >>> o = sort({ + ... 't1': {'c','b'}, # Set + ... 't2': ('a2', 'a10', 'e'), # Tuple + ... 't3': [5, 3, 2], # List + ... 't4': { # Dictionary + ... 'a4': ('b2', 'b3'), + ... 'a2': ['c1', 'c2', 'c0', 'c10'], + ... }, + ... 't5': ['a1b5', 'a2b1', 'a1b1'], + ... }) + >>> for t in o: + ... print(t+':', o[t]) + t1: ('b', 'c') + t2: ('a2', 'a10', 'e') + t3: (5, 3, 2) + t4: OrderedDict([('a2', ('c1', 'c2', 'c0', 'c10')), ('a4', ('b2', 'b3'))]) + t5: ('a1b5', 'a2b1', 'a1b1') + + Don't mangle "pairs" + >>> sort([('b', 'c'), ('2', '1')]) + (('b', 'c'), ('2', '1')) + """ + # FIXME: We assume that a list is a tileconn.json format... + if isinstance(data, list) and len(data) > 0 and 'wire_pairs' in data[0]: + for o in data: + o['wire_pairs'].sort( + key=lambda o: (extract_numbers(o[0]), extract_numbers(o[1]))) + + data.sort(key=lambda o: (o['tile_types'], o['grid_deltas'])) + return data + else: + + def key(o): + if o is None: + return None + elif isinstance(o, str): + return extract_numbers(o) + elif isinstance(o, int): + return o + elif isinstance(o, (list, tuple)): + return tuple(key(i) for i in o) + elif isinstance(o, dict): + return tuple((key(k), key(v)) for k, v in o.items()) + elif isinstance(o, set): + return tuple(key(k) for k in o) + raise ValueError(repr(o)) + + def rsorter(o): + if isinstance(o, dict): + nitems = [] + for k, v in o.items(): + nitems.append((key(k), k, rsorter(v))) + nitems.sort(key=lambda n: n[0]) + + new_dict = OrderedDict() + for _, k, v in nitems: + new_dict[k] = v + return new_dict + + elif isinstance(o, set): + return tuple(sorted((rsorter(v) for v in o), key=key)) + elif isinstance(o, (tuple, list)): + return tuple(rsorter(v) for v in o) + else: + return o + + return rsorter(data) + + +def pprint(f, data): + detach = False + if not isinstance(f, io.TextIOBase): + detach = True + f = io.TextIOWrapper(f) + data = sort(data) + json.dump(data, f, indent=4) + f.write('\n') + f.flush() + if detach: + f.detach() diff --git a/utils/xjson.py b/utils/xjson.py index 03be3ace..7affd767 100755 --- a/utils/xjson.py +++ b/utils/xjson.py @@ -1,113 +1,7 @@ #!/usr/bin/env python3 -import io -import json -import re import sys - -from collections import OrderedDict - - -def extract_numbers(s): - """ - >>> extract_numbers("CLK_HROW_WR10END2_3") - ('CLK_HROW_WR', 10, 'END', 2, '_', 3) - >>> extract_numbers("VBRK_WR1END2") - ('VBRK_WR', 1, 'END', 2) - """ - bits = [] - for m in re.finditer("([^0-9]*)([0-9]*)", s): - if m.group(1): - bits.append(m.group(1)) - if m.group(2): - bits.append(int(m.group(2))) - return tuple(bits) - - -def sort(data): - """Sort data types via "natural" numbers. - - Supports all the basic Python data types. - >>> o = sort({ - ... 't1': {'c','b'}, # Set - ... 't2': ('a2', 'a10', 'e'), # Tuple - ... 't3': [5, 3, 2], # List - ... 't4': { # Dictionary - ... 'a4': ('b2', 'b3'), - ... 'a2': ['c1', 'c2', 'c0', 'c10'], - ... }, - ... 't5': ['a1b5', 'a2b1', 'a1b1'], - ... }) - >>> for t in o: - ... print(t+':', o[t]) - t1: ('b', 'c') - t2: ('a2', 'a10', 'e') - t3: (5, 3, 2) - t4: OrderedDict([('a2', ('c1', 'c2', 'c0', 'c10')), ('a4', ('b2', 'b3'))]) - t5: ('a1b5', 'a2b1', 'a1b1') - - Don't mangle "pairs" - >>> sort([('b', 'c'), ('2', '1')]) - (('b', 'c'), ('2', '1')) - """ - # FIXME: We assume that a list is a tileconn.json format... - if isinstance(data, list) and len(data) > 0 and 'wire_pairs' in data[0]: - for o in data: - o['wire_pairs'].sort( - key=lambda o: (extract_numbers(o[0]), extract_numbers(o[1]))) - - data.sort(key=lambda o: (o['tile_types'], o['grid_deltas'])) - return data - else: - - def key(o): - if o is None: - return None - elif isinstance(o, str): - return extract_numbers(o) - elif isinstance(o, int): - return o - elif isinstance(o, (list, tuple)): - return tuple(key(i) for i in o) - elif isinstance(o, dict): - return tuple((key(k), key(v)) for k, v in o.items()) - elif isinstance(o, set): - return tuple(key(k) for k in o) - raise ValueError(repr(o)) - - def rsorter(o): - if isinstance(o, dict): - nitems = [] - for k, v in o.items(): - nitems.append((key(k), k, rsorter(v))) - nitems.sort(key=lambda n: n[0]) - - new_dict = OrderedDict() - for _, k, v in nitems: - new_dict[k] = v - return new_dict - - elif isinstance(o, set): - return tuple(sorted((rsorter(v) for v in o), key=key)) - elif isinstance(o, (tuple, list)): - return tuple(rsorter(v) for v in o) - else: - return o - - return rsorter(data) - - -def pprint(f, data): - detach = False - if not isinstance(f, io.TextIOBase): - detach = True - f = io.TextIOWrapper(f) - data = sort(data) - json.dump(data, f, indent=4) - f.write('\n') - f.flush() - if detach: - f.detach() - +import json +from prjxray.xjson import pprint if __name__ == "__main__": if len(sys.argv) == 1: From 0364315e82504c58903ccb7b7c7f94352d0f2764 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 18 Feb 2020 06:47:30 -0800 Subject: [PATCH 05/10] Avoid race in 001 fuzzer. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- .github/kokoro/db-full.sh | 1 - Makefile | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/kokoro/db-full.sh b/.github/kokoro/db-full.sh index 7abd0974..6d6c63f1 100755 --- a/.github/kokoro/db-full.sh +++ b/.github/kokoro/db-full.sh @@ -94,7 +94,6 @@ EXTRAS_HARNESS_RET=$? set -e # Generate extra parts file (tilegrid, tileconn, part yaml, part json and package_pin) -# TODO: Disabled for now as for big parts it takes a huge amount of time set +e make db-extras-${XRAY_SETTINGS}-parts -j $CORES EXTRAS_PARTS_RET=$? diff --git a/Makefile b/Makefile index aaa05a0c..0bc81806 100644 --- a/Makefile +++ b/Makefile @@ -160,8 +160,6 @@ endef $(foreach PART,$(XRAY_PARTS),$(eval $(call multiple-parts,$(PART)))) db-extras-artix7-parts: $(addprefix db-part-only-,$(ARTIX_PARTS)) - +XRAY_PIN_00=J13 XRAY_PIN_01=J14 XRAY_PIN_02=K15 XRAY_PIN_03=K16 \ - XRAY_PART=xc7a35tftg256-1 XRAY_EQUIV_PART=xc7a50tfgg484-1 $(MAKE) -C fuzzers roi_only db-extras-artix7-harness: +source minitests/roi_harness/basys3-swbut.sh && $(MAKE) -C fuzzers roi_only @@ -182,6 +180,8 @@ db-extras-artix7-harness: +source minitests/roi_harness/arty-swbut.sh && \ $(MAKE) -C minitests/roi_harness \ HARNESS_DIR=$(XRAY_DATABASE_DIR)/artix7/harness/arty-a7/swbut run copy + +XRAY_PIN_00=J13 XRAY_PIN_01=J14 XRAY_PIN_02=K15 XRAY_PIN_03=K16 \ + XRAY_PART=xc7a35tftg256-1 XRAY_EQUIV_PART=xc7a50tfgg484-1 $(MAKE) -C fuzzers roi_only db-extras-kintex7-parts: @true From c2a5c7ffa19b066a36df1373cdf94557d830d90c Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 18 Feb 2020 15:41:24 -0800 Subject: [PATCH 06/10] Remove broken special case logic from xjson. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- prjxray/xjson.py | 71 +++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 40 deletions(-) diff --git a/prjxray/xjson.py b/prjxray/xjson.py index 6bdd3e19..da888e0a 100644 --- a/prjxray/xjson.py +++ b/prjxray/xjson.py @@ -47,51 +47,42 @@ def sort(data): >>> sort([('b', 'c'), ('2', '1')]) (('b', 'c'), ('2', '1')) """ - # FIXME: We assume that a list is a tileconn.json format... - if isinstance(data, list) and len(data) > 0 and 'wire_pairs' in data[0]: - for o in data: - o['wire_pairs'].sort( - key=lambda o: (extract_numbers(o[0]), extract_numbers(o[1]))) - data.sort(key=lambda o: (o['tile_types'], o['grid_deltas'])) - return data - else: + def key(o): + if o is None: + return None + elif isinstance(o, str): + return extract_numbers(o) + elif isinstance(o, int): + return o + elif isinstance(o, (list, tuple)): + return tuple(key(i) for i in o) + elif isinstance(o, dict): + return tuple((key(k), key(v)) for k, v in o.items()) + elif isinstance(o, set): + return tuple(key(k) for k in o) + raise ValueError(repr(o)) - def key(o): - if o is None: - return None - elif isinstance(o, str): - return extract_numbers(o) - elif isinstance(o, int): - return o - elif isinstance(o, (list, tuple)): - return tuple(key(i) for i in o) - elif isinstance(o, dict): - return tuple((key(k), key(v)) for k, v in o.items()) - elif isinstance(o, set): - return tuple(key(k) for k in o) - raise ValueError(repr(o)) + def rsorter(o): + if isinstance(o, dict): + nitems = [] + for k, v in o.items(): + nitems.append((key(k), k, rsorter(v))) + nitems.sort(key=lambda n: n[0]) - def rsorter(o): - if isinstance(o, dict): - nitems = [] - for k, v in o.items(): - nitems.append((key(k), k, rsorter(v))) - nitems.sort(key=lambda n: n[0]) + new_dict = OrderedDict() + for _, k, v in nitems: + new_dict[k] = v + return new_dict - new_dict = OrderedDict() - for _, k, v in nitems: - new_dict[k] = v - return new_dict + elif isinstance(o, set): + return tuple(sorted((rsorter(v) for v in o), key=key)) + elif isinstance(o, (tuple, list)): + return tuple(rsorter(v) for v in o) + else: + return o - elif isinstance(o, set): - return tuple(sorted((rsorter(v) for v in o), key=key)) - elif isinstance(o, (tuple, list)): - return tuple(rsorter(v) for v in o) - else: - return o - - return rsorter(data) + return rsorter(data) def pprint(f, data): From 9aec0c8d9c9fbe676c06d10dfc9938353223efc5 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Wed, 19 Feb 2020 06:25:45 -0800 Subject: [PATCH 07/10] Sort wire pairs using extract_numbers. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/074-dump_all/generate_grid.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fuzzers/074-dump_all/generate_grid.py b/fuzzers/074-dump_all/generate_grid.py index bb90476b..4743d262 100644 --- a/fuzzers/074-dump_all/generate_grid.py +++ b/fuzzers/074-dump_all/generate_grid.py @@ -12,6 +12,7 @@ import pickle import sys from prjxray import util, lib +from prjxray.xjson import extract_numbers def get_tile_grid_info(fname): @@ -606,7 +607,10 @@ def main(): pool, node_tree, nodes, wire_map, grid) for data in tileconn: - data['wire_pairs'] = tuple(sorted(data['wire_pairs'])) + data['wire_pairs'] = tuple( + sorted( + data['wire_pairs'], + key=lambda x: tuple(extract_numbers(s) for s in x))) tileconn = tuple( sorted( From f7e3442f748e8fe21487a49f5419c5f772325836 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 14 Feb 2020 09:30:26 -0800 Subject: [PATCH 08/10] Remap some timing models. This is an approximation, but it may work better. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/074-dump_all/jobtiles.tcl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/fuzzers/074-dump_all/jobtiles.tcl b/fuzzers/074-dump_all/jobtiles.tcl index 37b37e58..c29b207c 100644 --- a/fuzzers/074-dump_all/jobtiles.tcl +++ b/fuzzers/074-dump_all/jobtiles.tcl @@ -48,6 +48,22 @@ proc lookup_speed_model_name {name} { return [dict get $speed_model_name_map $name] } +# For BSW_INT_LONG_MUX, use the model from BSW_INT_HLONG_MUX. +# This isn't exactly correct, but it is a better model to use. +set int_hlong_mux [lookup_speed_model_name BSW_INT_HLONG_MUX] +set int_long_mux [lookup_speed_model_name BSW_INT_LONG_MUX] + +set long_forward [get_property FORWARD $int_long_mux] +set hlong_forward [get_property FORWARD $int_hlong_mux] +dict set speed_model_name_map $long_forward [lookup_speed_model_name $hlong_forward] + +set long_reverse [get_property REVERSE $int_long_mux] +set hlong_reverse [get_property REVERSE $int_hlong_mux] +dict set speed_model_name_map $long_forward [lookup_speed_model_name $hlong_reverse] + +# Same here! +dict set speed_model_name_map _BSW_LONG_TLREVERSE [lookup_speed_model_name _BSW_LONG_NONTLFORWARD] + for {set j $start } { $j < $stop } { incr j } { set tile [lindex $tiles $j] From 328903d2be94b2271d40958233042ae32105c793 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 14 Feb 2020 11:33:28 -0800 Subject: [PATCH 09/10] Add workaround for double counting of long wire delay. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- utils/create_timing_worksheet_db.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/utils/create_timing_worksheet_db.py b/utils/create_timing_worksheet_db.py index ab269b36..3680cc57 100644 --- a/utils/create_timing_worksheet_db.py +++ b/utils/create_timing_worksheet_db.py @@ -125,7 +125,13 @@ class Net(object): def extend_rc_tree(self, ws, current_rc_root, timing_lookup, node): rc_elements = [] - for wire in node['wires']: + + # LV nodes have a workaround applied because of a working in the + # pip timing. + is_lv_node = any( + wire['name'].split('/')[1].startswith('LV') + for wire in node['wires']) + for idx, wire in enumerate(node['wires']): wire_timing = timing_lookup.find_wire(wire['name']) ws['A{}'.format(self.row)] = wire['name'] ws['B{}'.format(self.row)] = 'Part of wire' @@ -134,8 +140,20 @@ class Net(object): cells = {} cells['R'] = 'C{}'.format(self.row) cells['C'] = 'D{}'.format(self.row) - ws[cells['R']] = wire_timing.resistance - ws[cells['C']] = wire_timing.capacitance + if not is_lv_node: + ws[cells['R']] = wire_timing.resistance + ws[cells['C']] = wire_timing.capacitance + else: + # Only use first 2 wire RC's, ignore the rest. It appears + # that some of the RC constant was lumped into the switch + # timing, so don't double count. + if idx < 2: + ws[cells['R']] = wire_timing.resistance + ws[cells['C']] = wire_timing.capacitance + else: + ws[cells['R']] = 0 + ws[cells['C']] = 0 + rc_elements.append( RcElement( resistance=cells['R'], From 445934140e840c44918bc5d979168cd1f522c93d Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Wed, 19 Feb 2020 15:15:59 -0800 Subject: [PATCH 10/10] Fix up some comments. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/074-dump_all/jobtiles.tcl | 2 ++ utils/create_timing_worksheet_db.py | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fuzzers/074-dump_all/jobtiles.tcl b/fuzzers/074-dump_all/jobtiles.tcl index c29b207c..d4468a2e 100644 --- a/fuzzers/074-dump_all/jobtiles.tcl +++ b/fuzzers/074-dump_all/jobtiles.tcl @@ -50,6 +50,8 @@ proc lookup_speed_model_name {name} { # For BSW_INT_LONG_MUX, use the model from BSW_INT_HLONG_MUX. # This isn't exactly correct, but it is a better model to use. +# BSW_INT_LONG_MUX is a tl_buffer (which we don't really understand), and +# BSW_INT_HLONG_MUX is not. This subsitution appears good enough for now. set int_hlong_mux [lookup_speed_model_name BSW_INT_HLONG_MUX] set int_long_mux [lookup_speed_model_name BSW_INT_LONG_MUX] diff --git a/utils/create_timing_worksheet_db.py b/utils/create_timing_worksheet_db.py index 3680cc57..845b7af8 100644 --- a/utils/create_timing_worksheet_db.py +++ b/utils/create_timing_worksheet_db.py @@ -126,8 +126,8 @@ class Net(object): def extend_rc_tree(self, ws, current_rc_root, timing_lookup, node): rc_elements = [] - # LV nodes have a workaround applied because of a working in the - # pip timing. + # LV nodes have a workaround applied because of a work around in the + # pip timing data. is_lv_node = any( wire['name'].split('/')[1].startswith('LV') for wire in node['wires'])