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>
This commit is contained in:
Keith Rothman 2019-05-29 14:51:35 -07:00
parent e8299f6404
commit e1208e1014
3 changed files with 134 additions and 10 deletions

View File

@ -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': {}}

View File

@ -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\],"

View File

@ -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,
}