From f29fe77ea984bc9da8e322f22c40c8c30e5c3b14 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 09:54:51 -0800 Subject: [PATCH 01/10] Add initial REBUF pips. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/005-tilegrid/generate_full.py | 30 +++++++ fuzzers/043-clk-rebuf-pips/Makefile | 22 +++++ fuzzers/043-clk-rebuf-pips/bits.dbf | 0 fuzzers/043-clk-rebuf-pips/generate.py | 60 ++++++++++++++ fuzzers/043-clk-rebuf-pips/generate.tcl | 30 +++++++ fuzzers/043-clk-rebuf-pips/top.py | 105 ++++++++++++++++++++++++ 6 files changed, 247 insertions(+) create mode 100644 fuzzers/043-clk-rebuf-pips/Makefile create mode 100644 fuzzers/043-clk-rebuf-pips/bits.dbf create mode 100644 fuzzers/043-clk-rebuf-pips/generate.py create mode 100644 fuzzers/043-clk-rebuf-pips/generate.tcl create mode 100644 fuzzers/043-clk-rebuf-pips/top.py diff --git a/fuzzers/005-tilegrid/generate_full.py b/fuzzers/005-tilegrid/generate_full.py index dbb02a2b..1203d6d3 100644 --- a/fuzzers/005-tilegrid/generate_full.py +++ b/fuzzers/005-tilegrid/generate_full.py @@ -1,4 +1,5 @@ #!/usr/bin/env python3 +import copy import json from utils import xjson ''' @@ -209,6 +210,34 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): tile_name = next_tile tile = database[tile_name] +def propagate_rebuf(database, tiles_by_grid): + """ Writing a fuzzer for the CLK_BUFG_REBUF tiles is hard, so propigate from CLK_HROW tiles. + + In the clock column, there is a CLK_BUFG_REBUF above and below the CLK_HROW + tile. Each clock column appears to use the same offsets, so propigdate + the base address and frame count, and update the offset and word count. + + """ + for tile_name in sorted(database.keys()): + tile = database[tile_name] + + if tile['type'] not in ['CLK_HROW_BOT_R', 'CLK_HROW_TOP_R']: + continue + + rebuf_below = tiles_by_grid[(tile['grid_x'], tile['grid_y'] - 12)] + assert database[rebuf_below]['type'] == 'CLK_BUFG_REBUF', database[rebuf_below]['type'] + rebuf_above = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 13)] + assert database[rebuf_above]['type'] == 'CLK_BUFG_REBUF', database[rebuf_below]['type'] + + 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_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 + def run(json_in_fn, json_out_fn, verbose=False): # Load input files @@ -217,6 +246,7 @@ def run(json_in_fn, json_out_fn, verbose=False): propagate_INT_lr_bits(database, tiles_by_grid, verbose=verbose) propagate_INT_bits_in_column(database, tiles_by_grid) + propagate_rebuf(database, tiles_by_grid) # Save xjson.pprint(open(json_out_fn, "w"), database) diff --git a/fuzzers/043-clk-rebuf-pips/Makefile b/fuzzers/043-clk-rebuf-pips/Makefile new file mode 100644 index 00000000..ff3d9fa7 --- /dev/null +++ b/fuzzers/043-clk-rebuf-pips/Makefile @@ -0,0 +1,22 @@ +N ?= 50 + +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 \ + $(addsuffix /segdata_clk_bufg_rebuf.txt,$(SPECIMENS)) + +build/segbits_clk_bufg_rebuf.db: build/segbits_clk_bufg_rebuf.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ + --seg-fn-in build/segbits_clk_bufg_rebuf.rdb \ + --seg-fn-out build/segbits_clk_bufg_rebuf.db + ${XRAY_MASKMERGE} build/mask_clk_bufg_rebuf.db \ + $(addsuffix /segdata_clk_bufg_rebuf.txt,$(SPECIMENS)) + +pushdb: database + ${XRAY_MERGEDB} clk_bufg_rebuf build/segbits_clk_bufg_rebuf.db + ${XRAY_MERGEDB} mask_clk_bufg_rebuf build/mask_clk_bufg_rebuf.db + +.PHONY: database pushdb diff --git a/fuzzers/043-clk-rebuf-pips/bits.dbf b/fuzzers/043-clk-rebuf-pips/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/043-clk-rebuf-pips/generate.py b/fuzzers/043-clk-rebuf-pips/generate.py new file mode 100644 index 00000000..4204aaa8 --- /dev/null +++ b/fuzzers/043-clk-rebuf-pips/generate.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 + +from prjxray.segmaker import Segmaker +import re + +REBUF_GCLK = re.compile('^CLK_BUFG_REBUF_R_CK_GCLK([0-9]+)_BOT$') +def main(): + segmk = Segmaker("design.bits") + + print("Loading tags from design.txt.") + + gclks_in_use = {} + with open("design.txt", "r") as f: + for line in f: + if 'CLK_BUFG_REBUF' not in line: + continue + + parts = line.replace('{', '').replace('}','').strip().replace('\t', ' ').split(' ') + dst = parts[0] + pip = parts[3] + + tile_from_pip, pip = pip.split('/') + + if 'CLK_BUFG_REBUF' not in tile_from_pip: + continue + + tile_type, pip = pip.split('.') + assert tile_type == 'CLK_BUFG_REBUF' + + wire_a, wire_b = pip.split('<<->>') + + tile_from_wire, dst = dst.split('/') + + 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) + 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) + + 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.compile() + segmk.write(allow_empty=True) + + +if __name__ == '__main__': + main() diff --git a/fuzzers/043-clk-rebuf-pips/generate.tcl b/fuzzers/043-clk-rebuf-pips/generate.tcl new file mode 100644 index 00000000..c83cf947 --- /dev/null +++ b/fuzzers/043-clk-rebuf-pips/generate.tcl @@ -0,0 +1,30 @@ +source "$::env(XRAY_DIR)/utils/utils.tcl" + +proc write_route_data {filename} { + set fp [open $filename w] + foreach net [get_nets -hierarchical] { + puts $fp "Net $net route:" + puts $fp [report_route_status -of_objects $net -return_string] + puts $fp "" + } + close $fp +} + +proc run {} { + create_project -force -part $::env(XRAY_PART) design design + read_verilog top.v + synth_design -top top + + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] + + place_design + route_design + + write_checkpoint -force design.dcp + write_bitstream -force design.bit + write_route_data design.txt +} + +run diff --git a/fuzzers/043-clk-rebuf-pips/top.py b/fuzzers/043-clk-rebuf-pips/top.py new file mode 100644 index 00000000..b56fa135 --- /dev/null +++ b/fuzzers/043-clk-rebuf-pips/top.py @@ -0,0 +1,105 @@ +import os +import itertools +import re +import random +random.seed(int(os.getenv("SEED"), 16)) +from prjxray import util +from prjxray.db import Database + +XY_RE = re.compile('^BUFHCE_X([0-9]+)Y([0-9]+)$') +BUFGCTRL_XY_RE = re.compile('^BUFGCTRL_X([0-9]+)Y([0-9]+)$') +""" +BUFHCE's can be driven from: + +MMCME2_ADV +BUFHCE +PLLE2_ADV +BUFGCTRL +""" + + +def get_xy(s): + m = BUFGCTRL_XY_RE.match(s) + x = int(m.group(1)) + y = int(m.group(2)) + return x, y + + +def gen_sites(desired_site_type): + db = Database(util.get_db_root()) + grid = db.grid() + + for tile_name in sorted(grid.tiles()): + loc = grid.loc_of_tilename(tile_name) + gridinfo = grid.gridinfo_at_loc(loc) + for site, site_type in gridinfo.sites.items(): + if site_type == desired_site_type: + yield site + + +def gen_bufhce_sites(): + db = Database(util.get_db_root()) + grid = db.grid() + for tile_name in sorted(grid.tiles()): + loc = grid.loc_of_tilename(tile_name) + gridinfo = grid.gridinfo_at_loc(loc) + sites = [] + + for site, site_type in gridinfo.sites.items(): + if site_type == 'BUFHCE': + sites.append(site) + + if sites: + yield tile_name, set(sites) + +def main(): + print(''' +module top(); + ''') + + gclks = [] + for site in sorted(gen_sites("BUFGCTRL"), key=get_xy): + wire_name = 'clk_{}'.format(site) + gclks.append(wire_name) + + print( + """ + wire {wire_name}; + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFG bufg_{site} ( + .O({wire_name}) + ); + """.format( + site=site, + wire_name=wire_name, + )) + + bufhce_sites = list(gen_bufhce_sites()) + + opts = [] + for count in range(len(bufhce_sites)): + for opt in itertools.combinations(bufhce_sites, count+1): + opts.append(opt) + + for gclk in gclks[:2]: + #if random.random() < .2: + # continue + + for tile_name, sites in random.choice(opts): + for site in sorted(sites): + print(""" + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFHCE buf_{site} ( + .I({wire_name}) + );""".format( + site=site, + wire_name=gclk, + )) + sites.remove(site) + break + + print("endmodule") + + +if __name__ == '__main__': + main() From 5bebeb6c0dbc5b6de8f209b33b973537dc44245d Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 10:54:09 -0800 Subject: [PATCH 02/10] Add CLK_BUFG to tilegrid. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/005-tilegrid/Makefile | 5 ++ fuzzers/005-tilegrid/add_tdb.py | 1 + fuzzers/005-tilegrid/clk_bufg/Makefile | 4 ++ fuzzers/005-tilegrid/clk_bufg/generate.tcl | 21 ++++++++ fuzzers/005-tilegrid/clk_bufg/top.py | 62 ++++++++++++++++++++++ 5 files changed, 93 insertions(+) create mode 100644 fuzzers/005-tilegrid/clk_bufg/Makefile create mode 100644 fuzzers/005-tilegrid/clk_bufg/generate.tcl create mode 100644 fuzzers/005-tilegrid/clk_bufg/top.py diff --git a/fuzzers/005-tilegrid/Makefile b/fuzzers/005-tilegrid/Makefile index 83556908..e6cffaad 100644 --- a/fuzzers/005-tilegrid/Makefile +++ b/fuzzers/005-tilegrid/Makefile @@ -14,6 +14,7 @@ TILEGRID_TDB_DEPENDENCIES += fifo_int/build/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += cfg_int/build/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += monitor_int/build/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += clk_hrow/build/segbits_tilegrid.tdb +TILEGRID_TDB_DEPENDENCIES += clk_bufg/build/segbits_tilegrid.tdb GENERATE_FULL_ARGS= ifeq (${XRAY_DATABASE}, zynq7) @@ -100,6 +101,9 @@ orphan_int_column/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json clk_hrow/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json cd clk_hrow && $(MAKE) +clk_bufg/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json + cd clk_bufg && $(MAKE) + build/tilegrid_tdb.json: add_tdb.py $(TILEGRID_TDB_DEPENDENCIES) python3 add_tdb.py \ --fn-in build/basicdb/tilegrid.json \ @@ -134,6 +138,7 @@ clean: cd cfg_int && $(MAKE) clean cd orphan_int_column && $(MAKE) clean cd clk_hrow && $(MAKE) clean + cd clk_bufg && $(MAKE) clean .PHONY: database pushdb clean run diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py index b27d5960..793b2a3f 100644 --- a/fuzzers/005-tilegrid/add_tdb.py +++ b/fuzzers/005-tilegrid/add_tdb.py @@ -85,6 +85,7 @@ def run(fn_in, fn_out, verbose=False): ("clb/build/segbits_tilegrid.tdb", 36, 2), ("dsp/build/segbits_tilegrid.tdb", 28, 10), ("clk_hrow/build/segbits_tilegrid.tdb", 30, 7), + ("clk_bufg/build/segbits_tilegrid.tdb", 30, 8), ("clb_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("iob_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("bram_int/build/segbits_tilegrid.tdb", int_frames, int_words), diff --git a/fuzzers/005-tilegrid/clk_bufg/Makefile b/fuzzers/005-tilegrid/clk_bufg/Makefile new file mode 100644 index 00000000..68c698be --- /dev/null +++ b/fuzzers/005-tilegrid/clk_bufg/Makefile @@ -0,0 +1,4 @@ +N ?= 5 +GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 1B" +include ../fuzzaddr/common.mk + diff --git a/fuzzers/005-tilegrid/clk_bufg/generate.tcl b/fuzzers/005-tilegrid/clk_bufg/generate.tcl new file mode 100644 index 00000000..49e429ba --- /dev/null +++ b/fuzzers/005-tilegrid/clk_bufg/generate.tcl @@ -0,0 +1,21 @@ +source "$::env(XRAY_DIR)/utils/utils.tcl" + +proc run {} { + create_project -force -part $::env(XRAY_PART) design design + read_verilog top.v + synth_design -top top + + #set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk] + + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] + + place_design + route_design + + write_checkpoint -force design.dcp + write_bitstream -force design.bit +} + +run diff --git a/fuzzers/005-tilegrid/clk_bufg/top.py b/fuzzers/005-tilegrid/clk_bufg/top.py new file mode 100644 index 00000000..95cdea87 --- /dev/null +++ b/fuzzers/005-tilegrid/clk_bufg/top.py @@ -0,0 +1,62 @@ +import os +import random +random.seed(int(os.getenv("SEED"), 16)) +from prjxray import util +from prjxray.db import Database + + +def gen_sites(): + db = Database(util.get_db_root()) + grid = db.grid() + for tile_name in grid.tiles(): + loc = grid.loc_of_tilename(tile_name) + gridinfo = grid.gridinfo_at_loc(loc) + sites = [] + for site, site_type in gridinfo.sites.items(): + if site_type == 'BUFGCTRL': + sites.append(site) + + if sites: + yield tile_name, sorted(sites) + + +def write_params(params): + pinstr = 'tile,val,site\n' + for tile, (site, val) in sorted(params.items()): + pinstr += '%s,%s,%s\n' % (tile, val, site) + open('params.csv', 'w').write(pinstr) + + +def run(): + print(''' +module top(); + ''') + + params = {} + + sites = list(gen_sites()) + for (tile_name, sites), isone in zip(sites, + util.gen_fuzz_states(len(sites))): + site_name = sites[0] + params[tile_name] = (site_name, isone) + + print( + ''' + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFGCTRL #( + .INIT_OUT({isone}) + ) buf_{site} ( + .CE0(1), + .S0(1) + ); +'''.format( + site=site_name, + isone=isone, + )) + + print("endmodule") + write_params(params) + + +if __name__ == '__main__': + run() From 2311f251497e22596beae021cd5bd5a4e2e40f9f Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 10:55:41 -0800 Subject: [PATCH 03/10] Add initial BUFG config bits. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/042-clk-bufg-config/Makefile | 22 ++++ fuzzers/042-clk-bufg-config/bits.dbf | 0 fuzzers/042-clk-bufg-config/generate.py | 67 ++++++++++ fuzzers/042-clk-bufg-config/generate.tcl | 17 +++ fuzzers/042-clk-bufg-config/top.py | 148 +++++++++++++++++++++++ fuzzers/Makefile | 2 + utils/mergedb.sh | 5 + 7 files changed, 261 insertions(+) create mode 100644 fuzzers/042-clk-bufg-config/Makefile create mode 100644 fuzzers/042-clk-bufg-config/bits.dbf create mode 100644 fuzzers/042-clk-bufg-config/generate.py create mode 100644 fuzzers/042-clk-bufg-config/generate.tcl create mode 100644 fuzzers/042-clk-bufg-config/top.py diff --git a/fuzzers/042-clk-bufg-config/Makefile b/fuzzers/042-clk-bufg-config/Makefile new file mode 100644 index 00000000..86c076a5 --- /dev/null +++ b/fuzzers/042-clk-bufg-config/Makefile @@ -0,0 +1,22 @@ +N ?= 50 + +include ../fuzzer.mk + +database: build/segbits_clk_bufg.db + +build/segbits_clk_bufg.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -o build/segbits_clk_bufg.rdb $(addsuffix /segdata_clk_bufg_top_r.txt,$(SPECIMENS)) $(addsuffix /segdata_clk_bufg_bot_r.txt,$(SPECIMENS)) + +build/segbits_clk_bufg.db: build/segbits_clk_bufg.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ + --seg-fn-in build/segbits_clk_bufg.rdb \ + --seg-fn-out build/segbits_clk_bufg.db + ${XRAY_MASKMERGE} build/mask_clk_bufg.db $(addsuffix /segdata_clk_bufg_top_r.txt,$(SPECIMENS)) $(addsuffix /segdata_clk_bufg_bot_r.txt,$(SPECIMENS)) + +pushdb: database + ${XRAY_MERGEDB} clk_bufg_bot_r build/segbits_clk_bufg.db + ${XRAY_MERGEDB} clk_bufg_top_r build/segbits_clk_bufg.db + ${XRAY_MERGEDB} mask_clk_bufg_bot_r build/mask_clk_bufg.db + ${XRAY_MERGEDB} mask_clk_bufg_top_r build/mask_clk_bufg.db + +.PHONY: database pushdb diff --git a/fuzzers/042-clk-bufg-config/bits.dbf b/fuzzers/042-clk-bufg-config/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/042-clk-bufg-config/generate.py b/fuzzers/042-clk-bufg-config/generate.py new file mode 100644 index 00000000..ece8dcef --- /dev/null +++ b/fuzzers/042-clk-bufg-config/generate.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +import json + +from prjxray.segmaker import Segmaker + + +def main(): + segmk = Segmaker("design.bits") + + print("Loading tags") + with open('params.json') as f: + params = json.load(f) + + for row in params: + base_name = 'BUFGCTRL_X{}Y{}'.format(row['x'], row['y']) + + segmk.add_site_tag( + row['site'], '{}.IN_USE'.format(base_name), row['IN_USE']) + + if not row['IN_USE']: + continue + + for param in ( + 'INIT_OUT', + 'IS_IGNORE0_INVERTED', + 'IS_IGNORE1_INVERTED', + ): + segmk.add_site_tag( + row['site'], '{}.{}'.format(base_name, param), row[param]) + + if row['connect0'] and row['connect1']: + for param in ( + 'PRESELECT_I0', + ): + segmk.add_site_tag( + row['site'], '{}.Z{}'.format(base_name, param), 1 ^ row[param]) + + for param in ( + 'PRESELECT_I1', + ): + segmk.add_site_tag( + row['site'], '{}.{}'.format(base_name, param), row[param]) + + if row['connect0']: + for param, tag in ( + ('IS_CE0_INVERTED', 'ZINV_CE0'), + ('IS_S0_INVERTED', 'ZINV_S0') + ): + segmk.add_site_tag( + row['site'], '{}.{}'.format(base_name, tag), 1 ^ row[param]) + + if row['connect1']: + for param, tag in ( + ('IS_CE1_INVERTED', 'ZINV_CE1'), + ('IS_S1_INVERTED', 'ZINV_S1') + ): + segmk.add_site_tag( + row['site'], '{}.{}'.format(base_name, tag), 1 ^ row[param]) + + + segmk.compile() + segmk.write() + + +if __name__ == '__main__': + main() diff --git a/fuzzers/042-clk-bufg-config/generate.tcl b/fuzzers/042-clk-bufg-config/generate.tcl new file mode 100644 index 00000000..3044e100 --- /dev/null +++ b/fuzzers/042-clk-bufg-config/generate.tcl @@ -0,0 +1,17 @@ +proc run {} { + create_project -force -part $::env(XRAY_PART) design design + read_verilog top.v + synth_design -top top + + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] + + place_design + route_design + + write_checkpoint -force design.dcp + write_bitstream -force design.bit +} + +run diff --git a/fuzzers/042-clk-bufg-config/top.py b/fuzzers/042-clk-bufg-config/top.py new file mode 100644 index 00000000..0100a156 --- /dev/null +++ b/fuzzers/042-clk-bufg-config/top.py @@ -0,0 +1,148 @@ +import json +import os +import re +import random +random.seed(int(os.getenv("SEED"), 16)) +from prjxray import util +from prjxray import verilog +from prjxray.db import Database + +XY_RE = re.compile('^BUFGCTRL_X([0-9]+)Y([0-9]+)$') + + +def gen_sites(): + db = Database(util.get_db_root()) + grid = db.grid() + db = Database(util.get_db_root()) + grid = db.grid() + for tile_name in sorted(grid.tiles()): + loc = grid.loc_of_tilename(tile_name) + gridinfo = grid.gridinfo_at_loc(loc) + sites = [] + + xs = [] + ys = [] + for site, site_type in gridinfo.sites.items(): + if site_type == 'BUFGCTRL': + m = re.match(XY_RE, site) + assert m, site + x = int(m.group(1)) + y = int(m.group(2)) + xs.append(x) + ys.append(y) + + sites.append((site, x, y)) + + if sites: + yield tile_name, min(xs), min(ys), sorted(sites) + + +def main(): + print(''' +module top(); + ''') + + params_list = [] + for tile_name, x_min, y_min, sites in gen_sites(): + + for site, x, y in sites: + params = {} + params['tile'] = tile_name + params['site'] = site + params['x'] = x - x_min + params['y'] = y - y_min + params['IN_USE'] = random.random() > .1 + + if params['IN_USE']: + params['INIT_OUT'] = random.randint(0, 1) + params['IS_CE0_INVERTED'] = random.randint(0, 1) + params['IS_CE1_INVERTED'] = random.randint(0, 1) + params['IS_S0_INVERTED'] = random.randint(0, 1) + params['IS_S1_INVERTED'] = random.randint(0, 1) + params['IS_IGNORE0_INVERTED'] = random.randint(0, 1) + params['IS_IGNORE1_INVERTED'] = random.randint(0, 1) + params['PRESELECT_I0'] = 0 + params['PRESELECT_I1'] = 0 + + params['connect0'] = random.randint(0, 1) + + if params['connect0']: + params['connect1'] = random.randint(0, 1) + else: + params['connect1'] = 1 + + if params['connect0'] and params['connect1']: + params['PRESELECT_I0'] = random.randint(0, 1) + if not params['PRESELECT_I0']: + params['PRESELECT_I1'] = random.randint(0, 1) + else: + params['PRESELECT_I1'] = 0 + + params['connections'] = """ + .CE0(ce0_{site}), + .S0(s0_{site}), + .CE1(ce1_{site}), + .S1(s1_{site}) + """.format(site=site) + elif params['connect0']: + params['connections'] = """ + .CE0(ce0_{site}), + .S0(s0_{site}) + """.format(site=site) + elif params['connect1']: + params['connections'] = """ + .CE1(ce1_{site}), + .S1(s1_{site}) + """.format(site=site) + + + + print( + ''' + wire ce0_{site}; + wire s0_{site}; + (* KEEP, DONT_TOUCH *) + LUT6 l0_{site} ( + .O(ce0_{site}) + ); + (* KEEP, DONT_TOUCH *) + LUT6 l1_{site} ( + .O(s0_{site}) + ); + + wire ce1_{site}; + wire s1_{site}; + (* KEEP, DONT_TOUCH *) + LUT6 l2_{site} ( + .O(ce1_{site}) + ); + (* KEEP, DONT_TOUCH *) + LUT6 l3_{site} ( + .O(s1_{site}) + ); + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFGCTRL #( + .INIT_OUT({INIT_OUT}), + .PRESELECT_I0({PRESELECT_I0}), + .PRESELECT_I1({PRESELECT_I1}), + .IS_CE0_INVERTED({IS_CE0_INVERTED}), + .IS_CE1_INVERTED({IS_CE1_INVERTED}), + .IS_S0_INVERTED({IS_S0_INVERTED}), + .IS_S1_INVERTED({IS_S1_INVERTED}), + .IS_IGNORE0_INVERTED({IS_IGNORE0_INVERTED}), + .IS_IGNORE1_INVERTED({IS_IGNORE1_INVERTED}) + ) buf_{site} ( + {connections} + ); + '''.format(**params)) + + params_list.append(params) + + print("endmodule") + + with open('params.json', 'w') as f: + json.dump(params_list, f, indent=2) + + +if __name__ == '__main__': + main() diff --git a/fuzzers/Makefile b/fuzzers/Makefile index 32ecad40..d98c3ec6 100644 --- a/fuzzers/Makefile +++ b/fuzzers/Makefile @@ -72,6 +72,8 @@ $(eval $(call fuzzer,028-fifo-config,005-tilegrid)) $(eval $(call fuzzer,029-bram-fifo-config,005-tilegrid)) $(eval $(call fuzzer,040-clk-hrow-config,005-tilegrid)) $(eval $(call fuzzer,041-clk-hrow-pips,005-tilegrid)) +$(eval $(call fuzzer,042-clk-bufg-config,005-tilegrid)) +$(eval $(call fuzzer,043-clk-rebuf-pips,005-tilegrid)) $(eval $(call fuzzer,050-pip-seed,005-tilegrid)) $(eval $(call fuzzer,051-pip-imuxlout-bypalts,050-pip-seed)) $(eval $(call fuzzer,052-pip-clkin,050-pip-seed)) diff --git a/utils/mergedb.sh b/utils/mergedb.sh index 2f955c88..6c9c0e0e 100755 --- a/utils/mergedb.sh +++ b/utils/mergedb.sh @@ -78,6 +78,11 @@ case "$1" in clk_hrow_top_r) sed < "$2" > "$tmp1" -e 's/^CLK_HROW\./CLK_HROW_TOP_R./' ;; + clk_bufg_bot_r) + sed < "$2" > "$tmp1" -e 's/^CLK_BUFG\./CLK_BUFG_BOT_R./' ;; + clk_bufg_top_r) + sed < "$2" > "$tmp1" -e 's/^CLK_BUFG\./CLK_BUFG_TOP_R./' ;; + liob33) cp "$2" "$tmp1" ;; From 88b2fc6d35820acb5938e7d2edcc6187b72817e7 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 13:22:29 -0800 Subject: [PATCH 04/10] Fix 043 to document remaining bits. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/005-tilegrid/generate_full.py | 8 +-- fuzzers/043-clk-rebuf-pips/Makefile | 4 +- fuzzers/043-clk-rebuf-pips/generate.py | 95 ++++++++++++++++++++----- fuzzers/043-clk-rebuf-pips/generate.tcl | 26 ++++++- fuzzers/043-clk-rebuf-pips/top.py | 5 +- utils/mergedb.sh | 3 + 6 files changed, 113 insertions(+), 28 deletions(-) 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" ;; From e7d32dadb403cbedf79ed54bced1c40eb5138665 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 15:17:59 -0800 Subject: [PATCH 05/10] Use create_xy_fun. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/042-clk-bufg-config/top.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/fuzzers/042-clk-bufg-config/top.py b/fuzzers/042-clk-bufg-config/top.py index 0100a156..f26b75f9 100644 --- a/fuzzers/042-clk-bufg-config/top.py +++ b/fuzzers/042-clk-bufg-config/top.py @@ -1,18 +1,13 @@ import json import os -import re import random random.seed(int(os.getenv("SEED"), 16)) from prjxray import util -from prjxray import verilog from prjxray.db import Database -XY_RE = re.compile('^BUFGCTRL_X([0-9]+)Y([0-9]+)$') - def gen_sites(): - db = Database(util.get_db_root()) - grid = db.grid() + xy_fun = util.create_xy_fun('BUFGCTRL_') db = Database(util.get_db_root()) grid = db.grid() for tile_name in sorted(grid.tiles()): @@ -24,10 +19,7 @@ def gen_sites(): ys = [] for site, site_type in gridinfo.sites.items(): if site_type == 'BUFGCTRL': - m = re.match(XY_RE, site) - assert m, site - x = int(m.group(1)) - y = int(m.group(2)) + x, y = xy_fun() xs.append(x) ys.append(y) From 9ccc58b0771bb03528089cb5c6c81da9e33b08e1 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 15:18:25 -0800 Subject: [PATCH 06/10] Run make format. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/005-tilegrid/generate_full.py | 16 ++++++++---- fuzzers/042-clk-bufg-config/generate.py | 32 ++++++++++-------------- fuzzers/042-clk-bufg-config/top.py | 2 -- fuzzers/043-clk-rebuf-pips/generate.py | 33 ++++++++++++++++--------- fuzzers/043-clk-rebuf-pips/top.py | 8 +++--- 5 files changed, 51 insertions(+), 40 deletions(-) diff --git a/fuzzers/005-tilegrid/generate_full.py b/fuzzers/005-tilegrid/generate_full.py index e3a7290c..b75de807 100644 --- a/fuzzers/005-tilegrid/generate_full.py +++ b/fuzzers/005-tilegrid/generate_full.py @@ -210,6 +210,7 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): tile_name = next_tile tile = database[tile_name] + def propagate_rebuf(database, tiles_by_grid): """ Writing a fuzzer for the CLK_BUFG_REBUF tiles is hard, so propigate from CLK_HROW tiles. @@ -225,16 +226,21 @@ def propagate_rebuf(database, tiles_by_grid): continue rebuf_below = tiles_by_grid[(tile['grid_x'], tile['grid_y'] - 12)] - assert database[rebuf_below]['type'] == 'CLK_BUFG_REBUF', database[rebuf_below]['type'] + assert database[rebuf_below]['type'] == 'CLK_BUFG_REBUF', database[ + rebuf_below]['type'] rebuf_above = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 13)] - assert database[rebuf_above]['type'] == 'CLK_BUFG_REBUF', database[rebuf_below]['type'] + assert database[rebuf_above]['type'] == 'CLK_BUFG_REBUF', database[ + rebuf_below]['type'] - 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']) + 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'] = 73 database[rebuf_below]['bits']['CLB_IO_CLK']['words'] = 4 - database[rebuf_above]['bits'] = copy.deepcopy(database[tile_name]['bits']) + database[rebuf_above]['bits'] = copy.deepcopy( + database[tile_name]['bits']) database[rebuf_above]['bits']['CLB_IO_CLK']['offset'] = 24 database[rebuf_above]['bits']['CLB_IO_CLK']['words'] = 4 diff --git a/fuzzers/042-clk-bufg-config/generate.py b/fuzzers/042-clk-bufg-config/generate.py index ece8dcef..4895b43e 100644 --- a/fuzzers/042-clk-bufg-config/generate.py +++ b/fuzzers/042-clk-bufg-config/generate.py @@ -25,39 +25,33 @@ def main(): 'INIT_OUT', 'IS_IGNORE0_INVERTED', 'IS_IGNORE1_INVERTED', - ): + ): segmk.add_site_tag( row['site'], '{}.{}'.format(base_name, param), row[param]) if row['connect0'] and row['connect1']: - for param in ( - 'PRESELECT_I0', - ): + for param in ('PRESELECT_I0', ): segmk.add_site_tag( - row['site'], '{}.Z{}'.format(base_name, param), 1 ^ row[param]) + row['site'], '{}.Z{}'.format(base_name, param), + 1 ^ row[param]) - for param in ( - 'PRESELECT_I1', - ): + for param in ('PRESELECT_I1', ): segmk.add_site_tag( row['site'], '{}.{}'.format(base_name, param), row[param]) if row['connect0']: - for param, tag in ( - ('IS_CE0_INVERTED', 'ZINV_CE0'), - ('IS_S0_INVERTED', 'ZINV_S0') - ): + for param, tag in (('IS_CE0_INVERTED', 'ZINV_CE0'), + ('IS_S0_INVERTED', 'ZINV_S0')): segmk.add_site_tag( - row['site'], '{}.{}'.format(base_name, tag), 1 ^ row[param]) + row['site'], '{}.{}'.format(base_name, tag), + 1 ^ row[param]) if row['connect1']: - for param, tag in ( - ('IS_CE1_INVERTED', 'ZINV_CE1'), - ('IS_S1_INVERTED', 'ZINV_S1') - ): + for param, tag in (('IS_CE1_INVERTED', 'ZINV_CE1'), + ('IS_S1_INVERTED', 'ZINV_S1')): segmk.add_site_tag( - row['site'], '{}.{}'.format(base_name, tag), 1 ^ row[param]) - + row['site'], '{}.{}'.format(base_name, tag), + 1 ^ row[param]) segmk.compile() segmk.write() diff --git a/fuzzers/042-clk-bufg-config/top.py b/fuzzers/042-clk-bufg-config/top.py index f26b75f9..3d56beab 100644 --- a/fuzzers/042-clk-bufg-config/top.py +++ b/fuzzers/042-clk-bufg-config/top.py @@ -87,8 +87,6 @@ module top(); .S1(s1_{site}) """.format(site=site) - - print( ''' wire ce0_{site}; diff --git a/fuzzers/043-clk-rebuf-pips/generate.py b/fuzzers/043-clk-rebuf-pips/generate.py index 367a2837..d88a2d49 100644 --- a/fuzzers/043-clk-rebuf-pips/generate.py +++ b/fuzzers/043-clk-rebuf-pips/generate.py @@ -9,11 +9,13 @@ 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) @@ -32,12 +34,15 @@ class ClockColumn(object): 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])) + _, 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 + # 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)] + 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. @@ -47,7 +52,7 @@ class ClockColumn(object): gclk = gclk_of_wire(wire) self.gclk_columns[gclk][rebuf_idx] = True - self.gclk_columns[gclk][rebuf_idx-1] = 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 """ @@ -57,7 +62,7 @@ class ClockColumn(object): active_above = False if idx > 0: - active_below = self.gclk_columns[gclk][idx-1] + active_below = self.gclk_columns[gclk][idx - 1] if idx < len(self.gclk_columns[gclk]): active_above = self.gclk_columns[gclk][idx] @@ -79,7 +84,8 @@ def main(): if 'CLK_BUFG_REBUF' not in line: continue - parts = line.replace('{', '').replace('}','').strip().replace('\t', ' ').split(' ') + parts = line.replace('{', '').replace('}', '').strip().replace( + '\t', ' ').split(' ') dst = parts[0] pip = parts[3] @@ -104,14 +110,19 @@ def main(): b_to_a = wire_a != dst a_to_b = not b_to_a - 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) + 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) + 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/top.py b/fuzzers/043-clk-rebuf-pips/top.py index 3adc4605..769372e8 100644 --- a/fuzzers/043-clk-rebuf-pips/top.py +++ b/fuzzers/043-clk-rebuf-pips/top.py @@ -52,6 +52,7 @@ def gen_bufhce_sites(): if sites: yield tile_name, set(sites) + def main(): print(''' module top(); @@ -78,20 +79,21 @@ module top(); opts = [] for count in range(len(bufhce_sites)): - for opt in itertools.combinations(bufhce_sites, count+1): + for opt in itertools.combinations(bufhce_sites, count + 1): opts.append(opt) for gclk in gclks: for tile_name, sites in random.choice(opts): for site in sorted(sites): - print(""" + print( + """ (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE buf_{site} ( .I({wire_name}) );""".format( site=site, wire_name=gclk, - )) + )) sites.remove(site) break From 52f6f092cee6f574f83540a17d2a31a42829332f Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 15:21:51 -0800 Subject: [PATCH 07/10] Fix missing argument. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/042-clk-bufg-config/top.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzzers/042-clk-bufg-config/top.py b/fuzzers/042-clk-bufg-config/top.py index 3d56beab..8d770d6b 100644 --- a/fuzzers/042-clk-bufg-config/top.py +++ b/fuzzers/042-clk-bufg-config/top.py @@ -19,7 +19,7 @@ def gen_sites(): ys = [] for site, site_type in gridinfo.sites.items(): if site_type == 'BUFGCTRL': - x, y = xy_fun() + x, y = xy_fun(site) xs.append(x) ys.append(y) From 73a5c0454480024f3e70a8a05759074d1b544788 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 16:33:59 -0800 Subject: [PATCH 08/10] Add _ACTIVE bits to HROW bits. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/005-tilegrid/generate_full.py | 2 +- fuzzers/041-clk-hrow-pips/Makefile | 4 +-- fuzzers/041-clk-hrow-pips/generate.py | 27 +++++++++++++++++++ .../041-clk-hrow-pips/merge_clk_entries.py | 9 +++++++ 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/fuzzers/005-tilegrid/generate_full.py b/fuzzers/005-tilegrid/generate_full.py index b75de807..4b5277c5 100644 --- a/fuzzers/005-tilegrid/generate_full.py +++ b/fuzzers/005-tilegrid/generate_full.py @@ -215,7 +215,7 @@ def propagate_rebuf(database, tiles_by_grid): """ Writing a fuzzer for the CLK_BUFG_REBUF tiles is hard, so propigate from CLK_HROW tiles. In the clock column, there is a CLK_BUFG_REBUF above and below the CLK_HROW - tile. Each clock column appears to use the same offsets, so propigdate + tile. Each clock column appears to use the same offsets, so propigate the base address and frame count, and update the offset and word count. """ diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile index 1bb8bc01..155094ec 100644 --- a/fuzzers/041-clk-hrow-pips/Makefile +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -5,7 +5,7 @@ MAKETODO_FLAGS=--no-l --pip-type clk_hrow_bot --seg-type clk_hrow_bot --re "[^\. N = 50 # These PIPs all appear to be either a 0 or 2 bit solution. -SEGMATCH_FLAGS=-m 20 -M 45 -c 2 +SEGMATCH_FLAGS=-m 20 -M 45 -c 1 SPECIMENS_DEPS=build/cmt_regions.csv A_PIPLIST=clk_hrow_bot_r.txt @@ -18,7 +18,7 @@ build/cmt_regions.csv: output_cmt.tcl cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} -o build/segbits_clk_hrow.rdb \ + ${XRAY_SEGMATCH} ${SEGMATCH_FLAGS} -o build/segbits_clk_hrow.rdb \ $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) diff --git a/fuzzers/041-clk-hrow-pips/generate.py b/fuzzers/041-clk-hrow-pips/generate.py index fe4e53c0..f9b20ba2 100644 --- a/fuzzers/041-clk-hrow-pips/generate.py +++ b/fuzzers/041-clk-hrow-pips/generate.py @@ -9,6 +9,9 @@ def main(): table = clk_table.get_clk_table() print("Loading tags from design.txt.") + + active_gclks = {} + active_clks = {} with open("design.txt", "r") as f: for line in f: tile, pip, src, dst, pnum, pdir = line.split() @@ -44,6 +47,30 @@ def main(): segmk.add_tile_tag( tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 0) + if tile not in active_clks: + active_clks[tile] = set() + + active_clks[tile].add(src) + + if 'GCLK' in src: + if src not in active_gclks: + active_gclks[src] = set() + + active_gclks[src].add(tile) + + tiles = sorted(active_clks.keys()) + + for tile in active_clks: + for src in table: + if 'GCLK' not in src: + active = src in active_clks[tile] + segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), active) + else: + if src not in active_gclks: + segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), 0) + elif tile in active_gclks[src]: + segmk.add_tile_tag(tile, '{}_ACTIVE'.format(src), 1) + segmk.compile() segmk.write() diff --git a/fuzzers/041-clk-hrow-pips/merge_clk_entries.py b/fuzzers/041-clk-hrow-pips/merge_clk_entries.py index f7e2ea27..1ddd2ebe 100644 --- a/fuzzers/041-clk-hrow-pips/merge_clk_entries.py +++ b/fuzzers/041-clk-hrow-pips/merge_clk_entries.py @@ -11,6 +11,7 @@ def main(): args = parser.parse_args() + output_features = [] hrow_outs = {} tile = None with open(args.in_segbit) as f: @@ -19,6 +20,11 @@ def main(): feature = parts[0] bits = ' '.join(parts[1:]) + # No post-processing on _ACTIVE bits. + if feature.endswith('_ACTIVE'): + output_features.append(l.strip()) + continue + tile1, dst, src = feature.split('.') if tile is None: tile = tile1 @@ -53,6 +59,9 @@ def main(): table = clk_table.get_clk_table() with open(args.out_segbit, 'w') as f: + for l in output_features: + print(l, file=f) + for dst in sorted(hrow_outs): for src in sorted(piplists[dst]): if src not in table: From 457c0cde6f467af0d30bb08f2464d902df4d1477 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 16:43:02 -0800 Subject: [PATCH 09/10] Make generic generate_top for tilegrid. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/005-tilegrid/bram_int/generate.tcl | 18 +---------------- fuzzers/005-tilegrid/cfg_int/generate.tcl | 18 +---------------- fuzzers/005-tilegrid/clk_bufg/generate.tcl | 20 +------------------ fuzzers/005-tilegrid/clk_hrow/generate.tcl | 20 +------------------ fuzzers/005-tilegrid/dsp/generate.tcl | 18 +---------------- fuzzers/005-tilegrid/fifo_int/generate.tcl | 18 +---------------- fuzzers/005-tilegrid/monitor_int/generate.tcl | 18 +---------------- utils/utils.tcl | 17 ++++++++++++++++ 8 files changed, 24 insertions(+), 123 deletions(-) diff --git a/fuzzers/005-tilegrid/bram_int/generate.tcl b/fuzzers/005-tilegrid/bram_int/generate.tcl index 9e8cab8a..5a69791f 100644 --- a/fuzzers/005-tilegrid/bram_int/generate.tcl +++ b/fuzzers/005-tilegrid/bram_int/generate.tcl @@ -1,19 +1,3 @@ source "$::env(XRAY_DIR)/utils/utils.tcl" -proc run {} { - create_project -force -part $::env(XRAY_PART) design design - read_verilog top.v - synth_design -top top - - set_property CFGBVS VCCO [current_design] - set_property CONFIG_VOLTAGE 3.3 [current_design] - set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] - - place_design - route_design - - write_checkpoint -force design.dcp - write_bitstream -force design.bit -} - -run +generate_top diff --git a/fuzzers/005-tilegrid/cfg_int/generate.tcl b/fuzzers/005-tilegrid/cfg_int/generate.tcl index 9e8cab8a..5a69791f 100644 --- a/fuzzers/005-tilegrid/cfg_int/generate.tcl +++ b/fuzzers/005-tilegrid/cfg_int/generate.tcl @@ -1,19 +1,3 @@ source "$::env(XRAY_DIR)/utils/utils.tcl" -proc run {} { - create_project -force -part $::env(XRAY_PART) design design - read_verilog top.v - synth_design -top top - - set_property CFGBVS VCCO [current_design] - set_property CONFIG_VOLTAGE 3.3 [current_design] - set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] - - place_design - route_design - - write_checkpoint -force design.dcp - write_bitstream -force design.bit -} - -run +generate_top diff --git a/fuzzers/005-tilegrid/clk_bufg/generate.tcl b/fuzzers/005-tilegrid/clk_bufg/generate.tcl index 49e429ba..5a69791f 100644 --- a/fuzzers/005-tilegrid/clk_bufg/generate.tcl +++ b/fuzzers/005-tilegrid/clk_bufg/generate.tcl @@ -1,21 +1,3 @@ source "$::env(XRAY_DIR)/utils/utils.tcl" -proc run {} { - create_project -force -part $::env(XRAY_PART) design design - read_verilog top.v - synth_design -top top - - #set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk] - - set_property CFGBVS VCCO [current_design] - set_property CONFIG_VOLTAGE 3.3 [current_design] - set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] - - place_design - route_design - - write_checkpoint -force design.dcp - write_bitstream -force design.bit -} - -run +generate_top diff --git a/fuzzers/005-tilegrid/clk_hrow/generate.tcl b/fuzzers/005-tilegrid/clk_hrow/generate.tcl index 49e429ba..5a69791f 100644 --- a/fuzzers/005-tilegrid/clk_hrow/generate.tcl +++ b/fuzzers/005-tilegrid/clk_hrow/generate.tcl @@ -1,21 +1,3 @@ source "$::env(XRAY_DIR)/utils/utils.tcl" -proc run {} { - create_project -force -part $::env(XRAY_PART) design design - read_verilog top.v - synth_design -top top - - #set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk] - - set_property CFGBVS VCCO [current_design] - set_property CONFIG_VOLTAGE 3.3 [current_design] - set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] - - place_design - route_design - - write_checkpoint -force design.dcp - write_bitstream -force design.bit -} - -run +generate_top diff --git a/fuzzers/005-tilegrid/dsp/generate.tcl b/fuzzers/005-tilegrid/dsp/generate.tcl index 9e8cab8a..5a69791f 100644 --- a/fuzzers/005-tilegrid/dsp/generate.tcl +++ b/fuzzers/005-tilegrid/dsp/generate.tcl @@ -1,19 +1,3 @@ source "$::env(XRAY_DIR)/utils/utils.tcl" -proc run {} { - create_project -force -part $::env(XRAY_PART) design design - read_verilog top.v - synth_design -top top - - set_property CFGBVS VCCO [current_design] - set_property CONFIG_VOLTAGE 3.3 [current_design] - set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] - - place_design - route_design - - write_checkpoint -force design.dcp - write_bitstream -force design.bit -} - -run +generate_top diff --git a/fuzzers/005-tilegrid/fifo_int/generate.tcl b/fuzzers/005-tilegrid/fifo_int/generate.tcl index 9e8cab8a..5a69791f 100644 --- a/fuzzers/005-tilegrid/fifo_int/generate.tcl +++ b/fuzzers/005-tilegrid/fifo_int/generate.tcl @@ -1,19 +1,3 @@ source "$::env(XRAY_DIR)/utils/utils.tcl" -proc run {} { - create_project -force -part $::env(XRAY_PART) design design - read_verilog top.v - synth_design -top top - - set_property CFGBVS VCCO [current_design] - set_property CONFIG_VOLTAGE 3.3 [current_design] - set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] - - place_design - route_design - - write_checkpoint -force design.dcp - write_bitstream -force design.bit -} - -run +generate_top diff --git a/fuzzers/005-tilegrid/monitor_int/generate.tcl b/fuzzers/005-tilegrid/monitor_int/generate.tcl index 9e8cab8a..5a69791f 100644 --- a/fuzzers/005-tilegrid/monitor_int/generate.tcl +++ b/fuzzers/005-tilegrid/monitor_int/generate.tcl @@ -1,19 +1,3 @@ source "$::env(XRAY_DIR)/utils/utils.tcl" -proc run {} { - create_project -force -part $::env(XRAY_PART) design design - read_verilog top.v - synth_design -top top - - set_property CFGBVS VCCO [current_design] - set_property CONFIG_VOLTAGE 3.3 [current_design] - set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] - - place_design - route_design - - write_checkpoint -force design.dcp - write_bitstream -force design.bit -} - -run +generate_top diff --git a/utils/utils.tcl b/utils/utils.tcl index cead2bab..9fea66c1 100644 --- a/utils/utils.tcl +++ b/utils/utils.tcl @@ -131,3 +131,20 @@ proc write_pip_txtdata {filename} { } close $fp } + +# Generic non-ROI'd generate.tcl template +proc generate_top {} { + create_project -force -part $::env(XRAY_PART) design design + read_verilog top.v + synth_design -top top + + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] + + place_design + route_design + + write_checkpoint -force design.dcp + write_bitstream -force design.bit +} From 8bdc6696326f50407e59e64926626d3b96f8c7eb Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 16:50:21 -0800 Subject: [PATCH 10/10] Remove strict SEGMATCH criteria. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/041-clk-hrow-pips/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile index 155094ec..626362eb 100644 --- a/fuzzers/041-clk-hrow-pips/Makefile +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -4,8 +4,8 @@ PIPLIST_TCL=$(FUZDIR)/clk_hrow_pip_list.tcl MAKETODO_FLAGS=--no-l --pip-type clk_hrow_bot --seg-type clk_hrow_bot --re "[^\.]+\.CLK_HROW_CK_MUX_OUT_" N = 50 -# These PIPs all appear to be either a 0 or 2 bit solution. -SEGMATCH_FLAGS=-m 20 -M 45 -c 1 +# These PIPs all appear to be either a 1 bit solutions. +SEGMATCH_FLAGS=-c 1 SPECIMENS_DEPS=build/cmt_regions.csv A_PIPLIST=clk_hrow_bot_r.txt