From 5e9cb60917a83e3e9715fee32f593bcd3c7d62cd Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 8 Feb 2019 13:00:54 -0800 Subject: [PATCH 01/13] Add base addresses for CLK_HROW tiles. Word offset may be wrong. 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_hrow/Makefile | 4 ++ fuzzers/005-tilegrid/clk_hrow/generate.tcl | 21 ++++++++ fuzzers/005-tilegrid/clk_hrow/top.py | 60 ++++++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 fuzzers/005-tilegrid/clk_hrow/Makefile create mode 100644 fuzzers/005-tilegrid/clk_hrow/generate.tcl create mode 100644 fuzzers/005-tilegrid/clk_hrow/top.py diff --git a/fuzzers/005-tilegrid/Makefile b/fuzzers/005-tilegrid/Makefile index 46edf091..83556908 100644 --- a/fuzzers/005-tilegrid/Makefile +++ b/fuzzers/005-tilegrid/Makefile @@ -13,6 +13,7 @@ TILEGRID_TDB_DEPENDENCIES += dsp/build/segbits_tilegrid.tdb 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 GENERATE_FULL_ARGS= ifeq (${XRAY_DATABASE}, zynq7) @@ -96,6 +97,9 @@ cfg_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json orphan_int_column/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json cd orphan_int_column && $(MAKE) +clk_hrow/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json + cd clk_hrow && $(MAKE) + build/tilegrid_tdb.json: add_tdb.py $(TILEGRID_TDB_DEPENDENCIES) python3 add_tdb.py \ --fn-in build/basicdb/tilegrid.json \ @@ -129,6 +133,7 @@ clean: cd monitor_int && $(MAKE) clean cd cfg_int && $(MAKE) clean cd orphan_int_column && $(MAKE) clean + cd clk_hrow && $(MAKE) clean .PHONY: database pushdb clean run diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py index a98e6a68..0f09e0e4 100644 --- a/fuzzers/005-tilegrid/add_tdb.py +++ b/fuzzers/005-tilegrid/add_tdb.py @@ -84,6 +84,7 @@ def run(fn_in, fn_out, verbose=False): ("bram_block/build/segbits_tilegrid.tdb", 128, 10), ("clb/build/segbits_tilegrid.tdb", 36, 2), ("dsp/build/segbits_tilegrid.tdb", 28, 10), + ("clk_hrow/build/segbits_tilegrid.tdb", 26, 1), ("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_hrow/Makefile b/fuzzers/005-tilegrid/clk_hrow/Makefile new file mode 100644 index 00000000..24713793 --- /dev/null +++ b/fuzzers/005-tilegrid/clk_hrow/Makefile @@ -0,0 +1,4 @@ +N ?= 5 +GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 1A" +include ../fuzzaddr/common.mk + diff --git a/fuzzers/005-tilegrid/clk_hrow/generate.tcl b/fuzzers/005-tilegrid/clk_hrow/generate.tcl new file mode 100644 index 00000000..49e429ba --- /dev/null +++ b/fuzzers/005-tilegrid/clk_hrow/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_hrow/top.py b/fuzzers/005-tilegrid/clk_hrow/top.py new file mode 100644 index 00000000..0db696b3 --- /dev/null +++ b/fuzzers/005-tilegrid/clk_hrow/top.py @@ -0,0 +1,60 @@ +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 == 'BUFHCE': + 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}" *) + BUFHCE #( + .INIT_OUT({isone}) + ) buf_{site} (); +'''.format( + site=site_name, + isone=isone, + )) + + print("endmodule") + write_params(params) + + +if __name__ == '__main__': + run() From 00d9e1f314a58d406dba176763acaa4c048fdaa9 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 8 Feb 2019 14:23:39 -0800 Subject: [PATCH 02/13] Add CLK_HROW config fuzzer, and adjust tilegrid definition. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/005-tilegrid/add_tdb.py | 2 +- fuzzers/005-tilegrid/clk_hrow/Makefile | 2 +- fuzzers/040-clk_hrow_config/Makefile | 22 +++++++ fuzzers/040-clk_hrow_config/bits.dbf | 0 fuzzers/040-clk_hrow_config/generate.py | 35 +++++++++++ fuzzers/040-clk_hrow_config/generate.tcl | 17 ++++++ fuzzers/040-clk_hrow_config/top.py | 76 ++++++++++++++++++++++++ prjxray/segmaker.py | 3 +- utils/mergedb.py | 1 - utils/mergedb.sh | 5 ++ 10 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 fuzzers/040-clk_hrow_config/Makefile create mode 100644 fuzzers/040-clk_hrow_config/bits.dbf create mode 100644 fuzzers/040-clk_hrow_config/generate.py create mode 100644 fuzzers/040-clk_hrow_config/generate.tcl create mode 100644 fuzzers/040-clk_hrow_config/top.py diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py index 0f09e0e4..b27d5960 100644 --- a/fuzzers/005-tilegrid/add_tdb.py +++ b/fuzzers/005-tilegrid/add_tdb.py @@ -84,7 +84,7 @@ def run(fn_in, fn_out, verbose=False): ("bram_block/build/segbits_tilegrid.tdb", 128, 10), ("clb/build/segbits_tilegrid.tdb", 36, 2), ("dsp/build/segbits_tilegrid.tdb", 28, 10), - ("clk_hrow/build/segbits_tilegrid.tdb", 26, 1), + ("clk_hrow/build/segbits_tilegrid.tdb", 30, 7), ("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_hrow/Makefile b/fuzzers/005-tilegrid/clk_hrow/Makefile index 24713793..17297e84 100644 --- a/fuzzers/005-tilegrid/clk_hrow/Makefile +++ b/fuzzers/005-tilegrid/clk_hrow/Makefile @@ -1,4 +1,4 @@ N ?= 5 -GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 1A" +GENERATE_ARGS?="--oneval 1 --design params.csv --dword 1 --dframe 1A" include ../fuzzaddr/common.mk diff --git a/fuzzers/040-clk_hrow_config/Makefile b/fuzzers/040-clk_hrow_config/Makefile new file mode 100644 index 00000000..c815d293 --- /dev/null +++ b/fuzzers/040-clk_hrow_config/Makefile @@ -0,0 +1,22 @@ +N ?= 15 + +include ../fuzzer.mk + +database: build/segbits_clk_hrow.db + +build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -o build/segbits_clk_hrow.rdb $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) + +build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ + --seg-fn-in build/segbits_clk_hrow.rdb \ + --seg-fn-out build/segbits_clk_hrow.db + ${XRAY_MASKMERGE} build/mask_clk_hrow.db $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) + +pushdb: database + ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db + ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db + ${XRAY_MERGEDB} mask_clk_hrow_bot_r build/mask_clk_hrow.db + ${XRAY_MERGEDB} mask_clk_hrow_top_r build/mask_clk_hrow.db + +.PHONY: database pushdb diff --git a/fuzzers/040-clk_hrow_config/bits.dbf b/fuzzers/040-clk_hrow_config/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/040-clk_hrow_config/generate.py b/fuzzers/040-clk_hrow_config/generate.py new file mode 100644 index 00000000..d3a07f0a --- /dev/null +++ b/fuzzers/040-clk_hrow_config/generate.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +import json + +from prjxray.segmaker import Segmaker +from prjxray import verilog + + +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 = 'BUFHCE_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 + + segmk.add_site_tag(row['site'], '{}.INIT_OUT'.format(base_name), row['INIT_OUT']) + + # SYNC is a zero pattern + for opt in ['ASYNC']: + segmk.add_site_tag(row['site'], '{}.CE_TYPE.'.format(base_name) + opt, verilog.unquote(row['CE_TYPE']) == opt) + + segmk.compile() + segmk.write() + + +if __name__ == '__main__': + main() diff --git a/fuzzers/040-clk_hrow_config/generate.tcl b/fuzzers/040-clk_hrow_config/generate.tcl new file mode 100644 index 00000000..3044e100 --- /dev/null +++ b/fuzzers/040-clk_hrow_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/040-clk_hrow_config/top.py b/fuzzers/040-clk_hrow_config/top.py new file mode 100644 index 00000000..b19e936f --- /dev/null +++ b/fuzzers/040-clk_hrow_config/top.py @@ -0,0 +1,76 @@ +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('^BUFHCE_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 == 'BUFHCE': + 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.randint(0, 1) + + if params['IN_USE']: + params['INIT_OUT'] = random.randint(0, 1) + params['CE_TYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC'))) + + print(''' + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFHCE #( + .INIT_OUT({INIT_OUT}), + .CE_TYPE({CE_TYPE}) + ) buf_{site} (); + '''.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/prjxray/segmaker.py b/prjxray/segmaker.py index 5fccbf57..559556a1 100644 --- a/prjxray/segmaker.py +++ b/prjxray/segmaker.py @@ -335,8 +335,9 @@ class Segmaker: Simplify names by simplifying like: -CLBLM_L => CLB -CENTER_INTER_R => CENTER_INTER + -CLK_HROW_TOP_R => CLK_HROW ''' - tile_type_norm = re.sub("(LL|LM)?_[LR]$", "", tile_type) + tile_type_norm = re.sub("(_TOP|_BOT|LL|LM)?_[LR]$", "", tile_type) # ignore dummy tiles (ex: VBRK) if len(tiledata['bits']) == 0: diff --git a/utils/mergedb.py b/utils/mergedb.py index 70088dda..af9b5e4e 100755 --- a/utils/mergedb.py +++ b/utils/mergedb.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 -import sys, re import os from prjxray import util diff --git a/utils/mergedb.sh b/utils/mergedb.sh index 93011e51..2f955c88 100755 --- a/utils/mergedb.sh +++ b/utils/mergedb.sh @@ -73,6 +73,11 @@ case "$1" in hclk_r) sed < "$2" > "$tmp1" -e 's/^HCLK\./HCLK_R./' ;; + clk_hrow_bot_r) + sed < "$2" > "$tmp1" -e 's/^CLK_HROW\./CLK_HROW_BOT_R./' ;; + clk_hrow_top_r) + sed < "$2" > "$tmp1" -e 's/^CLK_HROW\./CLK_HROW_TOP_R./' ;; + liob33) cp "$2" "$tmp1" ;; From 1011a90769aa6d3ed06f0e3bc1aadadf09da18cf Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 8 Feb 2019 14:28:54 -0800 Subject: [PATCH 03/13] Run make format. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/005-tilegrid/clk_hrow/top.py | 11 +++++------ fuzzers/040-clk_hrow_config/generate.py | 11 +++++++---- fuzzers/040-clk_hrow_config/top.py | 7 +++++-- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/fuzzers/005-tilegrid/clk_hrow/top.py b/fuzzers/005-tilegrid/clk_hrow/top.py index 0db696b3..66b7d67a 100644 --- a/fuzzers/005-tilegrid/clk_hrow/top.py +++ b/fuzzers/005-tilegrid/clk_hrow/top.py @@ -28,8 +28,7 @@ def write_params(params): def run(): - print( - ''' + print(''' module top(); ''') @@ -37,7 +36,7 @@ module top(); sites = list(gen_sites()) for (tile_name, sites), isone in zip(sites, - util.gen_fuzz_states(len(sites))): + util.gen_fuzz_states(len(sites))): site_name = sites[0] params[tile_name] = (site_name, isone) @@ -48,9 +47,9 @@ module top(); .INIT_OUT({isone}) ) buf_{site} (); '''.format( - site=site_name, - isone=isone, - )) + site=site_name, + isone=isone, + )) print("endmodule") write_params(params) diff --git a/fuzzers/040-clk_hrow_config/generate.py b/fuzzers/040-clk_hrow_config/generate.py index d3a07f0a..1fe04bcf 100644 --- a/fuzzers/040-clk_hrow_config/generate.py +++ b/fuzzers/040-clk_hrow_config/generate.py @@ -16,16 +16,19 @@ def main(): for row in params: base_name = 'BUFHCE_X{}Y{}'.format(row['x'], row['y']) - - segmk.add_site_tag(row['site'], '{}.IN_USE'.format(base_name), row['IN_USE']) + segmk.add_site_tag( + row['site'], '{}.IN_USE'.format(base_name), row['IN_USE']) if not row['IN_USE']: continue - segmk.add_site_tag(row['site'], '{}.INIT_OUT'.format(base_name), row['INIT_OUT']) + segmk.add_site_tag( + row['site'], '{}.INIT_OUT'.format(base_name), row['INIT_OUT']) # SYNC is a zero pattern for opt in ['ASYNC']: - segmk.add_site_tag(row['site'], '{}.CE_TYPE.'.format(base_name) + opt, verilog.unquote(row['CE_TYPE']) == opt) + segmk.add_site_tag( + row['site'], '{}.CE_TYPE.'.format(base_name) + opt, + verilog.unquote(row['CE_TYPE']) == opt) segmk.compile() segmk.write() diff --git a/fuzzers/040-clk_hrow_config/top.py b/fuzzers/040-clk_hrow_config/top.py index b19e936f..9b3d329e 100644 --- a/fuzzers/040-clk_hrow_config/top.py +++ b/fuzzers/040-clk_hrow_config/top.py @@ -9,6 +9,7 @@ from prjxray.db import Database XY_RE = re.compile('^BUFHCE_X([0-9]+)Y([0-9]+)$') + def gen_sites(): db = Database(util.get_db_root()) grid = db.grid() @@ -54,9 +55,11 @@ module top(); if params['IN_USE']: params['INIT_OUT'] = random.randint(0, 1) - params['CE_TYPE'] = verilog.quote(random.choice(('SYNC', 'ASYNC'))) + params['CE_TYPE'] = verilog.quote( + random.choice(('SYNC', 'ASYNC'))) - print(''' + print( + ''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE #( .INIT_OUT({INIT_OUT}), From 3b10ceed547be3b0c62318ed7c9404f5c73e053a Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Fri, 8 Feb 2019 14:29:48 -0800 Subject: [PATCH 04/13] Rename fuzzer and add 040 to root fuzzer make. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/Makefile | 0 fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/bits.dbf | 0 fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/generate.py | 0 .../{040-clk_hrow_config => 040-clk-hrow-config}/generate.tcl | 0 fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/top.py | 0 fuzzers/Makefile | 1 + 6 files changed, 1 insertion(+) rename fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/Makefile (100%) rename fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/bits.dbf (100%) rename fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/generate.py (100%) rename fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/generate.tcl (100%) rename fuzzers/{040-clk_hrow_config => 040-clk-hrow-config}/top.py (100%) diff --git a/fuzzers/040-clk_hrow_config/Makefile b/fuzzers/040-clk-hrow-config/Makefile similarity index 100% rename from fuzzers/040-clk_hrow_config/Makefile rename to fuzzers/040-clk-hrow-config/Makefile diff --git a/fuzzers/040-clk_hrow_config/bits.dbf b/fuzzers/040-clk-hrow-config/bits.dbf similarity index 100% rename from fuzzers/040-clk_hrow_config/bits.dbf rename to fuzzers/040-clk-hrow-config/bits.dbf diff --git a/fuzzers/040-clk_hrow_config/generate.py b/fuzzers/040-clk-hrow-config/generate.py similarity index 100% rename from fuzzers/040-clk_hrow_config/generate.py rename to fuzzers/040-clk-hrow-config/generate.py diff --git a/fuzzers/040-clk_hrow_config/generate.tcl b/fuzzers/040-clk-hrow-config/generate.tcl similarity index 100% rename from fuzzers/040-clk_hrow_config/generate.tcl rename to fuzzers/040-clk-hrow-config/generate.tcl diff --git a/fuzzers/040-clk_hrow_config/top.py b/fuzzers/040-clk-hrow-config/top.py similarity index 100% rename from fuzzers/040-clk_hrow_config/top.py rename to fuzzers/040-clk-hrow-config/top.py diff --git a/fuzzers/Makefile b/fuzzers/Makefile index 78dd8a1c..50afad6c 100644 --- a/fuzzers/Makefile +++ b/fuzzers/Makefile @@ -70,6 +70,7 @@ $(eval $(call fuzzer,026-bram-data,005-tilegrid)) $(eval $(call fuzzer,027-bram36-config,005-tilegrid)) $(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,050-pip-seed,005-tilegrid)) $(eval $(call fuzzer,051-pip-imuxlout-bypalts,050-pip-seed)) $(eval $(call fuzzer,052-pip-clkin,050-pip-seed)) From 6fd2cb4eec41ae3526598b4985940afa36eb0c7f Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Sat, 9 Feb 2019 22:37:39 -0800 Subject: [PATCH 05/13] Initial working GCLK to HROW_CLK PIP fuzzer. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/041-clk-hrow-pips/Makefile | 26 +++ fuzzers/041-clk-hrow-pips/bits.dbf | 0 .../041-clk-hrow-pips/clk_hrow_pip_list.tcl | 21 ++ fuzzers/041-clk-hrow-pips/generate.py | 51 +++++ fuzzers/041-clk-hrow-pips/generate.tcl | 43 ++++ fuzzers/041-clk-hrow-pips/output_cmt.tcl | 11 + fuzzers/041-clk-hrow-pips/top.py | 190 ++++++++++++++++++ 7 files changed, 342 insertions(+) create mode 100644 fuzzers/041-clk-hrow-pips/Makefile create mode 100644 fuzzers/041-clk-hrow-pips/bits.dbf create mode 100644 fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl create mode 100644 fuzzers/041-clk-hrow-pips/generate.py create mode 100644 fuzzers/041-clk-hrow-pips/generate.tcl create mode 100644 fuzzers/041-clk-hrow-pips/output_cmt.tcl create mode 100644 fuzzers/041-clk-hrow-pips/top.py diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile new file mode 100644 index 00000000..f532495c --- /dev/null +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -0,0 +1,26 @@ +N ?= 50 + +include ../fuzzer.mk + +database: build/segbits_clk_hrow.db + +build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -o build/segbits_clk_hrow.rdb \ + $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ + $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) + +build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ + --seg-fn-in build/segbits_clk_hrow.rdb \ + --seg-fn-out build/segbits_clk_hrow.db + ${XRAY_MASKMERGE} build/mask_clk_hrow.db \ + $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ + $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) + +pushdb: database + ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db + ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db + ${XRAY_MERGEDB} mask_clk_hrow_bot_r build/mask_clk_hrow.db + ${XRAY_MERGEDB} mask_clk_hrow_top_r build/mask_clk_hrow.db + +.PHONY: database pushdb diff --git a/fuzzers/041-clk-hrow-pips/bits.dbf b/fuzzers/041-clk-hrow-pips/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl b/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl new file mode 100644 index 00000000..b21bec3a --- /dev/null +++ b/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl @@ -0,0 +1,21 @@ +proc print_tile_pips {tile_type filename} { + set tile [lindex [get_tiles -filter "TYPE == $tile_type"] 0] + puts "Dumping PIPs for tile $tile ($tile_type) to $filename." + set fp [open $filename w] + foreach pip [lsort [get_pips -of_objects [get_tiles $tile]]] { + set src [get_wires -uphill -of_objects $pip] + set dst [get_wires -downhill -of_objects $pip] + if {[llength [get_nodes -uphill -of_objects [get_nodes -of_objects $dst]]] != 1} { + puts $fp "$tile_type.[regsub {.*/} $dst ""].[regsub {.*/} $src ""]" + } + } + close $fp +} + +create_project -force -part $::env(XRAY_PART) design design +set_property design_mode PinPlanning [current_fileset] +open_io_design -name io_1 + +print_tile_pips CLK_HROW_TOP_R clk_hrow_top_r.txt +print_tile_pips CLK_HROW_BOT_R clk_hrow_bot_r.txt +print_tile_pips CLK_BUFG_REBUF clk_bufg_rebuf.txt diff --git a/fuzzers/041-clk-hrow-pips/generate.py b/fuzzers/041-clk-hrow-pips/generate.py new file mode 100644 index 00000000..ff1fcb61 --- /dev/null +++ b/fuzzers/041-clk-hrow-pips/generate.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 + +from prjxray.segmaker import Segmaker +import re + + +def main(): + segmk = Segmaker("design.bits") + + print("Loading tags from design.txt.") + with open("design.txt", "r") as f: + for line in f: + tile, pip, src, dst, pnum, pdir = line.split() + + if not tile.startswith('CLK_HROW'): + continue + + pip_prefix, pip = pip.split(".") + tile_from_pip, tile_type = pip_prefix.split('/') + assert tile == tile_from_pip + _, src = src.split("/") + _, dst = dst.split("/") + + rows = set(range(8)) + columns = set(range(4)) + + m = re.match('^CLK_HROW_R_CK_GCLK([0-9]+)$', src) + if m: + gclk = int(m.group(1)) + row = gclk % 8 + column = int(gclk / 8) + + segmk.add_tile_tag(tile, '{}.GCLK_ENABLE_ROW{}'.format(dst, row), 1) + segmk.add_tile_tag(tile, '{}.GCLK_ENABLE_COLUMN{}'.format(dst, column), 1) + + rows.remove(row) + columns.remove(column) + + for row in rows: + segmk.add_tile_tag(tile, '{}.GCLK_ENABLE_ROW{}'.format(dst, row), 0) + + for column in columns: + segmk.add_tile_tag(tile, '{}.GCLK_ENABLE_COLUMN{}'.format(dst, column), 0) + + + segmk.compile() + segmk.write() + + +if __name__ == '__main__': + main() diff --git a/fuzzers/041-clk-hrow-pips/generate.tcl b/fuzzers/041-clk-hrow-pips/generate.tcl new file mode 100644 index 00000000..9932ddc7 --- /dev/null +++ b/fuzzers/041-clk-hrow-pips/generate.tcl @@ -0,0 +1,43 @@ +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 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] + set_property IS_ENABLED 0 [get_drc_checks {REQP-161}] + set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets] + + place_design + route_design + + write_checkpoint -force design.dcp + write_bitstream -force design.bit + write_pip_txtdata design.txt +} + +run diff --git a/fuzzers/041-clk-hrow-pips/output_cmt.tcl b/fuzzers/041-clk-hrow-pips/output_cmt.tcl new file mode 100644 index 00000000..d1af528c --- /dev/null +++ b/fuzzers/041-clk-hrow-pips/output_cmt.tcl @@ -0,0 +1,11 @@ +create_project -force -part $::env(XRAY_PART) design design +set_property design_mode PinPlanning [current_fileset] +open_io_design -name io_1 + +set fp [open "cmt_regions.csv" "w"] +foreach site_type {MMCME2_ADV PLLE2_ADV BUFHCE} { + foreach site [get_sites -filter "SITE_TYPE == $site_type"] { + puts $fp "$site,[get_property CLOCK_REGION $site]" + } +} +close $fp diff --git a/fuzzers/041-clk-hrow-pips/top.py b/fuzzers/041-clk-hrow-pips/top.py new file mode 100644 index 00000000..44a153ff --- /dev/null +++ b/fuzzers/041-clk-hrow-pips/top.py @@ -0,0 +1,190 @@ +import os +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, sorted(sites) + + +def read_site_to_cmt(): + with open(os.path.join(os.getenv('FUZDIR'), 'build', 'cmt_regions.csv')) as f: + for l in f: + site, cmt = l.strip().split(',') + yield (site, cmt) + +CMT_RE = re.compile('X([0-9]+)Y([0-9]+)') + +class ClockSources(object): + def __init__(self): + self.sources = {} + self.merged_sources = {} + + def add_clock_source(self, source, cmt): + if cmt not in self.sources: + self.sources[cmt] = [] + + self.sources[cmt].append(source) + + def get_random_source(self, cmt): + if cmt not in self.merged_sources: + choices = [] + choices.extend(self.sources['ANY']) + + if cmt in self.sources: + choices.extend(self.sources[cmt]) + + m = CMT_RE.match(cmt) + x = int(m.group(1)) + y = int(m.group(2)) + + if x % 2 == 0: + x += 1 + else: + x -= 1 + + paired_cmt = 'X{}Y{}'.format(x, y) + + if paired_cmt in self.sources: + choices.extend(self.sources[paired_cmt]) + + self.merged_sources[cmt] = choices + + return random.choice(self.merged_sources[cmt]) + + +def other_sources(): + site_to_cmt = dict(read_site_to_cmt()) + + clock_sources = ClockSources() + clock_sources.add_clock_source('one', 'ANY') + clock_sources.add_clock_source('zero', 'ANY') + + print(""" + wire zero = 0; + wire one = 1;""") + + for idx in range(1): + wire_name = "lut_wire_{}".format(idx) + clock_sources.add_clock_source(wire_name, 'ANY') + print(""" + (* KEEP, DONT_TOUCH *) + wire {wire_name}; + LUT6 lut{idx} ( + .O({wire_name}) + );""".format( + idx=idx, + wire_name=wire_name, + )) + + for site in gen_sites('PLLE2_ADV'): + pll_clocks = ['pll_clock_{site}_{idx}'.format(site=site, idx=idx) for + idx in range(6)] + + for clk in pll_clocks[:2]: + clock_sources.add_clock_source(clk, site_to_cmt[site]) + + print(""" + wire {c0}, {c1}, {c2}, {c3}, {c4}, {c5}; + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + PLLE2_ADV pll_{site} ( + .CLKOUT0({c0}), + .CLKOUT1({c1}), + .CLKOUT2({c2}), + .CLKOUT3({c3}), + .CLKOUT4({c4}), + .CLKOUT5({c5}) + ); + """.format( + site=site, + c0=pll_clocks[0], + c1=pll_clocks[1], + c2=pll_clocks[2], + c3=pll_clocks[3], + c4=pll_clocks[4], + c5=pll_clocks[5], + )) + + +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()) + for tile_name, sites in bufhce_sites: + for site in sites: + print(""" + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFHCE buf_{site} ( + .I({wire_name}) + ); + """.format( + site=site, + wire_name=random.choice(gclks), + )) + + print("endmodule") + +if __name__ == '__main__': + main() From f58cf6bbda7423ffd3a4ee8600426e1270344037 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Sat, 9 Feb 2019 22:50:15 -0800 Subject: [PATCH 06/13] Output PIP form. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/041-clk-hrow-pips/Makefile | 6 +- .../041-clk-hrow-pips/merge_gclk_entries.py | 56 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 fuzzers/041-clk-hrow-pips/merge_gclk_entries.py diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile index f532495c..f2ef3eea 100644 --- a/fuzzers/041-clk-hrow-pips/Makefile +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -12,7 +12,11 @@ build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ --seg-fn-in build/segbits_clk_hrow.rdb \ - --seg-fn-out build/segbits_clk_hrow.db + --seg-fn-out build/segbits_clk_hrow_rc.db + python3 merge_gclk_entries.py \ + build/segbits_clk_hrow_rc.db \ + build/segbits_clk_hrow.db + ${XRAY_MASKMERGE} build/mask_clk_hrow.db \ $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) diff --git a/fuzzers/041-clk-hrow-pips/merge_gclk_entries.py b/fuzzers/041-clk-hrow-pips/merge_gclk_entries.py new file mode 100644 index 00000000..20ae0b77 --- /dev/null +++ b/fuzzers/041-clk-hrow-pips/merge_gclk_entries.py @@ -0,0 +1,56 @@ +import argparse + +GCLKS = 32 + +def main(): + parser = argparse.ArgumentParser(description="Convert GCLK ROW/COLUMN definitions into GCLK pips.") + parser.add_argument('in_segbit') + parser.add_argument('out_segbit') + + args = parser.parse_args() + + hrow_outs = {} + tile = None + with open(args.in_segbit) as f: + for l in f: + parts = l.strip().split(' ') + feature = parts[0] + bits = ' '.join(parts[1:]) + + tile1, dst, src = feature.split('.') + if tile is None: + tile = tile1 + else: + assert tile == tile1 + + n = int(src[-1]) + + if dst not in hrow_outs: + hrow_outs[dst] = { + 'rows': {}, + 'columns': {}, + } + + if src[-4:-1] == 'ROW': + hrow_outs[dst]['rows'][n] = bits + else: + assert src[-7:-1] == 'COLUMN', src + hrow_outs[dst]['columns'][n] = bits + + with open(args.out_segbit, 'w') as f: + for dst in hrow_outs: + for gclk in range(GCLKS): + row = gclk % 8 + column = int(gclk / 8) + + print('{tile}.{dst}.CLK_HROW_R_CK_GCLK{gclk} {row_bits} {column_bits}'.format( + tile=tile, + dst=dst, + gclk=gclk, + row_bits=hrow_outs[dst]['rows'][row], + column_bits=hrow_outs[dst]['columns'][column], + ), file=f) + + +if __name__ == "__main__": + main() From 0b1e8e9974986d396f01823a45a95cf76ec60e29 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Mon, 11 Feb 2019 09:59:09 -0800 Subject: [PATCH 07/13] Add left and right clock pips. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/041-clk-hrow-pips/Makefile | 16 ++- fuzzers/041-clk-hrow-pips/clk_table.py | 34 +++++ fuzzers/041-clk-hrow-pips/generate.py | 22 ++- fuzzers/041-clk-hrow-pips/generate.tcl | 2 + ...e_gclk_entries.py => merge_clk_entries.py} | 40 ++++-- fuzzers/041-clk-hrow-pips/top.py | 126 +++++++++++++++--- fuzzers/fuzzer.mk | 3 +- 7 files changed, 195 insertions(+), 48 deletions(-) create mode 100644 fuzzers/041-clk-hrow-pips/clk_table.py rename fuzzers/041-clk-hrow-pips/{merge_gclk_entries.py => merge_clk_entries.py} (55%) diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile index f2ef3eea..400f43c9 100644 --- a/fuzzers/041-clk-hrow-pips/Makefile +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -1,20 +1,30 @@ -N ?= 50 +N ?= 150 +SPECIMENS_DEPS=build/cmt_regions.csv include ../fuzzer.mk database: build/segbits_clk_hrow.db +build/clk_hrow_bot_r.txt: clk_hrow_pip_list.tcl + mkdir -p build + cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/clk_hrow_pip_list.tcl + +build/cmt_regions.csv: output_cmt.tcl build/clk_hrow_bot_r.txt + mkdir -p build + 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 \ $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) -build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb +build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb build/clk_hrow_bot_r.txt ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ --seg-fn-in build/segbits_clk_hrow.rdb \ --seg-fn-out build/segbits_clk_hrow_rc.db - python3 merge_gclk_entries.py \ + python3 merge_clk_entries.py \ build/segbits_clk_hrow_rc.db \ + build/clk_hrow_bot_r.txt \ build/segbits_clk_hrow.db ${XRAY_MASKMERGE} build/mask_clk_hrow.db \ diff --git a/fuzzers/041-clk-hrow-pips/clk_table.py b/fuzzers/041-clk-hrow-pips/clk_table.py new file mode 100644 index 00000000..0b46564b --- /dev/null +++ b/fuzzers/041-clk-hrow-pips/clk_table.py @@ -0,0 +1,34 @@ +HCLKS = 24 +GCLKS = 32 +SIDE_CLK_INPUTS = 14 +CLK_TABLE = {} + +CLK_TABLE_NUM_ROWS = 8 +CLK_TABLE_NUM_COLS = 8 + +for gclk in range(GCLKS): + gclk_name = 'CLK_HROW_R_CK_GCLK{}'.format(gclk) + row = gclk % 8 + column = int(gclk / 8) + CLK_TABLE[gclk_name] = (row, column) + +for lr in ['L', 'R']: + for side_inputs in range(SIDE_CLK_INPUTS): + side_clk_name = 'CLK_HROW_CK_IN_{}{}'.format(lr, side_inputs) + +for row in range(8): + CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row)] = (row, 4) +for row in range(6): + CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row+8)] = (row, 5) + +for row in range(8): + CLK_TABLE['CLK_HROW_CK_IN_R{}'.format(row)] = (row, 6) +for row in range(6): + CLK_TABLE['CLK_HROW_CK_IN_R{}'.format(row+8)] = (row, 7) + +# HROW_CK_INT__, Y == Y share the same bits, and only X = 0 or X = 1 are +# present on a particular HROW. +for y in range(2): + for x in range(2): + int_clk_name = 'CLK_HROW_CK_INT_{}_{}'.format(x, y) + CLK_TABLE[int_clk_name] = (y+6, 7) diff --git a/fuzzers/041-clk-hrow-pips/generate.py b/fuzzers/041-clk-hrow-pips/generate.py index ff1fcb61..1974ba74 100644 --- a/fuzzers/041-clk-hrow-pips/generate.py +++ b/fuzzers/041-clk-hrow-pips/generate.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 from prjxray.segmaker import Segmaker -import re +import clk_table def main(): @@ -21,27 +21,23 @@ def main(): _, src = src.split("/") _, dst = dst.split("/") - rows = set(range(8)) - columns = set(range(4)) + rows = set(range(clk_table.CLK_TABLE_NUM_ROWS)) + columns = set(range(clk_table.CLK_TABLE_NUM_COLS)) - m = re.match('^CLK_HROW_R_CK_GCLK([0-9]+)$', src) - if m: - gclk = int(m.group(1)) - row = gclk % 8 - column = int(gclk / 8) + if src in clk_table.CLK_TABLE: + row, column = clk_table.CLK_TABLE[src] - segmk.add_tile_tag(tile, '{}.GCLK_ENABLE_ROW{}'.format(dst, row), 1) - segmk.add_tile_tag(tile, '{}.GCLK_ENABLE_COLUMN{}'.format(dst, column), 1) + segmk.add_tile_tag(tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 1) + segmk.add_tile_tag(tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 1) rows.remove(row) columns.remove(column) for row in rows: - segmk.add_tile_tag(tile, '{}.GCLK_ENABLE_ROW{}'.format(dst, row), 0) + segmk.add_tile_tag(tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 0) for column in columns: - segmk.add_tile_tag(tile, '{}.GCLK_ENABLE_COLUMN{}'.format(dst, column), 0) - + segmk.add_tile_tag(tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 0) segmk.compile() segmk.write() diff --git a/fuzzers/041-clk-hrow-pips/generate.tcl b/fuzzers/041-clk-hrow-pips/generate.tcl index 9932ddc7..05210e30 100644 --- a/fuzzers/041-clk-hrow-pips/generate.tcl +++ b/fuzzers/041-clk-hrow-pips/generate.tcl @@ -30,6 +30,8 @@ proc run {} { set_property CONFIG_VOLTAGE 3.3 [current_design] set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] set_property IS_ENABLED 0 [get_drc_checks {REQP-161}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-123}] + set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets] place_design diff --git a/fuzzers/041-clk-hrow-pips/merge_gclk_entries.py b/fuzzers/041-clk-hrow-pips/merge_clk_entries.py similarity index 55% rename from fuzzers/041-clk-hrow-pips/merge_gclk_entries.py rename to fuzzers/041-clk-hrow-pips/merge_clk_entries.py index 20ae0b77..53005716 100644 --- a/fuzzers/041-clk-hrow-pips/merge_gclk_entries.py +++ b/fuzzers/041-clk-hrow-pips/merge_clk_entries.py @@ -1,10 +1,10 @@ import argparse - -GCLKS = 32 +import clk_table def main(): - parser = argparse.ArgumentParser(description="Convert GCLK ROW/COLUMN definitions into GCLK pips.") + parser = argparse.ArgumentParser(description="Convert HCLK ROW/COLUMN definitions into HCLK pips.") parser.add_argument('in_segbit') + parser.add_argument('piplist') parser.add_argument('out_segbit') args = parser.parse_args() @@ -37,16 +37,34 @@ def main(): assert src[-7:-1] == 'COLUMN', src hrow_outs[dst]['columns'][n] = bits - with open(args.out_segbit, 'w') as f: - for dst in hrow_outs: - for gclk in range(GCLKS): - row = gclk % 8 - column = int(gclk / 8) + piplists = {} + with open(args.piplist) as f: + for l in f: + tile, dst, src = l.strip().split('.') + assert tile == 'CLK_HROW_BOT_R', tile - print('{tile}.{dst}.CLK_HROW_R_CK_GCLK{gclk} {row_bits} {column_bits}'.format( - tile=tile, + if dst not in piplists: + piplists[dst] = [] + + piplists[dst].append(src) + + with open(args.out_segbit, 'w') as f: + for dst in sorted(hrow_outs): + for src in sorted(piplists[dst]): + if src not in clk_table.CLK_TABLE: + continue + + row, column = clk_table.CLK_TABLE[src] + + if row not in hrow_outs[dst]['rows']: + continue + + if column not in hrow_outs[dst]['columns']: + continue + + print('CLK_HROW.{dst}.{inclk} {row_bits} {column_bits}'.format( dst=dst, - gclk=gclk, + inclk=src, row_bits=hrow_outs[dst]['rows'][row], column_bits=hrow_outs[dst]['columns'][column], ), file=f) diff --git a/fuzzers/041-clk-hrow-pips/top.py b/fuzzers/041-clk-hrow-pips/top.py index 44a153ff..32d45177 100644 --- a/fuzzers/041-clk-hrow-pips/top.py +++ b/fuzzers/041-clk-hrow-pips/top.py @@ -63,17 +63,22 @@ class ClockSources(object): def __init__(self): self.sources = {} self.merged_sources = {} + self.source_to_cmt = {} + self.used_sources_from_cmt = {} def add_clock_source(self, source, cmt): if cmt not in self.sources: self.sources[cmt] = [] self.sources[cmt].append(source) + assert source not in self.source_to_cmt or self.source_to_cmt[source] == cmt, source + self.source_to_cmt[source] = cmt def get_random_source(self, cmt): if cmt not in self.merged_sources: choices = [] - choices.extend(self.sources['ANY']) + if 'ANY' in self.sources: + choices.extend(self.sources['ANY']) if cmt in self.sources: choices.extend(self.sources[cmt]) @@ -94,15 +99,49 @@ class ClockSources(object): self.merged_sources[cmt] = choices - return random.choice(self.merged_sources[cmt]) + if self.merged_sources[cmt]: + source = random.choice(self.merged_sources[cmt]) + + source_cmt = self.source_to_cmt[source] + if source_cmt not in self.used_sources_from_cmt: + self.used_sources_from_cmt[source_cmt] = set() + + self.used_sources_from_cmt[source_cmt].add(source) + + if source_cmt != 'ANY' and len(self.used_sources_from_cmt[source_cmt]) > 14: + print('//', self.used_sources_from_cmt) + self.used_sources_from_cmt[source_cmt].remove(source) + return None + else: + return source -def other_sources(): +def check_allowed(mmcm_pll_dir, cmt): + if mmcm_pll_dir == 'BOTH': + return True + elif mmcm_pll_dir == 'ODD': + return (int(CMT_RE.match(cmt).group(1)) & 1) == 1 + elif mmcm_pll_dir == 'EVEN': + return (int(CMT_RE.match(cmt).group(1)) & 1) == 0 + else: + assert False, mmcm_pll_dir + +def main(): + print(''' +module top(); + ''') + site_to_cmt = dict(read_site_to_cmt()) clock_sources = ClockSources() - clock_sources.add_clock_source('one', 'ANY') - clock_sources.add_clock_source('zero', 'ANY') + + mmcm_pll_only = random.randint(0, 1) + mmcm_pll_dir = random.choice(('ODD', 'EVEN', 'BOTH')) + + if not mmcm_pll_only: + for _ in range(2): + clock_sources.add_clock_source('one', 'ANY') + clock_sources.add_clock_source('zero', 'ANY') print(""" wire zero = 0; @@ -110,7 +149,7 @@ def other_sources(): for idx in range(1): wire_name = "lut_wire_{}".format(idx) - clock_sources.add_clock_source(wire_name, 'ANY') + #clock_sources.add_clock_source(wire_name, 'ANY') print(""" (* KEEP, DONT_TOUCH *) wire {wire_name}; @@ -121,11 +160,59 @@ def other_sources(): wire_name=wire_name, )) + for site in gen_sites('MMCME2_ADV'): + mmcm_clocks = ['mmcm_clock_{site}_{idx}'.format(site=site, idx=idx) for + idx in range(13)] + + if not check_allowed(mmcm_pll_dir, site_to_cmt[site]): + continue + + for clk in mmcm_clocks: + clock_sources.add_clock_source(clk, site_to_cmt[site]) + + print(""" + wire {c0}, {c1}, {c2}, {c3}, {c4}, {c5}; + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + MMCME2_ADV pll_{site} ( + .CLKOUT0({c0}), + .CLKOUT0B({c1}), + .CLKOUT1({c2}), + .CLKOUT1B({c3}), + .CLKOUT2({c4}), + .CLKOUT2B({c5}), + .CLKOUT3({c6}), + .CLKOUT3B({c7}), + .CLKOUT4({c8}), + .CLKOUT5({c9}), + .CLKOUT6({c10}), + .CLKFBOUT({c11}), + .CLKFBOUTB({c12}) + ); + """.format( + site=site, + c0=mmcm_clocks[0], + c1=mmcm_clocks[1], + c2=mmcm_clocks[2], + c3=mmcm_clocks[3], + c4=mmcm_clocks[4], + c5=mmcm_clocks[5], + c6=mmcm_clocks[6], + c7=mmcm_clocks[7], + c8=mmcm_clocks[8], + c9=mmcm_clocks[9], + c10=mmcm_clocks[10], + c11=mmcm_clocks[11], + c12=mmcm_clocks[12], + )) + for site in gen_sites('PLLE2_ADV'): pll_clocks = ['pll_clock_{site}_{idx}'.format(site=site, idx=idx) for idx in range(6)] - for clk in pll_clocks[:2]: + if not check_allowed(mmcm_pll_dir, site_to_cmt[site]): + continue + + for clk in pll_clocks: clock_sources.add_clock_source(clk, site_to_cmt[site]) print(""" @@ -149,16 +236,11 @@ def other_sources(): c5=pll_clocks[5], )) - -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) + + if not mmcm_pll_only: + clock_sources.add_clock_source(wire_name, 'ANY') print(""" wire {wire_name}; @@ -174,14 +256,18 @@ module top(); bufhce_sites = list(gen_bufhce_sites()) for tile_name, sites in bufhce_sites: for site in sites: + wire_name = clock_sources.get_random_source(site_to_cmt[site]) + if wire_name is None: + continue + print(""" - (* KEEP, DONT_TOUCH, LOC = "{site}" *) - BUFHCE buf_{site} ( - .I({wire_name}) - ); + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + BUFHCE buf_{site} ( + .I({wire_name}) + ); """.format( site=site, - wire_name=random.choice(gclks), + wire_name=wire_name, )) print("endmodule") diff --git a/fuzzers/fuzzer.mk b/fuzzers/fuzzer.mk index 0f260ea2..d7cc8010 100644 --- a/fuzzers/fuzzer.mk +++ b/fuzzers/fuzzer.mk @@ -2,13 +2,14 @@ N ?= 1 SPECIMENS := $(addprefix build/specimen_,$(shell seq -f '%03.0f' $(N))) SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) ENV_VAR ?= +SPECIMENS_DEPS ?= FUZDIR ?= ${PWD} all: database # generate.sh / top_generate.sh call make, hence the command must # have a + before it. -$(SPECIMENS_OK): +$(SPECIMENS_OK): $(SPECIMENS_DEPS) mkdir -p build +if [ -f $(FUZDIR)/generate.sh ]; then \ export $(ENV_VAR); \ From 31cca0949b70fc310df801569b9dcc9e15ff5ae0 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Mon, 11 Feb 2019 13:03:02 -0800 Subject: [PATCH 08/13] Add routing for LR CMT inputs. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/041-clk-hrow-pips/Makefile | 34 +++-- .../041-clk-hrow-pips/clk_hrow_pip_list.tcl | 1 - fuzzers/041-clk-hrow-pips/clk_table.py | 8 +- fuzzers/041-clk-hrow-pips/generate.tcl | 122 ++++++++++++++++++ fuzzers/060-bram-cascades/Makefile | 7 +- fuzzers/int_maketodo.py | 34 +++-- fuzzers/pip_loop.mk | 15 ++- 7 files changed, 183 insertions(+), 38 deletions(-) diff --git a/fuzzers/041-clk-hrow-pips/Makefile b/fuzzers/041-clk-hrow-pips/Makefile index 400f43c9..1bb8bc01 100644 --- a/fuzzers/041-clk-hrow-pips/Makefile +++ b/fuzzers/041-clk-hrow-pips/Makefile @@ -1,15 +1,19 @@ -N ?= 150 +export FUZDIR=$(shell pwd) +PIP_TYPE?=clk_hrow +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 2 SPECIMENS_DEPS=build/cmt_regions.csv -include ../fuzzer.mk +A_PIPLIST=clk_hrow_bot_r.txt + +include ../pip_loop.mk database: build/segbits_clk_hrow.db -build/clk_hrow_bot_r.txt: clk_hrow_pip_list.tcl - mkdir -p build - cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/clk_hrow_pip_list.tcl - -build/cmt_regions.csv: output_cmt.tcl build/clk_hrow_bot_r.txt +build/cmt_regions.csv: output_cmt.tcl mkdir -p build cd build/ && ${XRAY_VIVADO} -mode batch -source ${FUZDIR}/output_cmt.tcl @@ -18,19 +22,31 @@ build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) -build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb build/clk_hrow_bot_r.txt +build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb $(XRAY_FUZZERS_DIR)/piplist/build/clk_hrow_bot_r.txt ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ --seg-fn-in build/segbits_clk_hrow.rdb \ --seg-fn-out build/segbits_clk_hrow_rc.db + + # Convert row/column into PIP definition. python3 merge_clk_entries.py \ build/segbits_clk_hrow_rc.db \ - build/clk_hrow_bot_r.txt \ + $(XRAY_FUZZERS_DIR)/piplist/build/clk_hrow_bot_r.txt \ build/segbits_clk_hrow.db + # Keep a copy to track iter progress + cp build/segbits_clk_hrow.rdb build/$(ITER)/segbits_clk_hrow.rdb + cp build/segbits_clk_hrow_rc.db build/$(ITER)/segbits_clk_hrow_rc.db + + ${XRAY_MASKMERGE} build/mask_clk_hrow.db \ $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) + # Clobber existing .db to eliminate potential conflicts + cp ${XRAY_DATABASE_DIR}/${XRAY_DATABASE}/segbits*.db build/database/${XRAY_DATABASE} + XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db + XRAY_DATABASE_DIR=${FUZDIR}/build/database ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db + pushdb: database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db ${XRAY_MERGEDB} clk_hrow_top_r build/segbits_clk_hrow.db diff --git a/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl b/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl index b21bec3a..83872c61 100644 --- a/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl +++ b/fuzzers/041-clk-hrow-pips/clk_hrow_pip_list.tcl @@ -18,4 +18,3 @@ open_io_design -name io_1 print_tile_pips CLK_HROW_TOP_R clk_hrow_top_r.txt print_tile_pips CLK_HROW_BOT_R clk_hrow_bot_r.txt -print_tile_pips CLK_BUFG_REBUF clk_bufg_rebuf.txt diff --git a/fuzzers/041-clk-hrow-pips/clk_table.py b/fuzzers/041-clk-hrow-pips/clk_table.py index 0b46564b..a6721dc3 100644 --- a/fuzzers/041-clk-hrow-pips/clk_table.py +++ b/fuzzers/041-clk-hrow-pips/clk_table.py @@ -8,14 +8,10 @@ CLK_TABLE_NUM_COLS = 8 for gclk in range(GCLKS): gclk_name = 'CLK_HROW_R_CK_GCLK{}'.format(gclk) - row = gclk % 8 - column = int(gclk / 8) + row = gclk % CLK_TABLE_NUM_ROWS + column = int(gclk / CLK_TABLE_NUM_ROWS) CLK_TABLE[gclk_name] = (row, column) -for lr in ['L', 'R']: - for side_inputs in range(SIDE_CLK_INPUTS): - side_clk_name = 'CLK_HROW_CK_IN_{}{}'.format(lr, side_inputs) - for row in range(8): CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row)] = (row, 4) for row in range(6): diff --git a/fuzzers/041-clk-hrow-pips/generate.tcl b/fuzzers/041-clk-hrow-pips/generate.tcl index 05210e30..e9f672b4 100644 --- a/fuzzers/041-clk-hrow-pips/generate.tcl +++ b/fuzzers/041-clk-hrow-pips/generate.tcl @@ -1,3 +1,5 @@ +source "$::env(XRAY_DIR)/utils/utils.tcl" + proc write_pip_txtdata {filename} { puts "FUZ([pwd]): Writing $filename." set fp [open $filename w] @@ -21,6 +23,124 @@ proc write_pip_txtdata {filename} { close $fp } +proc load_todo {} { + set fp [open "../../todo.txt" r] + set todo_lines {} + for {gets $fp line} {$line != ""} {gets $fp line} { + lappend todo_lines [split $line .] + } + close $fp + return $todo_lines +} + +proc route_todo {} { + puts "Checking TODO's" + set todo_lines [load_todo] + set srcs {} + foreach todo $todo_lines { + set src [lindex $todo 2] + + if [string match "*CLK_HROW_CK_IN_*" $src] { + lappend srcs $src + } + } + + set srcs [lsort -unique $srcs] + + set nets [get_nets -hierarchical "*clock*"] + set found_wires {} + set remaining_nets {} + foreach net $nets { + set wires [get_wires -of_objects $net] + + foreach wire $wires { + if [regexp "CLK_HROW_CK_IN_\[LR\]\[0-9\]+" $wire] { + # Route already going where we want it, continue + puts "Checking wire $wire." + set wire [lindex [split $wire "/"] 1] + if {[lsearch -regexp $srcs "$wire$"] != -1} { + puts "Found in TODO list, removing from list." + lappend found_wires $wire + # Fix route that is using target net. + set_property is_route_fixed 1 $net + } else { + puts "Wire not in TODO list, adding to reroute list." + lappend remaining_nets $net + } + break + } + } + } + + set found_wires [lsort -unique $found_wires] + foreach wire $found_wires { + puts "Removing $wire" + set srcs [lsearch -regexp -all -inline -not $srcs "$wire$"] + } + + puts "Remaining TODOs:" + foreach src $srcs { + puts $src + } + + set remaining_nets [lsort -unique $remaining_nets] + set completed_todos {} + + foreach net $remaining_nets { + set wires [get_wires -of_objects $net] + + set clk_in_wire "" + foreach wire $wires { + if [regexp "CLK_HROW_CK_IN_(\[LR\])\[0-9\]+" $wire match lr] { + set clk_in_wire $wire + break + } + } + + if {$clk_in_wire == ""} { + error "$net does not appear to be correct net for rerouting?" + } + + puts "" + puts "Rerouting net $net at $clk_in_wire ($lr)" + + # Find an input in the todo list that this can can drive. + foreach src $srcs { + if {[lsearch -exact $completed_todos $src] != -1} { + continue + } + + if [regexp "CLK_HROW_CK_IN_$lr\[0-9\]+" $src] { + puts "Found target pip $src for net $net." + set tile [get_tiles -of_objects $clk_in_wire] + + set target_wire [get_wires "$tile/$src"] + set target_node [get_nodes -of_objects $target_wire] + if {[llength $target_node] == 0} { + error "Failed to find node for $tile/$src." + } + + set origin_node [get_nodes -of_objects [get_site_pins -filter {DIRECTION == OUT} -of_objects $net]] + set destination_nodes [get_nodes -of_objects [get_site_pins -filter {DIRECTION == IN} -of_objects $net]] + route_design -unroute -nets $net + set new_route [find_routing_path -to $target_node -from $origin_node] + puts "Origin node: $origin_node" + puts "Target wire: $target_wire" + puts "Target node: $target_node" + puts "Destination nodes: $destination_nodes" + + # Only need to set route to one of the destinations. + # Router will handle the rest. + set_property FIXED_ROUTE [concat $new_route [lindex $destination_nodes 0]] $net + + # Remove wire, as we've found a clock to set + lappend completed_todos $src + break + } + } + } +} + proc run {} { create_project -force -part $::env(XRAY_PART) design design read_verilog top.v @@ -36,6 +156,8 @@ proc run {} { place_design route_design + route_todo + route_design write_checkpoint -force design.dcp write_bitstream -force design.bit diff --git a/fuzzers/060-bram-cascades/Makefile b/fuzzers/060-bram-cascades/Makefile index 2b8d61bc..bf8f531b 100644 --- a/fuzzers/060-bram-cascades/Makefile +++ b/fuzzers/060-bram-cascades/Makefile @@ -1,11 +1,12 @@ -MAKETODO_FLAGS=--re "BRAM_.\.BRAM_(?!LOGIC_OUTS).*" export FUZDIR=$(shell pwd) -PIPLIST_TCL=$(FUZDIR)/bram_pip_list.tcl PIP_TYPE?=bram_pips_int -SEG_TYPE?=bram +PIPLIST_TCL=$(FUZDIR)/bram_pip_list.tcl +MAKETODO_FLAGS=--pip-type ${PIP_TYPE} --seg-type bram --re "BRAM_.\.BRAM_(?!LOGIC_OUTS).*" N = 50 + # These PIPs all appear to be either a 0 or 2 bit solution. SEGMATCH_FLAGS=-m 20 -M 45 -c 2 + include ../pip_loop.mk # # Specimens from current run must complete, but previous iterations may exist diff --git a/fuzzers/int_maketodo.py b/fuzzers/int_maketodo.py index 69b1d9e3..f022202d 100644 --- a/fuzzers/int_maketodo.py +++ b/fuzzers/int_maketodo.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 import os, re -import sys from prjxray import util @@ -90,6 +89,7 @@ def run( db_dir, pip_dir, intre, + l, r, pip_type, seg_type, not_endswith=None, @@ -102,18 +102,22 @@ def run( pip_dir = "%s/piplist/build" % (os.getenv("XRAY_FUZZERS_DIR")) assert intre, "RE is required" - maketodo( - "%s/%s_l.txt" % (pip_dir, pip_type), - "%s/segbits_%s_l.db" % (db_dir, seg_type), - intre, - not_endswith, - verbose=verbose) - maketodo( - "%s/%s_r.txt" % (pip_dir, pip_type), - "%s/segbits_%s_r.db" % (db_dir, seg_type), - intre, - not_endswith, - verbose=verbose) + + if l: + maketodo( + "%s/%s_l.txt" % (pip_dir, pip_type), + "%s/segbits_%s_l.db" % (db_dir, seg_type), + intre, + not_endswith, + verbose=verbose) + + if r: + maketodo( + "%s/%s_r.txt" % (pip_dir, pip_type), + "%s/segbits_%s_r.db" % (db_dir, seg_type), + intre, + not_endswith, + verbose=verbose) def main(): @@ -129,6 +133,8 @@ def main(): parser.add_argument('--re', required=True, help='') parser.add_argument('--pip-type', default="pips_int", help='') parser.add_argument('--seg-type', default="int", help='') + util.add_bool_arg(parser, '--l', default=True, help='') + util.add_bool_arg(parser, '--r', default=True, help='') parser.add_argument( '--not-endswith', help='Drop lines if they end with this') args = parser.parse_args() @@ -138,6 +144,8 @@ def main(): db_dir=args.db_dir, pip_dir=args.pip_dir, intre=args.re, + l=args.l, + r=args.r, pip_type=args.pip_type, seg_type=args.seg_type, not_endswith=args.not_endswith, diff --git a/fuzzers/pip_loop.mk b/fuzzers/pip_loop.mk index 1c1497b9..6fad6d66 100644 --- a/fuzzers/pip_loop.mk +++ b/fuzzers/pip_loop.mk @@ -12,10 +12,11 @@ endif # Iteration number (each containing N specimens) # Driven by int_loop.sh ITER ?= 1 -MAKETODO_FLAGS ?= PIP_TYPE?=pips_int -SEG_TYPE?=int +MAKETODO_FLAGS ?=--pip-type pips_int --seg-type int +A_PIPLIST?=$(PIP_TYPE)_l.txt PIPLIST_TCL?=$(XRAY_FUZZERS_DIR)/piplist/piplist.tcl +SPECIMENS_DEPS ?= # See int_loop_check.py # rempips took 35 iters once, so set 50 as a good start point @@ -27,18 +28,20 @@ export FUZDIR=$(shell pwd) all: database -$(SPECIMENS_OK): build/todo.txt +$(SPECIMENS_OK): build/todo.txt $(SPECIMENS_DEPS) mkdir -p build/$(ITER) bash ${XRAY_DIR}/utils/top_generate.sh $(subst /OK,,$@) touch $@ -$(XRAY_FUZZERS_DIR)/piplist/build/$(PIP_TYPE)_l.txt: $(PIPLIST_TCL) +$(XRAY_FUZZERS_DIR)/piplist/build/$(A_PIPLIST): $(PIPLIST_TCL) mkdir -p $(XRAY_FUZZERS_DIR)/piplist/build cd $(XRAY_FUZZERS_DIR)/piplist/build && ${XRAY_VIVADO} -mode batch -source $(PIPLIST_TCL) # Used 1) to see if we are done 2) pips to try in generate.tcl -build/todo.txt: $(XRAY_FUZZERS_DIR)/piplist/build/$(PIP_TYPE)_l.txt $(XRAY_DIR)/fuzzers/int_maketodo.py build/database/seeded - XRAY_DATABASE_DIR=${FUZDIR}/build/database python3 $(XRAY_DIR)/fuzzers/int_maketodo.py --pip-type $(PIP_TYPE) --seg-type $(SEG_TYPE) $(MAKETODO_FLAGS) |sort >build/todo_all.txt +build/todo.txt: $(XRAY_FUZZERS_DIR)/piplist/build/$(A_PIPLIST) $(XRAY_DIR)/fuzzers/int_maketodo.py build/database/seeded + XRAY_DATABASE_DIR=${FUZDIR}/build/database \ + python3 $(XRAY_DIR)/fuzzers/int_maketodo.py \ + $(MAKETODO_FLAGS) |sort >build/todo_all.txt cat build/todo_all.txt | sort -R | head -n$(TODO_N) > build/todo.txt.tmp mv build/todo.txt.tmp build/todo.txt # Per iter files From 524c85fb3a0ef513464f3e910dfb358423f93d50 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Mon, 11 Feb 2019 13:03:42 -0800 Subject: [PATCH 09/13] Make format. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/041-clk-hrow-pips/clk_table.py | 10 +- fuzzers/041-clk-hrow-pips/generate.py | 12 ++- .../041-clk-hrow-pips/merge_clk_entries.py | 24 +++-- fuzzers/041-clk-hrow-pips/top.py | 99 +++++++++++-------- fuzzers/int_maketodo.py | 3 +- 5 files changed, 87 insertions(+), 61 deletions(-) diff --git a/fuzzers/041-clk-hrow-pips/clk_table.py b/fuzzers/041-clk-hrow-pips/clk_table.py index a6721dc3..fe09fb54 100644 --- a/fuzzers/041-clk-hrow-pips/clk_table.py +++ b/fuzzers/041-clk-hrow-pips/clk_table.py @@ -13,18 +13,18 @@ for gclk in range(GCLKS): CLK_TABLE[gclk_name] = (row, column) for row in range(8): - CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row)] = (row, 4) + CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row)] = (row, 4) for row in range(6): - CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row+8)] = (row, 5) + CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row + 8)] = (row, 5) for row in range(8): - CLK_TABLE['CLK_HROW_CK_IN_R{}'.format(row)] = (row, 6) + CLK_TABLE['CLK_HROW_CK_IN_R{}'.format(row)] = (row, 6) for row in range(6): - CLK_TABLE['CLK_HROW_CK_IN_R{}'.format(row+8)] = (row, 7) + CLK_TABLE['CLK_HROW_CK_IN_R{}'.format(row + 8)] = (row, 7) # HROW_CK_INT__, Y == Y share the same bits, and only X = 0 or X = 1 are # present on a particular HROW. for y in range(2): for x in range(2): int_clk_name = 'CLK_HROW_CK_INT_{}_{}'.format(x, y) - CLK_TABLE[int_clk_name] = (y+6, 7) + CLK_TABLE[int_clk_name] = (y + 6, 7) diff --git a/fuzzers/041-clk-hrow-pips/generate.py b/fuzzers/041-clk-hrow-pips/generate.py index 1974ba74..5fd6cc75 100644 --- a/fuzzers/041-clk-hrow-pips/generate.py +++ b/fuzzers/041-clk-hrow-pips/generate.py @@ -27,17 +27,21 @@ def main(): if src in clk_table.CLK_TABLE: row, column = clk_table.CLK_TABLE[src] - segmk.add_tile_tag(tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 1) - segmk.add_tile_tag(tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 1) + segmk.add_tile_tag( + tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 1) + segmk.add_tile_tag( + tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 1) rows.remove(row) columns.remove(column) for row in rows: - segmk.add_tile_tag(tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 0) + segmk.add_tile_tag( + tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 0) for column in columns: - segmk.add_tile_tag(tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 0) + segmk.add_tile_tag( + tile, '{}.HCLK_ENABLE_COLUMN{}'.format(dst, column), 0) 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 53005716..89d42fe6 100644 --- a/fuzzers/041-clk-hrow-pips/merge_clk_entries.py +++ b/fuzzers/041-clk-hrow-pips/merge_clk_entries.py @@ -1,8 +1,10 @@ import argparse import clk_table + def main(): - parser = argparse.ArgumentParser(description="Convert HCLK ROW/COLUMN definitions into HCLK pips.") + parser = argparse.ArgumentParser( + description="Convert HCLK ROW/COLUMN definitions into HCLK pips.") parser.add_argument('in_segbit') parser.add_argument('piplist') parser.add_argument('out_segbit') @@ -27,9 +29,9 @@ def main(): if dst not in hrow_outs: hrow_outs[dst] = { - 'rows': {}, - 'columns': {}, - } + 'rows': {}, + 'columns': {}, + } if src[-4:-1] == 'ROW': hrow_outs[dst]['rows'][n] = bits @@ -62,12 +64,14 @@ def main(): if column not in hrow_outs[dst]['columns']: continue - print('CLK_HROW.{dst}.{inclk} {row_bits} {column_bits}'.format( - dst=dst, - inclk=src, - row_bits=hrow_outs[dst]['rows'][row], - column_bits=hrow_outs[dst]['columns'][column], - ), file=f) + print( + 'CLK_HROW.{dst}.{inclk} {row_bits} {column_bits}'.format( + dst=dst, + inclk=src, + row_bits=hrow_outs[dst]['rows'][row], + column_bits=hrow_outs[dst]['columns'][column], + ), + file=f) if __name__ == "__main__": diff --git a/fuzzers/041-clk-hrow-pips/top.py b/fuzzers/041-clk-hrow-pips/top.py index 32d45177..c599770b 100644 --- a/fuzzers/041-clk-hrow-pips/top.py +++ b/fuzzers/041-clk-hrow-pips/top.py @@ -7,7 +7,6 @@ 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: @@ -17,12 +16,14 @@ 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() @@ -52,13 +53,16 @@ def gen_bufhce_sites(): def read_site_to_cmt(): - with open(os.path.join(os.getenv('FUZDIR'), 'build', 'cmt_regions.csv')) as f: + with open(os.path.join(os.getenv('FUZDIR'), 'build', + 'cmt_regions.csv')) as f: for l in f: site, cmt = l.strip().split(',') yield (site, cmt) + CMT_RE = re.compile('X([0-9]+)Y([0-9]+)') + class ClockSources(object): def __init__(self): self.sources = {} @@ -71,7 +75,8 @@ class ClockSources(object): self.sources[cmt] = [] self.sources[cmt].append(source) - assert source not in self.source_to_cmt or self.source_to_cmt[source] == cmt, source + assert source not in self.source_to_cmt or self.source_to_cmt[ + source] == cmt, source self.source_to_cmt[source] = cmt def get_random_source(self, cmt): @@ -108,7 +113,8 @@ class ClockSources(object): self.used_sources_from_cmt[source_cmt].add(source) - if source_cmt != 'ANY' and len(self.used_sources_from_cmt[source_cmt]) > 14: + if source_cmt != 'ANY' and len( + self.used_sources_from_cmt[source_cmt]) > 14: print('//', self.used_sources_from_cmt) self.used_sources_from_cmt[source_cmt].remove(source) return None @@ -126,6 +132,7 @@ def check_allowed(mmcm_pll_dir, cmt): else: assert False, mmcm_pll_dir + def main(): print(''' module top(); @@ -150,19 +157,22 @@ module top(); for idx in range(1): wire_name = "lut_wire_{}".format(idx) #clock_sources.add_clock_source(wire_name, 'ANY') - print(""" + print( + """ (* KEEP, DONT_TOUCH *) wire {wire_name}; LUT6 lut{idx} ( .O({wire_name}) );""".format( - idx=idx, - wire_name=wire_name, + idx=idx, + wire_name=wire_name, )) for site in gen_sites('MMCME2_ADV'): - mmcm_clocks = ['mmcm_clock_{site}_{idx}'.format(site=site, idx=idx) for - idx in range(13)] + mmcm_clocks = [ + 'mmcm_clock_{site}_{idx}'.format(site=site, idx=idx) + for idx in range(13) + ] if not check_allowed(mmcm_pll_dir, site_to_cmt[site]): continue @@ -170,7 +180,8 @@ module top(); for clk in mmcm_clocks: clock_sources.add_clock_source(clk, site_to_cmt[site]) - print(""" + print( + """ wire {c0}, {c1}, {c2}, {c3}, {c4}, {c5}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) MMCME2_ADV pll_{site} ( @@ -189,25 +200,27 @@ module top(); .CLKFBOUTB({c12}) ); """.format( - site=site, - c0=mmcm_clocks[0], - c1=mmcm_clocks[1], - c2=mmcm_clocks[2], - c3=mmcm_clocks[3], - c4=mmcm_clocks[4], - c5=mmcm_clocks[5], - c6=mmcm_clocks[6], - c7=mmcm_clocks[7], - c8=mmcm_clocks[8], - c9=mmcm_clocks[9], - c10=mmcm_clocks[10], - c11=mmcm_clocks[11], - c12=mmcm_clocks[12], + site=site, + c0=mmcm_clocks[0], + c1=mmcm_clocks[1], + c2=mmcm_clocks[2], + c3=mmcm_clocks[3], + c4=mmcm_clocks[4], + c5=mmcm_clocks[5], + c6=mmcm_clocks[6], + c7=mmcm_clocks[7], + c8=mmcm_clocks[8], + c9=mmcm_clocks[9], + c10=mmcm_clocks[10], + c11=mmcm_clocks[11], + c12=mmcm_clocks[12], )) for site in gen_sites('PLLE2_ADV'): - pll_clocks = ['pll_clock_{site}_{idx}'.format(site=site, idx=idx) for - idx in range(6)] + pll_clocks = [ + 'pll_clock_{site}_{idx}'.format(site=site, idx=idx) + for idx in range(6) + ] if not check_allowed(mmcm_pll_dir, site_to_cmt[site]): continue @@ -215,7 +228,8 @@ module top(); for clk in pll_clocks: clock_sources.add_clock_source(clk, site_to_cmt[site]) - print(""" + print( + """ wire {c0}, {c1}, {c2}, {c3}, {c4}, {c5}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) PLLE2_ADV pll_{site} ( @@ -227,13 +241,13 @@ module top(); .CLKOUT5({c5}) ); """.format( - site=site, - c0=pll_clocks[0], - c1=pll_clocks[1], - c2=pll_clocks[2], - c3=pll_clocks[3], - c4=pll_clocks[4], - c5=pll_clocks[5], + site=site, + c0=pll_clocks[0], + c1=pll_clocks[1], + c2=pll_clocks[2], + c3=pll_clocks[3], + c4=pll_clocks[4], + c5=pll_clocks[5], )) for site in sorted(gen_sites("BUFGCTRL"), key=get_xy): @@ -242,15 +256,16 @@ module top(); if not mmcm_pll_only: clock_sources.add_clock_source(wire_name, 'ANY') - print(""" + print( + """ wire {wire_name}; (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFG bufg_{site} ( .O({wire_name}) ); """.format( - site=site, - wire_name=wire_name, + site=site, + wire_name=wire_name, )) bufhce_sites = list(gen_bufhce_sites()) @@ -260,17 +275,19 @@ module top(); if wire_name is None: continue - print(""" + print( + """ (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE buf_{site} ( .I({wire_name}) ); """.format( - site=site, - wire_name=wire_name, - )) + site=site, + wire_name=wire_name, + )) print("endmodule") + if __name__ == '__main__': main() diff --git a/fuzzers/int_maketodo.py b/fuzzers/int_maketodo.py index f022202d..8ed0774a 100644 --- a/fuzzers/int_maketodo.py +++ b/fuzzers/int_maketodo.py @@ -89,7 +89,8 @@ def run( db_dir, pip_dir, intre, - l, r, + l, + r, pip_type, seg_type, not_endswith=None, From 91044cedd07c20f9f10ae31323ca2c49fd495022 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Mon, 11 Feb 2019 14:36:47 -0800 Subject: [PATCH 10/13] Add ZINV_CE config. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/040-clk-hrow-config/generate.py | 3 +++ fuzzers/040-clk-hrow-config/top.py | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/fuzzers/040-clk-hrow-config/generate.py b/fuzzers/040-clk-hrow-config/generate.py index 1fe04bcf..8fc7d1ee 100644 --- a/fuzzers/040-clk-hrow-config/generate.py +++ b/fuzzers/040-clk-hrow-config/generate.py @@ -24,6 +24,9 @@ def main(): segmk.add_site_tag( row['site'], '{}.INIT_OUT'.format(base_name), row['INIT_OUT']) + segmk.add_site_tag( + row['site'], '{}.ZINV_CE'.format(base_name), 1 ^ row['IS_CE_INVERTED']) + # SYNC is a zero pattern for opt in ['ASYNC']: segmk.add_site_tag( diff --git a/fuzzers/040-clk-hrow-config/top.py b/fuzzers/040-clk-hrow-config/top.py index 9b3d329e..8979f096 100644 --- a/fuzzers/040-clk-hrow-config/top.py +++ b/fuzzers/040-clk-hrow-config/top.py @@ -57,13 +57,14 @@ module top(); params['INIT_OUT'] = random.randint(0, 1) params['CE_TYPE'] = verilog.quote( random.choice(('SYNC', 'ASYNC'))) - + params['IS_CE_INVERTED'] = random.randint(0, 1) print( ''' (* KEEP, DONT_TOUCH, LOC = "{site}" *) BUFHCE #( .INIT_OUT({INIT_OUT}), - .CE_TYPE({CE_TYPE}) + .CE_TYPE({CE_TYPE}), + .IS_CE_INVERTED({IS_CE_INVERTED}) ) buf_{site} (); '''.format(**params)) From d2c9c96b968ebaa3c959e3dcb5fbc7703f2f150f Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 13:24:08 -0800 Subject: [PATCH 11/13] Add 041 to root fuzzer Makefile. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/fuzzers/Makefile b/fuzzers/Makefile index 50afad6c..b3b0d145 100644 --- a/fuzzers/Makefile +++ b/fuzzers/Makefile @@ -71,6 +71,7 @@ $(eval $(call fuzzer,027-bram36-config,005-tilegrid)) $(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,050-pip-seed,005-tilegrid)) $(eval $(call fuzzer,051-pip-imuxlout-bypalts,050-pip-seed)) $(eval $(call fuzzer,052-pip-clkin,050-pip-seed)) From ca232e4e8117fc96dfcb6298c16f20c178f1e719 Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 14:06:45 -0800 Subject: [PATCH 12/13] Address review comments. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/040-clk-hrow-config/Makefile | 8 +- fuzzers/040-clk-hrow-config/generate.py | 3 +- fuzzers/040-clk-hrow-config/top.py | 11 +-- fuzzers/041-clk-hrow-pips/clk_table.py | 44 +++++---- fuzzers/041-clk-hrow-pips/generate.py | 5 +- .../041-clk-hrow-pips/merge_clk_entries.py | 6 +- fuzzers/041-clk-hrow-pips/top.py | 91 ++++++++++--------- prjxray/util.py | 35 +++++++ 8 files changed, 124 insertions(+), 79 deletions(-) diff --git a/fuzzers/040-clk-hrow-config/Makefile b/fuzzers/040-clk-hrow-config/Makefile index c815d293..f20a6d84 100644 --- a/fuzzers/040-clk-hrow-config/Makefile +++ b/fuzzers/040-clk-hrow-config/Makefile @@ -5,13 +5,17 @@ include ../fuzzer.mk database: build/segbits_clk_hrow.db build/segbits_clk_hrow.rdb: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} -o build/segbits_clk_hrow.rdb $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) + ${XRAY_SEGMATCH} -o build/segbits_clk_hrow.rdb \ + $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ + $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) build/segbits_clk_hrow.db: build/segbits_clk_hrow.rdb ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \ --seg-fn-in build/segbits_clk_hrow.rdb \ --seg-fn-out build/segbits_clk_hrow.db - ${XRAY_MASKMERGE} build/mask_clk_hrow.db $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) + ${XRAY_MASKMERGE} build/mask_clk_hrow.db \ + $(addsuffix /segdata_clk_hrow_top_r.txt,$(SPECIMENS)) \ + $(addsuffix /segdata_clk_hrow_bot_r.txt,$(SPECIMENS)) pushdb: database ${XRAY_MERGEDB} clk_hrow_bot_r build/segbits_clk_hrow.db diff --git a/fuzzers/040-clk-hrow-config/generate.py b/fuzzers/040-clk-hrow-config/generate.py index 8fc7d1ee..615f03b0 100644 --- a/fuzzers/040-clk-hrow-config/generate.py +++ b/fuzzers/040-clk-hrow-config/generate.py @@ -25,7 +25,8 @@ def main(): row['site'], '{}.INIT_OUT'.format(base_name), row['INIT_OUT']) segmk.add_site_tag( - row['site'], '{}.ZINV_CE'.format(base_name), 1 ^ row['IS_CE_INVERTED']) + row['site'], '{}.ZINV_CE'.format(base_name), + 1 ^ row['IS_CE_INVERTED']) # SYNC is a zero pattern for opt in ['ASYNC']: diff --git a/fuzzers/040-clk-hrow-config/top.py b/fuzzers/040-clk-hrow-config/top.py index 8979f096..56a0d54f 100644 --- a/fuzzers/040-clk-hrow-config/top.py +++ b/fuzzers/040-clk-hrow-config/top.py @@ -1,18 +1,14 @@ 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('^BUFHCE_X([0-9]+)Y([0-9]+)$') - def gen_sites(): - db = Database(util.get_db_root()) - grid = db.grid() + get_xy = util.create_xy_fun('BUFHCE_') db = Database(util.get_db_root()) grid = db.grid() for tile_name in sorted(grid.tiles()): @@ -24,10 +20,7 @@ def gen_sites(): ys = [] for site, site_type in gridinfo.sites.items(): if site_type == 'BUFHCE': - m = re.match(XY_RE, site) - assert m, site - x = int(m.group(1)) - y = int(m.group(2)) + x, y = get_xy(site) xs.append(x) ys.append(y) diff --git a/fuzzers/041-clk-hrow-pips/clk_table.py b/fuzzers/041-clk-hrow-pips/clk_table.py index fe09fb54..9b3ccdfd 100644 --- a/fuzzers/041-clk-hrow-pips/clk_table.py +++ b/fuzzers/041-clk-hrow-pips/clk_table.py @@ -1,30 +1,34 @@ HCLKS = 24 GCLKS = 32 SIDE_CLK_INPUTS = 14 -CLK_TABLE = {} CLK_TABLE_NUM_ROWS = 8 CLK_TABLE_NUM_COLS = 8 -for gclk in range(GCLKS): - gclk_name = 'CLK_HROW_R_CK_GCLK{}'.format(gclk) - row = gclk % CLK_TABLE_NUM_ROWS - column = int(gclk / CLK_TABLE_NUM_ROWS) - CLK_TABLE[gclk_name] = (row, column) -for row in range(8): - CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row)] = (row, 4) -for row in range(6): - CLK_TABLE['CLK_HROW_CK_IN_L{}'.format(row + 8)] = (row, 5) +def get_clk_table(): + clk_table = {} + for gclk in range(GCLKS): + gclk_name = 'CLK_HROW_R_CK_GCLK{}'.format(gclk) + row = gclk % CLK_TABLE_NUM_ROWS + column = int(gclk / CLK_TABLE_NUM_ROWS) + clk_table[gclk_name] = (row, column) -for row in range(8): - CLK_TABLE['CLK_HROW_CK_IN_R{}'.format(row)] = (row, 6) -for row in range(6): - CLK_TABLE['CLK_HROW_CK_IN_R{}'.format(row + 8)] = (row, 7) + for row in range(8): + clk_table['CLK_HROW_CK_IN_L{}'.format(row)] = (row, 4) + for row in range(6): + clk_table['CLK_HROW_CK_IN_L{}'.format(row + 8)] = (row, 5) -# HROW_CK_INT__, Y == Y share the same bits, and only X = 0 or X = 1 are -# present on a particular HROW. -for y in range(2): - for x in range(2): - int_clk_name = 'CLK_HROW_CK_INT_{}_{}'.format(x, y) - CLK_TABLE[int_clk_name] = (y + 6, 7) + for row in range(8): + clk_table['CLK_HROW_CK_IN_R{}'.format(row)] = (row, 6) + for row in range(6): + clk_table['CLK_HROW_CK_IN_R{}'.format(row + 8)] = (row, 7) + + # HROW_CK_INT__, Y == Y share the same bits, and only X = 0 or X = 1 + # are present on a particular HROW. + for y in range(2): + for x in range(2): + int_clk_name = 'CLK_HROW_CK_INT_{}_{}'.format(x, y) + clk_table[int_clk_name] = (y + 6, 7) + + return clk_table diff --git a/fuzzers/041-clk-hrow-pips/generate.py b/fuzzers/041-clk-hrow-pips/generate.py index 5fd6cc75..fe4e53c0 100644 --- a/fuzzers/041-clk-hrow-pips/generate.py +++ b/fuzzers/041-clk-hrow-pips/generate.py @@ -6,6 +6,7 @@ import clk_table def main(): segmk = Segmaker("design.bits") + table = clk_table.get_clk_table() print("Loading tags from design.txt.") with open("design.txt", "r") as f: @@ -24,8 +25,8 @@ def main(): rows = set(range(clk_table.CLK_TABLE_NUM_ROWS)) columns = set(range(clk_table.CLK_TABLE_NUM_COLS)) - if src in clk_table.CLK_TABLE: - row, column = clk_table.CLK_TABLE[src] + if src in table: + row, column = table[src] segmk.add_tile_tag( tile, '{}.HCLK_ENABLE_ROW{}'.format(dst, row), 1) diff --git a/fuzzers/041-clk-hrow-pips/merge_clk_entries.py b/fuzzers/041-clk-hrow-pips/merge_clk_entries.py index 89d42fe6..f7e2ea27 100644 --- a/fuzzers/041-clk-hrow-pips/merge_clk_entries.py +++ b/fuzzers/041-clk-hrow-pips/merge_clk_entries.py @@ -50,13 +50,15 @@ def main(): piplists[dst].append(src) + table = clk_table.get_clk_table() + with open(args.out_segbit, 'w') as f: for dst in sorted(hrow_outs): for src in sorted(piplists[dst]): - if src not in clk_table.CLK_TABLE: + if src not in table: continue - row, column = clk_table.CLK_TABLE[src] + row, column = table[src] if row not in hrow_outs[dst]['rows']: continue diff --git a/fuzzers/041-clk-hrow-pips/top.py b/fuzzers/041-clk-hrow-pips/top.py index c599770b..fe72f644 100644 --- a/fuzzers/041-clk-hrow-pips/top.py +++ b/fuzzers/041-clk-hrow-pips/top.py @@ -1,27 +1,11 @@ +""" Emits top.v's for various BUFHCE routing inputs. """ import os -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 +CMT_XY_FUN = util.create_xy_fun(prefix='') def gen_sites(desired_site_type): @@ -53,6 +37,7 @@ def gen_bufhce_sites(): def read_site_to_cmt(): + """ Yields clock sources and which CMT they route within. """ with open(os.path.join(os.getenv('FUZDIR'), 'build', 'cmt_regions.csv')) as f: for l in f: @@ -60,10 +45,15 @@ def read_site_to_cmt(): yield (site, cmt) -CMT_RE = re.compile('X([0-9]+)Y([0-9]+)') - - class ClockSources(object): + """ Class for tracking clock sources. + + Some clock sources can be routed to any CMT, for these, cmt='ANY'. + For clock sources that belong to a CMT, cmt should be set to the CMT of + the source. + + """ + def __init__(self): self.sources = {} self.merged_sources = {} @@ -71,6 +61,10 @@ class ClockSources(object): self.used_sources_from_cmt = {} def add_clock_source(self, source, cmt): + """ Adds a source from a specific CMT. + + cmt='ANY' indicates that this source can be routed to any CMT. + """ if cmt not in self.sources: self.sources[cmt] = [] @@ -80,6 +74,12 @@ class ClockSources(object): self.source_to_cmt[source] = cmt def get_random_source(self, cmt): + """ Get a random source that is routable to the specific CMT. + + get_random_source will return a source that is either cmt='ANY', + cmt equal to the input CMT, or the adjecent CMT. + + """ if cmt not in self.merged_sources: choices = [] if 'ANY' in self.sources: @@ -88,9 +88,7 @@ class ClockSources(object): if cmt in self.sources: choices.extend(self.sources[cmt]) - m = CMT_RE.match(cmt) - x = int(m.group(1)) - y = int(m.group(2)) + x, y = CMT_XY_FUN(cmt) if x % 2 == 0: x += 1 @@ -123,17 +121,35 @@ class ClockSources(object): def check_allowed(mmcm_pll_dir, cmt): + """ Check whether the CMT specified is in the allowed direction. + + This function is designed to bias sources to either the left or right + input lines. + + """ if mmcm_pll_dir == 'BOTH': return True elif mmcm_pll_dir == 'ODD': - return (int(CMT_RE.match(cmt).group(1)) & 1) == 1 + x, y = CMT_XY_FUN(cmt) + return (x & 1) == 1 elif mmcm_pll_dir == 'EVEN': - return (int(CMT_RE.match(cmt).group(1)) & 1) == 0 + x, y = CMT_XY_FUN(cmt) + return (x & 1) == 0 else: assert False, mmcm_pll_dir def main(): + """ + BUFHCE's can be driven from: + + MMCME2_ADV + PLLE2_ADV + BUFGCTRL + Local INT connect + + """ + print(''' module top(); ''') @@ -142,6 +158,9 @@ module top(); clock_sources = ClockSources() + # To ensure that all left or right sources are used, sometimes only MMCM/PLL + # sources are allowed. The force of ODD/EVEN/BOTH further biases the + # clock sources to the left or right column inputs. mmcm_pll_only = random.randint(0, 1) mmcm_pll_dir = random.choice(('ODD', 'EVEN', 'BOTH')) @@ -154,20 +173,6 @@ module top(); wire zero = 0; wire one = 1;""") - for idx in range(1): - wire_name = "lut_wire_{}".format(idx) - #clock_sources.add_clock_source(wire_name, 'ANY') - print( - """ - (* KEEP, DONT_TOUCH *) - wire {wire_name}; - LUT6 lut{idx} ( - .O({wire_name}) - );""".format( - idx=idx, - wire_name=wire_name, - )) - for site in gen_sites('MMCME2_ADV'): mmcm_clocks = [ 'mmcm_clock_{site}_{idx}'.format(site=site, idx=idx) @@ -250,7 +255,8 @@ module top(); c5=pll_clocks[5], )) - for site in sorted(gen_sites("BUFGCTRL"), key=get_xy): + for site in sorted(gen_sites("BUFGCTRL"), + key=util.create_xy_fun('BUFGCTRL_')): wire_name = 'clk_{}'.format(site) if not mmcm_pll_only: @@ -268,8 +274,7 @@ module top(); wire_name=wire_name, )) - bufhce_sites = list(gen_bufhce_sites()) - for tile_name, sites in bufhce_sites: + for tile_name, sites in gen_bufhce_sites(): for site in sites: wire_name = clock_sources.get_random_source(site_to_cmt[site]) if wire_name is None: diff --git a/prjxray/util.py b/prjxray/util.py index 0b4cf689..8b4d80ea 100644 --- a/prjxray/util.py +++ b/prjxray/util.py @@ -22,6 +22,41 @@ def roi_xy(): return (x1, x2), (y1, y2) +def create_xy_fun(prefix): + """ Create function that extracts X and Y coordinate from a prefixed string + + >>> fun = create_xy_fun(prefix='') + >>> fun('X5Y23') + (5, 23) + >>> fun('X0Y0') + (0, 0) + >>> fun('X50Y100') + (50, 100) + + >>> fun = create_xy_fun(prefix='SITE_') + >>> fun('SITE_X5Y23') + (5, 23) + >>> fun('SITE_X0Y0') + (0, 0) + >>> fun('SITE_X50Y100') + (50, 100) + + """ + compiled_re = re.compile( + '^{prefix}X([0-9]+)Y([0-9]+)$'.format(prefix=prefix)) + + def get_xy(s): + m = compiled_re.match(s) + assert m, (prefix, s) + + x = int(m.group(1)) + y = int(m.group(2)) + + return x, y + + return get_xy + + def slice_xy(): '''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)''' # SLICE_X12Y100:SLICE_X27Y149 From f5bff021222514f00ac9a772ce730ffb737e7a5d Mon Sep 17 00:00:00 2001 From: Keith Rothman <537074+litghost@users.noreply.github.com> Date: Tue, 12 Feb 2019 15:12:45 -0800 Subject: [PATCH 13/13] Fix pip-bi makefile. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com> --- fuzzers/057-pip-bi/Makefile | 2 +- fuzzers/057-pip-bi/generate.tcl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/fuzzers/057-pip-bi/Makefile b/fuzzers/057-pip-bi/Makefile index 0052906d..33aebca5 100644 --- a/fuzzers/057-pip-bi/Makefile +++ b/fuzzers/057-pip-bi/Makefile @@ -1,4 +1,4 @@ -MAKETODO_FLAGS=--re ".*" +MAKETODO_FLAGS=--pip-type bipips_int --re ".*" export FUZDIR=$(shell pwd) PIPLIST_TCL=$(FUZDIR)/bipiplist.tcl PIP_TYPE?=bipips_int diff --git a/fuzzers/057-pip-bi/generate.tcl b/fuzzers/057-pip-bi/generate.tcl index fb295ebf..1743bd0f 100644 --- a/fuzzers/057-pip-bi/generate.tcl +++ b/fuzzers/057-pip-bi/generate.tcl @@ -84,8 +84,7 @@ for {set idx 0} {$idx < [llength $todo_lines]} {incr idx} { # sometimes it gets stuck in specific src -> dst locations if {$tries >= 3} { - puts "WARNING: failed to route net after $tries tries" - error + error "WARNING: failed to route net after $tries tries" } }