From e1208e10148777085ebfb31aaf516f1ea5edf5e2 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Wed, 29 May 2019 14:51:35 -0700 Subject: [PATCH] Add wire, pip, and site pin timing information. This is required for interconnect timing modelling. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/074-dump_all/create_node_tree.py | 3 +- fuzzers/074-dump_all/jobtiles.tcl | 81 ++++++++++++++++++++++- fuzzers/074-dump_all/reduce_tile_types.py | 60 ++++++++++++++--- 3 files changed, 134 insertions(+), 10 deletions(-) diff --git a/fuzzers/074-dump_all/create_node_tree.py b/fuzzers/074-dump_all/create_node_tree.py index e7834ec8..53efb58c 100644 --- a/fuzzers/074-dump_all/create_node_tree.py +++ b/fuzzers/074-dump_all/create_node_tree.py @@ -100,7 +100,8 @@ def create_ordered_wires_for_node(node, wires_in_node, downhill, uphill): roots |= set((wire[0], wire[-1])) all_wires |= set(wire) - assert len(wires_in_node) >= len(all_wires) + assert len(wires_in_node) >= len(all_wires), ( + len(wires_in_node), len(all_wires)) if len(all_wires) <= 2: return {'edges': tuple(all_wires), 'joins': {}} diff --git a/fuzzers/074-dump_all/jobtiles.tcl b/fuzzers/074-dump_all/jobtiles.tcl index 28350f85..bc6ca442 100644 --- a/fuzzers/074-dump_all/jobtiles.tcl +++ b/fuzzers/074-dump_all/jobtiles.tcl @@ -13,6 +13,27 @@ set root_fp [open "root_${blocknb}.csv" w] #puts $root_fp "filetype,subtype,filename" set tiles [get_tiles] +set MAGIC 0.6875 + +set speed_model_index_map [dict create] +set speed_model_name_map [dict create] +foreach speed_model [get_speed_models] { + set index [get_property SPEED_INDEX $speed_model] + if { $index != 65535 } { + if [dict exists $speed_model_index_map $index] { + error "$index already in map!" + } + dict set speed_model_index_map $index $speed_model + } + + if { [get_property IS_INSTANCE_SPECIFIC -quiet $speed_model] != 1 } { + set name [get_property NAME $speed_model] + if [dict exists $speed_model_name_map $name] { + error "$name already in map!" + } + dict set speed_model_name_map $name $speed_model + } +} for {set j $start } { $j < $stop } { incr j } { @@ -54,7 +75,23 @@ for {set j $start } { $j < $stop } { incr j } { # SPEED_INDEX puts $fp "\t\t\t\{" puts $fp "\t\t\t\t\"site_pin\":\"$site_pin\"," - puts $fp "\t\t\t\t\"direction\":\"[get_property DIRECTION $site_pin]\"," + set site_pin_speed_model [dict get $speed_model_index_map [get_property SPEED_INDEX $site_pin]] + set dir [get_property DIRECTION $site_pin] + + if { $dir == "IN" } { + puts $fp "\t\t\t\t\"cap\": \"[get_property CAP $site_pin_speed_model]\"," + } else { + set site_pin_speed_model [dict get $speed_model_name_map [get_property DRIVER $site_pin_speed_model]] + puts $fp "\t\t\t\t\"res\": \"[expr $MAGIC * [get_property DRIVE $site_pin_speed_model]]\"," + } + + puts $fp "\t\t\t\t\"delay\": \[" + puts $fp "\t\t\t\t\t\"[get_property FAST_MIN $site_pin_speed_model]\"," + puts $fp "\t\t\t\t\t\"[get_property FAST_MAX $site_pin_speed_model]\"," + puts $fp "\t\t\t\t\t\"[get_property SLOW_MIN $site_pin_speed_model]\"," + puts $fp "\t\t\t\t\t\"[get_property SLOW_MAX $site_pin_speed_model]\"," + puts $fp "\t\t\t\t\]," + puts $fp "\t\t\t\t\"direction\":\"$dir\"," set site_pin_node [get_nodes -of_objects $site_pin] if {[llength $site_pin_node] == 0} { puts $fp "\t\t\t\t\"node\":null," @@ -95,6 +132,45 @@ for {set j $start } { $j < $stop } { incr j } { # IS_TEST_PIP NAME SPEED_INDEX TILE puts $fp "\t\t\{" puts $fp "\t\t\t\"pip\":\"$pip\"," + set pip_speed_model [dict get $speed_model_index_map [get_property SPEED_INDEX $pip]] + set forward_speed_model [dict get $speed_model_name_map [get_property FORWARD $pip_speed_model]] + set reverse_speed_model [dict get $speed_model_name_map [get_property REVERSE $pip_speed_model]] + + set forward_speed_model_type [get_property TYPE $forward_speed_model] + set reverse_speed_model_type [get_property TYPE $reverse_speed_model] + set is_pass_transistor [expr {"$forward_speed_model_type" == "pass_transistor"}] + puts $fp "\t\t\t\"is_pass_transistor\":$is_pass_transistor," + + if { !$is_pass_transistor } { + puts $fp "\t\t\t\"forward_delay\":\[" + puts $fp "\t\t\t\t\"[get_property FAST_MIN $forward_speed_model]\"," + puts $fp "\t\t\t\t\"[get_property FAST_MAX $forward_speed_model]\"," + puts $fp "\t\t\t\t\"[get_property SLOW_MIN $forward_speed_model]\"," + puts $fp "\t\t\t\t\"[get_property SLOW_MAX $forward_speed_model]\"," + puts $fp "\t\t\t\]," + if {$forward_speed_model_type == "buffer_switch" || $forward_speed_model_type == "buffer"} { + puts $fp "\t\t\t\"forward_res\": \"[expr $MAGIC * [get_property DRIVE $forward_speed_model]]\"," + } + if {$forward_speed_model_type == "buffer_switch"} { + puts $fp "\t\t\t\"forward_in_cap\": \"[get_property IN_CAP $forward_speed_model]\"," + } + + puts $fp "\t\t\t\"reverse_delay\":\[" + puts $fp "\t\t\t\t\"[get_property FAST_MIN $reverse_speed_model]\"," + puts $fp "\t\t\t\t\"[get_property FAST_MAX $reverse_speed_model]\"," + puts $fp "\t\t\t\t\"[get_property SLOW_MIN $reverse_speed_model]\"," + puts $fp "\t\t\t\t\"[get_property SLOW_MAX $reverse_speed_model]\"," + puts $fp "\t\t\t\]," + if {$reverse_speed_model_type == "buffer_switch" || $reverse_speed_model_type == "buffer"} { + puts $fp "\t\t\t\"reverse_res\": \"[expr $MAGIC * [get_property DRIVE $reverse_speed_model]]\"," + } + if {$reverse_speed_model_type == "buffer_switch"} { + puts $fp "\t\t\t\"reverse_in_cap\": \"[get_property IN_CAP $reverse_speed_model]\"," + } + } else { + puts $fp "\t\t\t\"forward_res\": \"[get_property RES $forward_speed_model]\"," + puts $fp "\t\t\t\"reverse_res\": \"[get_property RES $reverse_speed_model]\"," + } puts $fp "\t\t\t\"src_wire\":\"[get_wires -uphill -of_objects $pip]\"," puts $fp "\t\t\t\"dst_wire\":\"[get_wires -downhill -of_objects $pip]\"," puts $fp "\t\t\t\"is_pseudo\":\"[get_property IS_PSEUDO $pip]\"," @@ -111,7 +187,10 @@ for {set j $start } { $j < $stop } { incr j } { # IS_PART_OF_BUS NAME NUM_DOWNHILL_PIPS NUM_INTERSECTS NUM_PIPS # NUM_TILE_PORTS NUM_UPHILL_PIPS SPEED_INDEX TILE_NAME TILE_PATTERN_OFFSET puts $fp "\t\t\{" + set wire_speed_model [dict get $speed_model_index_map [get_property SPEED_INDEX $wire]] puts $fp "\t\t\t\"wire\":\"$wire\"," + puts $fp "\t\t\t\"res\":\"[get_property WIRE_RES $wire_speed_model]\"," + puts $fp "\t\t\t\"cap\":\"[get_property WIRE_CAP $wire_speed_model]\"," puts $fp "\t\t\}," } puts $fp "\t\]," diff --git a/fuzzers/074-dump_all/reduce_tile_types.py b/fuzzers/074-dump_all/reduce_tile_types.py index d7949e11..1e4f1d97 100644 --- a/fuzzers/074-dump_all/reduce_tile_types.py +++ b/fuzzers/074-dump_all/reduce_tile_types.py @@ -39,9 +39,20 @@ def flatten_site_pins(tile, site, site_pins, site_pin_node_to_wires): assert len(wires) == 1, repr(wires) + pin_info = { + 'wire': wires[0], + 'delay': site_pin['delay'], + } + + if 'cap' in site_pin: + pin_info['cap'] = site_pin['cap'] + + if 'res' in site_pin: + pin_info['res'] = site_pin['res'] + yield ( check_and_strip_prefix(site_pin['site_pin'], site + '/'), - wires[0]) + pin_info) return dict(inner()) @@ -103,6 +114,18 @@ def get_pips(tile, pips): pip['is_directional'], 'can_invert': pip['can_invert'], + 'is_pass_transistor': + pip['is_pass_transistor'], + 'src_to_dst': { + 'delay': pip.get('forward_delay', None), + 'in_cap': pip.get('forward_in_cap', None), + 'res': pip.get('forward_res', None), + }, + 'dst_to_src': { + 'delay': pip.get('reverse_delay', None), + 'in_cap': pip.get('reverse_in_cap', None), + 'res': pip.get('reverse_res', None), + }, } return proto_pips @@ -148,7 +171,7 @@ def check_wires(wires, sites, pips): for site in sites: for wire_to_site_pin in site['site_pins'].values(): if wire_to_site_pin is not None: - assert wire_to_site_pin in wires, repr( + assert wire_to_site_pin['wire'] in wires, repr( (wire_to_site_pin, wires)) if pips is not None: @@ -207,19 +230,37 @@ def read_json5(fname, database_file): def inner(): for wire in tile['wires']: assert wire['wire'].startswith(tile['tile'] + '/') - yield wire['wire'][len(tile['tile']) + 1:] - wires = set(inner()) + if wire['res'] != '0.000' or wire['cap'] != '0.000': + wire_delay_model = { + 'res': wire['res'], + 'cap': wire['cap'], + } + else: + wire_delay_model = None + + yield wire['wire'][len(tile['tile']) + 1:], wire_delay_model + + wires = {k: v for (k, v) in inner()} wires_from_nodes = set(node_lookup.wires_for_tile(tile['tile'])) - assert len(wires_from_nodes - wires) == 0, repr((wires, wires_from_nodes)) + assert len(wires_from_nodes - wires.keys()) == 0, repr( + (wires, wires_from_nodes)) return fname, tile, site_types, sites, pips, wires +def compare_and_update_wires(wires, new_wires): + for wire in new_wires: + if wire not in wires: + wires[wire] = new_wires + else: + assert wires[wire] == new_wires[wire] + + def reduce_tile(pool, site_types, tile_type, tile_instances, database_file): sites = None pips = None - wires = set() + wires = None with progressbar.ProgressBar(max_value=len(tile_instances)) as bar: chunksize = 1 @@ -259,7 +300,10 @@ def reduce_tile(pool, site_types, tile_type, tile_instances, database_file): else: compare_and_update_pips(pips, new_pips) - wires |= new_wires + if wires is None: + wires = new_wires + else: + compare_and_update_wires(wires, new_wires) bar.update(idx + 1) @@ -269,7 +313,7 @@ def reduce_tile(pool, site_types, tile_type, tile_instances, database_file): 'tile_type': tile_type, 'sites': sites, 'pips': pips, - 'wires': tuple(wires), + 'wires': wires, }