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" ;;