mirror of https://github.com/openXC7/prjxray.git
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:
parent
e8299f6404
commit
e1208e1014
|
|
@ -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': {}}
|
||||
|
|
|
|||
|
|
@ -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\],"
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue