diff --git a/fuzzers/005-tilegrid/generate_full.py b/fuzzers/005-tilegrid/generate_full.py index 1203d6d3..e3a7290c 100644 --- a/fuzzers/005-tilegrid/generate_full.py +++ b/fuzzers/005-tilegrid/generate_full.py @@ -231,12 +231,12 @@ def propagate_rebuf(database, tiles_by_grid): assert database[tile_name]['bits']['CLB_IO_CLK']['offset'] == 47, database[tile_name]['bits']['CLB_IO_CLK'] database[rebuf_below]['bits'] = copy.deepcopy(database[tile_name]['bits']) - database[rebuf_below]['bits']['CLB_IO_CLK']['offset'] = 71 - database[rebuf_below]['bits']['CLB_IO_CLK']['words'] = 10 + database[rebuf_below]['bits']['CLB_IO_CLK']['offset'] = 73 + database[rebuf_below]['bits']['CLB_IO_CLK']['words'] = 4 database[rebuf_above]['bits'] = copy.deepcopy(database[tile_name]['bits']) - database[rebuf_above]['bits']['CLB_IO_CLK']['offset'] = 22 - database[rebuf_above]['bits']['CLB_IO_CLK']['words'] = 10 + database[rebuf_above]['bits']['CLB_IO_CLK']['offset'] = 24 + database[rebuf_above]['bits']['CLB_IO_CLK']['words'] = 4 def run(json_in_fn, json_out_fn, verbose=False): diff --git a/fuzzers/043-clk-rebuf-pips/Makefile b/fuzzers/043-clk-rebuf-pips/Makefile index ff3d9fa7..516d916d 100644 --- a/fuzzers/043-clk-rebuf-pips/Makefile +++ b/fuzzers/043-clk-rebuf-pips/Makefile @@ -1,11 +1,11 @@ -N ?= 50 +N ?= 25 include ../fuzzer.mk database: build/segbits_clk_bufg_rebuf.db build/segbits_clk_bufg_rebuf.rdb: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} -o build/segbits_clk_bufg_rebuf.rdb \ + ${XRAY_SEGMATCH} -c 1 -o build/segbits_clk_bufg_rebuf.rdb \ $(addsuffix /segdata_clk_bufg_rebuf.txt,$(SPECIMENS)) build/segbits_clk_bufg_rebuf.db: build/segbits_clk_bufg_rebuf.rdb diff --git a/fuzzers/043-clk-rebuf-pips/generate.py b/fuzzers/043-clk-rebuf-pips/generate.py index 4204aaa8..367a2837 100644 --- a/fuzzers/043-clk-rebuf-pips/generate.py +++ b/fuzzers/043-clk-rebuf-pips/generate.py @@ -1,16 +1,80 @@ #!/usr/bin/env python3 from prjxray.segmaker import Segmaker +from prjxray.db import Database +from prjxray.util import get_db_root import re REBUF_GCLK = re.compile('^CLK_BUFG_REBUF_R_CK_GCLK([0-9]+)_BOT$') + +GCLKS = 32 + +def gclk_of_wire(wire): + m = REBUF_GCLK.match(wire) + assert m, wire + return int(m.group(1)) + +class ClockColumn(object): + def __init__(self, db_root): + db = Database(db_root) + grid = db.grid() + + tiles_in_gclk_columns = [] + self.gclk_columns = {} + + for tile in grid.tiles(): + gridinfo = grid.gridinfo_at_tilename(tile) + + if gridinfo.tile_type != 'CLK_BUFG_REBUF': + continue + + loc = grid.loc_of_tilename(tile) + + tiles_in_gclk_columns.append((loc.grid_y, tile)) + + _, self.tiles_in_gclk_columns = zip(*sorted(tiles_in_gclk_columns, key=lambda x: x[0])) + + # Initially all GCLK lines are idle. GCLK lines only exist between + #CLK_BUFG_REBUF tiles, hence len-1. + for gclk in range(GCLKS): + self.gclk_columns[gclk] = [False for _ in range(len(self.tiles_in_gclk_columns)-1)] + + def enable_rebuf(self, tile, wire): + # Find which REBUF is being activated. + rebuf_idx = self.tiles_in_gclk_columns.index(tile) + assert rebuf_idx != -1, tile + + gclk = gclk_of_wire(wire) + + self.gclk_columns[gclk][rebuf_idx] = True + self.gclk_columns[gclk][rebuf_idx-1] = True + + def yield_rebuf_state(self): + """ Yields tile_name, gclk, bool if active above tile, bool if active below tile """ + for idx, tile in enumerate(self.tiles_in_gclk_columns): + for gclk in range(GCLKS): + active_below = False + active_above = False + + if idx > 0: + active_below = self.gclk_columns[gclk][idx-1] + + if idx < len(self.gclk_columns[gclk]): + active_above = self.gclk_columns[gclk][idx] + + yield tile, gclk, active_below, active_above + + def main(): + db_root = get_db_root() + + clock_column = ClockColumn(db_root) + segmk = Segmaker("design.bits") print("Loading tags from design.txt.") - gclks_in_use = {} - with open("design.txt", "r") as f: + with open("route.txt", "r") as f: for line in f: if 'CLK_BUFG_REBUF' not in line: continue @@ -33,24 +97,21 @@ def main(): assert dst == wire_a - m = REBUF_GCLK.match(dst) - assert m, dst - gclk = int(m.group(1)) - - if tile_from_pip not in gclks_in_use: - gclks_in_use[tile_from_pip] = set() - gclks_in_use[tile_from_pip].add(gclk) - if tile_from_wire == tile_from_pip: - segmk.add_tile_tag(tile_from_pip, '{}.{}'.format(wire_a, wire_b), wire_a == dst) - segmk.add_tile_tag(tile_from_pip, '{}.{}'.format(wire_b, wire_a), wire_a != dst) + b_to_a = wire_a == dst + a_to_b = not b_to_a else: - segmk.add_tile_tag(tile_from_pip, '{}.{}'.format(wire_a, wire_b), wire_a != dst) - segmk.add_tile_tag(tile_from_pip, '{}.{}'.format(wire_b, wire_a), wire_a == dst) + b_to_a = wire_a != dst + a_to_b = not b_to_a - for tile, gclks in gclks_in_use.items(): - for gclk in range(2): - segmk.add_tile_tag(tile, 'GCLK{}_ENABLED'.format(gclk), gclk in gclks) + segmk.add_tile_tag(tile_from_pip, '{}.{}'.format(wire_a, wire_b), b_to_a) + segmk.add_tile_tag(tile_from_pip, '{}.{}'.format(wire_b, wire_a), a_to_b) + + clock_column.enable_rebuf(tile_from_pip, wire_a) + + for tile, gclk, active_below, active_above in clock_column.yield_rebuf_state(): + segmk.add_tile_tag(tile, 'GCLK{}_ENABLE_ABOVE'.format(gclk), active_above) + segmk.add_tile_tag(tile, 'GCLK{}_ENABLE_BELOW'.format(gclk), active_below) segmk.compile() segmk.write(allow_empty=True) diff --git a/fuzzers/043-clk-rebuf-pips/generate.tcl b/fuzzers/043-clk-rebuf-pips/generate.tcl index c83cf947..64bf1204 100644 --- a/fuzzers/043-clk-rebuf-pips/generate.tcl +++ b/fuzzers/043-clk-rebuf-pips/generate.tcl @@ -1,5 +1,28 @@ source "$::env(XRAY_DIR)/utils/utils.tcl" +proc write_pip_txtdata {filename} { + puts "FUZ([pwd]): Writing $filename." + set fp [open $filename w] + set nets [get_nets -hierarchical] + set nnets [llength $nets] + set neti 0 + foreach net $nets { + incr neti + if {($neti % 100) == 0 } { + puts "FUZ([pwd]): Dumping pips from net $net ($neti / $nnets)" + } + foreach pip [get_pips -of_objects $net] { + set tile [get_tiles -of_objects $pip] + set src_wire [get_wires -uphill -of_objects $pip] + set dst_wire [get_wires -downhill -of_objects $pip] + set num_pips [llength [get_nodes -uphill -of_objects [get_nodes -of_objects $dst_wire]]] + set dir_prop [get_property IS_DIRECTIONAL $pip] + puts $fp "$tile $pip $src_wire $dst_wire $num_pips $dir_prop" + } + } + close $fp +} + proc write_route_data {filename} { set fp [open $filename w] foreach net [get_nets -hierarchical] { @@ -24,7 +47,8 @@ proc run {} { write_checkpoint -force design.dcp write_bitstream -force design.bit - write_route_data design.txt + write_route_data route.txt + write_pip_txtdata pips.txt } run diff --git a/fuzzers/043-clk-rebuf-pips/top.py b/fuzzers/043-clk-rebuf-pips/top.py index b56fa135..3adc4605 100644 --- a/fuzzers/043-clk-rebuf-pips/top.py +++ b/fuzzers/043-clk-rebuf-pips/top.py @@ -81,10 +81,7 @@ module top(); for opt in itertools.combinations(bufhce_sites, count+1): opts.append(opt) - for gclk in gclks[:2]: - #if random.random() < .2: - # continue - + for gclk in gclks: for tile_name, sites in random.choice(opts): for site in sorted(sites): print(""" diff --git a/utils/mergedb.sh b/utils/mergedb.sh index 6c9c0e0e..62164dc4 100755 --- a/utils/mergedb.sh +++ b/utils/mergedb.sh @@ -83,6 +83,9 @@ case "$1" in clk_bufg_top_r) sed < "$2" > "$tmp1" -e 's/^CLK_BUFG\./CLK_BUFG_TOP_R./' ;; + clk_bufg_rebuf) + cp "$2" "$tmp1" ;; + liob33) cp "$2" "$tmp1" ;;