From bbc908d6d8654a76e2b69d85048ecf1baf3d9604 Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Sat, 13 Jul 2019 11:43:31 +0200 Subject: [PATCH 1/9] Initial IODELAY fuzzer Signed-off-by: Maciej Kurc --- fuzzers/035a-iob-idelay/Makefile | 20 +++ fuzzers/035a-iob-idelay/bits.dbf | 0 fuzzers/035a-iob-idelay/generate.py | 56 +++++++ fuzzers/035a-iob-idelay/generate.tcl | 23 +++ fuzzers/035a-iob-idelay/top.py | 216 +++++++++++++++++++++++++++ 5 files changed, 315 insertions(+) create mode 100644 fuzzers/035a-iob-idelay/Makefile create mode 100644 fuzzers/035a-iob-idelay/bits.dbf create mode 100644 fuzzers/035a-iob-idelay/generate.py create mode 100644 fuzzers/035a-iob-idelay/generate.tcl create mode 100644 fuzzers/035a-iob-idelay/top.py diff --git a/fuzzers/035a-iob-idelay/Makefile b/fuzzers/035a-iob-idelay/Makefile new file mode 100644 index 00000000..3066c3a1 --- /dev/null +++ b/fuzzers/035a-iob-idelay/Makefile @@ -0,0 +1,20 @@ +N := 5 +include ../fuzzer.mk + +database: build/segbits_xiob33.db + +build/segbits_xiob33.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -m 2 -M 2 -o build/segbits_xiob33.rdb $$(find -name segdata_*.txt) + +build/segbits_xiob33.db: build/segbits_xiob33.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@ + ${XRAY_MASKMERGE} build/mask_xiob33.db $$(find -name segdata_*.txt) + +pushdb: + ${XRAY_MERGEDB} liob33 build/segbits_xiob33.db + ${XRAY_MERGEDB} riob33 build/segbits_xiob33.db + ${XRAY_MERGEDB} mask_liob33 build/mask_xiob33.db + ${XRAY_MERGEDB} mask_riob33 build/mask_xiob33.db + +.PHONY: todo database pushdb + diff --git a/fuzzers/035a-iob-idelay/bits.dbf b/fuzzers/035a-iob-idelay/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/035a-iob-idelay/generate.py b/fuzzers/035a-iob-idelay/generate.py new file mode 100644 index 00000000..4e95e611 --- /dev/null +++ b/fuzzers/035a-iob-idelay/generate.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +import json + +from prjxray.segmaker import Segmaker +from prjxray import util +from prjxray import verilog + +segmk = Segmaker("design.bits", verbose=True) + +# Load tags +with open("params.json", "r") as fp: + data = json.load(fp) + +idelay_types = ["FIXED", "VARIABLE", "VAR_LOAD"] +delay_srcs = ["IDATAIN", "DATAIN"] +signal_patterns = ["DATA", "CLOCK"] + +# Output tags +for params in data: + loc = verilog.unquote(params["LOC"]) + + # Delay type + value = verilog.unquote(params["IDELAY_TYPE"]) + value = value.replace("_PIPE", "") # VAR_LOAD and VAR_LOAD_PIPE are the same + for x in idelay_types: + segmk.add_site_tag(loc, "IDELAY_TYPE_%s" % x, int(value == x)) + + # Delay value + value = int(params["IDELAY_VALUE"]) + for i in range(5): + segmk.add_site_tag(loc, "IDELAY_VALUE[%01d]" % i, ((value >> i) & 1) != 0) + + # Delay source + value = verilog.unquote(params["DELAY_SRC"]) + for x in delay_srcs: + segmk.add_site_tag(loc, "DELAY_SRC_%s" % x, int(value == x)) + +# # Signal pattern +# value = verilog.unquote(params["SIGNAL_PATTERN"]) +# for x in signal_patterns: +# segmk.add_site_tag(loc, "SIGNAL_PATTERN_%s" % x, int(value == x)) + + value = verilog.unquote(params["HIGH_PERFORMANCE_MODE"]) + segmk.add_site_tag(loc, "HIGH_PERFORMANCE_MODE", int(value == "TRUE")) + + value = verilog.unquote(params["CINVCTRL_SEL"]) + segmk.add_site_tag(loc, "CINVCTRL_SEL", int(value == "TRUE")) + + value = verilog.unquote(params["PIPE_SEL"]) + segmk.add_site_tag(loc, "PIPE_SEL", int(value == "TRUE")) + +def bitfilter(frame_idx, bit_idx): + return True + +segmk.compile(bitfilter=bitfilter) +segmk.write() diff --git a/fuzzers/035a-iob-idelay/generate.tcl b/fuzzers/035a-iob-idelay/generate.tcl new file mode 100644 index 00000000..e9a3d61b --- /dev/null +++ b/fuzzers/035a-iob-idelay/generate.tcl @@ -0,0 +1,23 @@ +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_param tcl.collectionResultDisplayLimit 0 + +set_property IS_ENABLED 0 [get_drc_checks {NSTD-1}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-79}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-81}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-84}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-85}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-87}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-85}] +set_property IS_ENABLED 0 [get_drc_checks {AVAL-28}] + +place_design +route_design + +write_checkpoint -force design.dcp +write_bitstream -force design.bit diff --git a/fuzzers/035a-iob-idelay/top.py b/fuzzers/035a-iob-idelay/top.py new file mode 100644 index 00000000..7a1ed040 --- /dev/null +++ b/fuzzers/035a-iob-idelay/top.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python3 + +import os, random +random.seed(int(os.getenv("SEED"), 16)) + +import re +import json + +from prjxray import util +from prjxray.db import Database + +# ============================================================================= + +#todo_file_name = "../todo.txt" + +#def make_todo(): + +# if os.path.isfile(file_name): +# return + +# with open(file_name, "w") as fp: +# fp.write("IDELAY_TYPE\n") +# fp.write("IDELAY_VALUE\n") +# fp.write("DELAY_SRC\n") +# fp.write("HIGH_PERFORMANCE_MODE\n") +# fp.write("SIGNAL_PATTERN\n") +# fp.write("CINVCTRL_SEL\n") +# fp.write("PIPE_SEL\n") + +def get_loc(name): + m = re.match("^\S+_X([0-9]+)Y([0-9]+)$", name) + assert m != None + + x = int(m.group(1)) + y = int(m.group(2)) + return (x, y,) + +def gen_sites(): + db = Database(util.get_db_root()) + grid = db.grid() + + tile_list = [] + for tile_name in sorted(grid.tiles()): + if "IOB33" not in tile_name or "SING" in tile_name: + continue + tile_list.append(tile_name) + + def key(name): + x, y = get_loc(name) + return y + x * 10000 + + tile_list.sort(key=key) + + for iob_tile_name in tile_list: + iob_gridinfo = grid.gridinfo_at_loc(grid.loc_of_tilename(iob_tile_name)) + + # Find IOI tile adjacent to IOB + for suffix in ["IOI3", "IOI3_TBYTESRC", "IOI3_TBYTETERM"]: + try: + ioi_tile_name = iob_tile_name.replace("IOB33", suffix) + ioi_gridinfo = grid.gridinfo_at_loc(grid.loc_of_tilename(ioi_tile_name)) + break + except KeyError: + pass + + #idelay = [k for k,v in ioi_gridinfo.sites.items() if v == "IDELAYE2"][0] + iob33s = [k for k,v in iob_gridinfo.sites.items() if v == "IOB33S"][0] + iob33m = [k for k,v in iob_gridinfo.sites.items() if v == "IOB33M"][0] + idelay_s = iob33s.replace("IOB", "IDELAY") + idelay_m = iob33m.replace("IOB", "IDELAY") + + yield iob33m, idelay_m, iob33s, idelay_s + + +def run(): + + # Get all [LR]IOI3 tiles + tiles = list(gen_sites()) + +# N = 1 +# tiles = tiles[:N] # HACK + +# for t in tiles: +# print(t) +# exit(-1) + + # Header + print("// Tile count: %d" % len(tiles)) + print("// Seed: '%s'" % os.getenv("SEED")) + print(''' +module top ( + input wire [{N}:0] di, + output wire [{N}:0] do +); + +wire [{N}:0] di_buf; +wire [{N}:0] do_buf; + '''.format(**{"N": len(tiles) - 1})) + + # LOCes IOBs + data = [] + for i, sites in enumerate(tiles): + + if random.randint(0, 1): + iob_i = sites[0] + iob_o = sites[2] + idelay = sites[1] + else: + iob_i = sites[2] + iob_o = sites[0] + idelay = sites[3] + + params = { + "LOC": "\"" + idelay + "\"", + "IDELAY_TYPE": "\"" + random.choice(["FIXED", "VARIABLE", "VAR_LOAD", "VAR_LOAD_PIPE"]) + "\"", + "IDELAY_VALUE": random.randint(0, 31), + "DELAY_SRC": "\"" + random.choice(["IDATAIN", "DATAIN"]) + "\"", + "HIGH_PERFORMANCE_MODE": "\"" + random.choice(["TRUE", "FALSE"]) + "\"", + "CINVCTRL_SEL": "\"" + random.choice(["TRUE", "FALSE"]) + "\"", + "PIPE_SEL": "\"" + random.choice(["TRUE", "FALSE"]) + "\"", + } + + if params["IDELAY_TYPE"] != "\"VAR_LOAD_PIPE\"": + params["PIPE_SEL"] = "\"FALSE\"" + + # The datasheet says that for these two modes the delay is set to 0 + if params["IDELAY_TYPE"] == "\"VAR_LOAD\"": + params["IDELAY_VALUE"] = 0 + if params["IDELAY_TYPE"] == "\"VAR_LOAD_PIPE\"": + params["IDELAY_VALUE"] = 0 + + # SIGNAL_PATTERN and HIGH_PERFORMANCE_MODE have no bits + + param_str = ",".join(".%s(%s)" % (k, v) for k, v in params.items()) + + print('') + print('(* LOC="%s", KEEP, DONT_TOUCH *)' % iob_i) + print('IBUF ibuf_%03d (.I(di[%3d]), .O(di_buf[%3d]));' % (i, i, i)) + print('(* LOC="%s", KEEP, DONT_TOUCH *)' % iob_o) + print('OBUF obuf_%03d (.I(do_buf[%3d]), .O(do[%3d]));' % (i, i, i)) + print('mod #(%s) mod_%03d (.I(di_buf[%3d]), .O(do_buf[%3d]));' % + (param_str, i, i, i)) + + data.append(params) + + # Store params + with open("params.json", "w") as fp: + json.dump(data, fp, sort_keys=True, indent=1) + + print(''' +// IDELAYCTRL +(* KEEP, DONT_TOUCH *) +IDELAYCTRL idelayctrl(); + +endmodule + + +module mod( + input wire I, + output wire O +); + +parameter LOC = ""; +parameter IDELAY_TYPE = "FIXED"; +parameter IDELAY_VALUE = 0; +parameter DELAY_SRC = "IDATAIN"; +parameter HIGH_PERFORMANCE_MODE = "TRUE"; +parameter SIGNAL_PATTERN = "DATA"; +parameter CINVCTRL_SEL = "FALSE"; +parameter PIPE_SEL = "FALSE"; + +wire x; + +// IDELAY +(* LOC=LOC, KEEP, DONT_TOUCH *) +IDELAYE2 #( + .IDELAY_TYPE(IDELAY_TYPE), + .IDELAY_VALUE(IDELAY_VALUE), + .DELAY_SRC(DELAY_SRC), + .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE), + .SIGNAL_PATTERN(SIGNAL_PATTERN), + .CINVCTRL_SEL(CINVCTRL_SEL), + .PIPE_SEL(PIPE_SEL) +) +idelay +( + .C(), + .REGRST(), + .LD(), + .CE(), + .INC(), + .CINVCTRL(), + .CNTVALUEIN(), + .IDATAIN(I), + .DATAIN(), + .LDPIPEEN(), + .DATAOUT(x), + .CNTVALUEOUT() +); + +// A LUT +(* KEEP, DONT_TOUCH *) +LUT6 #(.INIT(32'hDEADBEEF)) lut ( + .I0(x), + .I1(x), + .I2(x), + .I3(x), + .I4(x), + .I5(x), + .O(O) +); + +endmodule + ''') + +run() From bd6c3c7f9d3de2add4909c35ac70da0ef6018074 Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Sun, 14 Jul 2019 09:39:59 +0200 Subject: [PATCH 2/9] Added support for Y0/Y1 site locations in IOB and IOI tiles to the segmaker.py Signed-off-by: Maciej Kurc --- prjxray/segmaker.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/prjxray/segmaker.py b/prjxray/segmaker.py index 8ce64dca..375714db 100644 --- a/prjxray/segmaker.py +++ b/prjxray/segmaker.py @@ -311,6 +311,9 @@ class Segmaker: 'SLICE': name_slice, 'RAMB18': name_bram18, 'IOB': name_y0y1, + 'IDELAY': name_y0y1, + 'ILOGIC': name_y0y1, + 'OLOGIC': name_y0y1, }.get(site_prefix, name_default)() self.verbose and print( 'site %s w/ %s prefix => tag %s' % @@ -337,6 +340,7 @@ class Segmaker: -CENTER_INTER_R => CENTER_INTER -CLK_HROW_TOP_R => CLK_HROW -LIOB33 => IOB33 + -LIOI3 => IOI3 ''' tile_type_norm = re.sub("(_TOP|_BOT|LL|LM)?_[LR]$", "", tile_type) tile_type_norm = re.sub( @@ -345,6 +349,13 @@ class Segmaker: if tile_type_norm in ['LIOB33', 'RIOB33']: tile_type_norm = 'IOB33' + if tile_type_norm in ['LIOI3', 'RIOI3']: + tile_type_norm = 'IOI3' + if tile_type_norm in ['LIOI3_TBYTESRC', 'RIOI3_TBYTESRC']: + tile_type_norm = 'IOI3' + if tile_type_norm in ['LIOI3_TBYTETERM', 'RIOI3_TBYTETERM']: + tile_type_norm = 'IOI3' + # ignore dummy tiles (ex: VBRK) if len(tiledata['bits']) == 0: if self.verbose: From 3c30f9f34abf2ef3141cc31b96dd0c28e8e32fd8 Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Mon, 15 Jul 2019 12:36:39 +0200 Subject: [PATCH 3/9] Fixes to the fuzzer Signed-off-by: Maciej Kurc --- fuzzers/035a-iob-idelay/bits.dbf | 0 fuzzers/035a-iob-idelay/generate.py | 5 ----- fuzzers/035a-iob-idelay/top.py | 25 +------------------------ 3 files changed, 1 insertion(+), 29 deletions(-) delete mode 100644 fuzzers/035a-iob-idelay/bits.dbf diff --git a/fuzzers/035a-iob-idelay/bits.dbf b/fuzzers/035a-iob-idelay/bits.dbf deleted file mode 100644 index e69de29b..00000000 diff --git a/fuzzers/035a-iob-idelay/generate.py b/fuzzers/035a-iob-idelay/generate.py index 4e95e611..d0ce1d8c 100644 --- a/fuzzers/035a-iob-idelay/generate.py +++ b/fuzzers/035a-iob-idelay/generate.py @@ -35,11 +35,6 @@ for params in data: for x in delay_srcs: segmk.add_site_tag(loc, "DELAY_SRC_%s" % x, int(value == x)) -# # Signal pattern -# value = verilog.unquote(params["SIGNAL_PATTERN"]) -# for x in signal_patterns: -# segmk.add_site_tag(loc, "SIGNAL_PATTERN_%s" % x, int(value == x)) - value = verilog.unquote(params["HIGH_PERFORMANCE_MODE"]) segmk.add_site_tag(loc, "HIGH_PERFORMANCE_MODE", int(value == "TRUE")) diff --git a/fuzzers/035a-iob-idelay/top.py b/fuzzers/035a-iob-idelay/top.py index 7a1ed040..a0f2c812 100644 --- a/fuzzers/035a-iob-idelay/top.py +++ b/fuzzers/035a-iob-idelay/top.py @@ -11,22 +11,6 @@ from prjxray.db import Database # ============================================================================= -#todo_file_name = "../todo.txt" - -#def make_todo(): - -# if os.path.isfile(file_name): -# return - -# with open(file_name, "w") as fp: -# fp.write("IDELAY_TYPE\n") -# fp.write("IDELAY_VALUE\n") -# fp.write("DELAY_SRC\n") -# fp.write("HIGH_PERFORMANCE_MODE\n") -# fp.write("SIGNAL_PATTERN\n") -# fp.write("CINVCTRL_SEL\n") -# fp.write("PIPE_SEL\n") - def get_loc(name): m = re.match("^\S+_X([0-9]+)Y([0-9]+)$", name) assert m != None @@ -76,13 +60,6 @@ def run(): # Get all [LR]IOI3 tiles tiles = list(gen_sites()) - -# N = 1 -# tiles = tiles[:N] # HACK - -# for t in tiles: -# print(t) -# exit(-1) # Header print("// Tile count: %d" % len(tiles)) @@ -154,7 +131,7 @@ IDELAYCTRL idelayctrl(); endmodule - +(* KEEP, DONT_TOUCH *) module mod( input wire I, output wire O From c9ce06f688845ce6612591672703434ad53e7eae Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Mon, 15 Jul 2019 12:37:10 +0200 Subject: [PATCH 4/9] Fixed mergedb.sh to support IOI3 tiles Signed-off-by: Maciej Kurc --- utils/mergedb.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/utils/mergedb.sh b/utils/mergedb.sh index f47548c3..570f8f16 100755 --- a/utils/mergedb.sh +++ b/utils/mergedb.sh @@ -114,6 +114,12 @@ case "$1" in riob33) sed < "$2" > "$tmp1" -e 's/^IOB33\./RIOB33./' ;; + lioi3) + sed < "$2" > "$tmp1" -e 's/^IOI3\./LIOI3./' ;; + + rioi3) + sed < "$2" > "$tmp1" -e 's/^IOI3\./RIOI3./' ;; + cmt_top_r_upper_t) sed < "$2" > "$tmp1" -e 's/^CMT_UPPER_T\./CMT_TOP_R_UPPER_T./' ;; From c880707d27a5eeecd85805e759d635e45dd4fa0a Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Tue, 16 Jul 2019 10:27:40 +0200 Subject: [PATCH 5/9] Final fixes to the fuzzer. Signed-off-by: Maciej Kurc --- fuzzers/035a-iob-idelay/Makefile | 4 +-- fuzzers/035a-iob-idelay/bits.dbf | 0 fuzzers/035a-iob-idelay/generate.py | 27 ++++++++------- fuzzers/035a-iob-idelay/top.py | 51 ++++++++++++++++++++--------- fuzzers/Makefile | 1 + 5 files changed, 53 insertions(+), 30 deletions(-) create mode 100644 fuzzers/035a-iob-idelay/bits.dbf diff --git a/fuzzers/035a-iob-idelay/Makefile b/fuzzers/035a-iob-idelay/Makefile index 3066c3a1..60040127 100644 --- a/fuzzers/035a-iob-idelay/Makefile +++ b/fuzzers/035a-iob-idelay/Makefile @@ -4,7 +4,7 @@ include ../fuzzer.mk database: build/segbits_xiob33.db build/segbits_xiob33.rdb: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} -m 2 -M 2 -o build/segbits_xiob33.rdb $$(find -name segdata_*.txt) + ${XRAY_SEGMATCH} -m 1 -M 1 -o build/segbits_xiob33.rdb $$(find -name segdata_*.txt) build/segbits_xiob33.db: build/segbits_xiob33.rdb ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@ @@ -16,5 +16,5 @@ pushdb: ${XRAY_MERGEDB} mask_liob33 build/mask_xiob33.db ${XRAY_MERGEDB} mask_riob33 build/mask_xiob33.db -.PHONY: todo database pushdb +.PHONY: database pushdb diff --git a/fuzzers/035a-iob-idelay/bits.dbf b/fuzzers/035a-iob-idelay/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/035a-iob-idelay/generate.py b/fuzzers/035a-iob-idelay/generate.py index d0ce1d8c..e83cd373 100644 --- a/fuzzers/035a-iob-idelay/generate.py +++ b/fuzzers/035a-iob-idelay/generate.py @@ -11,9 +11,8 @@ segmk = Segmaker("design.bits", verbose=True) with open("params.json", "r") as fp: data = json.load(fp) -idelay_types = ["FIXED", "VARIABLE", "VAR_LOAD"] +idelay_types = ["FIXED", "VARIABLE", "VAR_LOAD"] delay_srcs = ["IDATAIN", "DATAIN"] -signal_patterns = ["DATA", "CLOCK"] # Output tags for params in data: @@ -21,31 +20,35 @@ for params in data: # Delay type value = verilog.unquote(params["IDELAY_TYPE"]) - value = value.replace("_PIPE", "") # VAR_LOAD and VAR_LOAD_PIPE are the same + value = value.replace( + "_PIPE", "") # VAR_LOAD and VAR_LOAD_PIPE are the same for x in idelay_types: - segmk.add_site_tag(loc, "IDELAY_TYPE_%s" % x, int(value == x)) - + segmk.add_site_tag(loc, "IDELAY_TYPE_%s" % x, int(value == x)) + # Delay value value = int(params["IDELAY_VALUE"]) for i in range(5): - segmk.add_site_tag(loc, "IDELAY_VALUE[%01d]" % i, ((value >> i) & 1) != 0) + segmk.add_site_tag( + loc, "IDELAY_VALUE[%01d]" % i, ((value >> i) & 1) != 0) # Delay source value = verilog.unquote(params["DELAY_SRC"]) for x in delay_srcs: - segmk.add_site_tag(loc, "DELAY_SRC_%s" % x, int(value == x)) + segmk.add_site_tag(loc, "DELAY_SRC_%s" % x, int(value == x)) value = verilog.unquote(params["HIGH_PERFORMANCE_MODE"]) - segmk.add_site_tag(loc, "HIGH_PERFORMANCE_MODE", int(value == "TRUE")) + segmk.add_site_tag(loc, "HIGH_PERFORMANCE_MODE", int(value == "TRUE")) value = verilog.unquote(params["CINVCTRL_SEL"]) - segmk.add_site_tag(loc, "CINVCTRL_SEL", int(value == "TRUE")) - + segmk.add_site_tag(loc, "CINVCTRL_SEL", int(value == "TRUE")) + value = verilog.unquote(params["PIPE_SEL"]) - segmk.add_site_tag(loc, "PIPE_SEL", int(value == "TRUE")) + segmk.add_site_tag(loc, "PIPE_SEL", int(value == "TRUE")) + def bitfilter(frame_idx, bit_idx): - return True + return True + segmk.compile(bitfilter=bitfilter) segmk.write() diff --git a/fuzzers/035a-iob-idelay/top.py b/fuzzers/035a-iob-idelay/top.py index a0f2c812..119279f7 100644 --- a/fuzzers/035a-iob-idelay/top.py +++ b/fuzzers/035a-iob-idelay/top.py @@ -11,13 +11,18 @@ from prjxray.db import Database # ============================================================================= + def get_loc(name): m = re.match("^\S+_X([0-9]+)Y([0-9]+)$", name) assert m != None x = int(m.group(1)) y = int(m.group(2)) - return (x, y,) + return ( + x, + y, + ) + def gen_sites(): db = Database(util.get_db_root()) @@ -36,20 +41,22 @@ def gen_sites(): tile_list.sort(key=key) for iob_tile_name in tile_list: - iob_gridinfo = grid.gridinfo_at_loc(grid.loc_of_tilename(iob_tile_name)) + iob_gridinfo = grid.gridinfo_at_loc( + grid.loc_of_tilename(iob_tile_name)) # Find IOI tile adjacent to IOB for suffix in ["IOI3", "IOI3_TBYTESRC", "IOI3_TBYTETERM"]: try: ioi_tile_name = iob_tile_name.replace("IOB33", suffix) - ioi_gridinfo = grid.gridinfo_at_loc(grid.loc_of_tilename(ioi_tile_name)) + ioi_gridinfo = grid.gridinfo_at_loc( + grid.loc_of_tilename(ioi_tile_name)) break except KeyError: pass #idelay = [k for k,v in ioi_gridinfo.sites.items() if v == "IDELAYE2"][0] - iob33s = [k for k,v in iob_gridinfo.sites.items() if v == "IOB33S"][0] - iob33m = [k for k,v in iob_gridinfo.sites.items() if v == "IOB33M"][0] + iob33s = [k for k, v in iob_gridinfo.sites.items() if v == "IOB33S"][0] + iob33m = [k for k, v in iob_gridinfo.sites.items() if v == "IOB33M"][0] idelay_s = iob33s.replace("IOB", "IDELAY") idelay_m = iob33m.replace("IOB", "IDELAY") @@ -57,14 +64,15 @@ def gen_sites(): def run(): - + # Get all [LR]IOI3 tiles tiles = list(gen_sites()) # Header print("// Tile count: %d" % len(tiles)) print("// Seed: '%s'" % os.getenv("SEED")) - print(''' + print( + ''' module top ( input wire [{N}:0] di, output wire [{N}:0] do @@ -88,13 +96,21 @@ wire [{N}:0] do_buf; idelay = sites[3] params = { - "LOC": "\"" + idelay + "\"", - "IDELAY_TYPE": "\"" + random.choice(["FIXED", "VARIABLE", "VAR_LOAD", "VAR_LOAD_PIPE"]) + "\"", - "IDELAY_VALUE": random.randint(0, 31), - "DELAY_SRC": "\"" + random.choice(["IDATAIN", "DATAIN"]) + "\"", - "HIGH_PERFORMANCE_MODE": "\"" + random.choice(["TRUE", "FALSE"]) + "\"", - "CINVCTRL_SEL": "\"" + random.choice(["TRUE", "FALSE"]) + "\"", - "PIPE_SEL": "\"" + random.choice(["TRUE", "FALSE"]) + "\"", + "LOC": + "\"" + idelay + "\"", + "IDELAY_TYPE": + "\"" + random.choice( + ["FIXED", "VARIABLE", "VAR_LOAD", "VAR_LOAD_PIPE"]) + "\"", + "IDELAY_VALUE": + random.randint(0, 31), + "DELAY_SRC": + "\"" + random.choice(["IDATAIN", "DATAIN"]) + "\"", + "HIGH_PERFORMANCE_MODE": + "\"" + random.choice(["TRUE", "FALSE"]) + "\"", + "CINVCTRL_SEL": + "\"" + random.choice(["TRUE", "FALSE"]) + "\"", + "PIPE_SEL": + "\"" + random.choice(["TRUE", "FALSE"]) + "\"", } if params["IDELAY_TYPE"] != "\"VAR_LOAD_PIPE\"": @@ -115,7 +131,8 @@ wire [{N}:0] do_buf; print('IBUF ibuf_%03d (.I(di[%3d]), .O(di_buf[%3d]));' % (i, i, i)) print('(* LOC="%s", KEEP, DONT_TOUCH *)' % iob_o) print('OBUF obuf_%03d (.I(do_buf[%3d]), .O(do[%3d]));' % (i, i, i)) - print('mod #(%s) mod_%03d (.I(di_buf[%3d]), .O(do_buf[%3d]));' % + print( + 'mod #(%s) mod_%03d (.I(di_buf[%3d]), .O(do_buf[%3d]));' % (param_str, i, i, i)) data.append(params) @@ -124,7 +141,8 @@ wire [{N}:0] do_buf; with open("params.json", "w") as fp: json.dump(data, fp, sort_keys=True, indent=1) - print(''' + print( + ''' // IDELAYCTRL (* KEEP, DONT_TOUCH *) IDELAYCTRL idelayctrl(); @@ -190,4 +208,5 @@ LUT6 #(.INIT(32'hDEADBEEF)) lut ( endmodule ''') + run() diff --git a/fuzzers/Makefile b/fuzzers/Makefile index b0662990..0c425cf8 100644 --- a/fuzzers/Makefile +++ b/fuzzers/Makefile @@ -86,6 +86,7 @@ $(eval $(call fuzzer,030-iob,005-tilegrid)) $(eval $(call fuzzer,032-cmt-pll,005-tilegrid)) $(eval $(call fuzzer,034-cmt-pll-pips,005-tilegrid)) $(eval $(call fuzzer,035-iob-ilogic,005-tilegrid)) +$(eval $(call fuzzer,035a-iob-idelay,005-tilegrid)) $(eval $(call fuzzer,036-iob-ologic,005-tilegrid)) $(eval $(call fuzzer,038-cfg,005-tilegrid)) $(eval $(call fuzzer,040-clk-hrow-config,005-tilegrid)) From c935d44fdcfb49718310be56277506717a8a549c Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Tue, 16 Jul 2019 14:18:18 +0200 Subject: [PATCH 6/9] Added fuzzing of local inverters Signed-off-by: Maciej Kurc --- fuzzers/035a-iob-idelay/generate.py | 8 ++++++++ fuzzers/035a-iob-idelay/generate.tcl | 1 + fuzzers/035a-iob-idelay/top.py | 29 ++++++++++++++++++++++------ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/fuzzers/035a-iob-idelay/generate.py b/fuzzers/035a-iob-idelay/generate.py index e83cd373..f93950ff 100644 --- a/fuzzers/035a-iob-idelay/generate.py +++ b/fuzzers/035a-iob-idelay/generate.py @@ -45,6 +45,14 @@ for params in data: value = verilog.unquote(params["PIPE_SEL"]) segmk.add_site_tag(loc, "PIPE_SEL", int(value == "TRUE")) + if "IS_C_INVERTED" in params: + segmk.add_site_tag(loc, "IS_C_INVERTED", int(params["IS_C_INVERTED"])) + + segmk.add_site_tag( + loc, "IS_DATAIN_INVERTED", int(params["IS_DATAIN_INVERTED"])) + segmk.add_site_tag( + loc, "IS_IDATAIN_INVERTED", int(params["IS_IDATAIN_INVERTED"])) + def bitfilter(frame_idx, bit_idx): return True diff --git a/fuzzers/035a-iob-idelay/generate.tcl b/fuzzers/035a-iob-idelay/generate.tcl index e9a3d61b..15aa2de7 100644 --- a/fuzzers/035a-iob-idelay/generate.tcl +++ b/fuzzers/035a-iob-idelay/generate.tcl @@ -8,6 +8,7 @@ set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] set_param tcl.collectionResultDisplayLimit 0 set_property IS_ENABLED 0 [get_drc_checks {NSTD-1}] +set_property IS_ENABLED 0 [get_drc_checks {UCIO-1}] set_property IS_ENABLED 0 [get_drc_checks {REQP-79}] set_property IS_ENABLED 0 [get_drc_checks {REQP-81}] set_property IS_ENABLED 0 [get_drc_checks {REQP-84}] diff --git a/fuzzers/035a-iob-idelay/top.py b/fuzzers/035a-iob-idelay/top.py index 119279f7..3fe2e4a3 100644 --- a/fuzzers/035a-iob-idelay/top.py +++ b/fuzzers/035a-iob-idelay/top.py @@ -54,7 +54,6 @@ def gen_sites(): except KeyError: pass - #idelay = [k for k,v in ioi_gridinfo.sites.items() if v == "IDELAYE2"][0] iob33s = [k for k, v in iob_gridinfo.sites.items() if v == "IOB33S"][0] iob33m = [k for k, v in iob_gridinfo.sites.items() if v == "IOB33M"][0] idelay_s = iob33s.replace("IOB", "IDELAY") @@ -74,10 +73,14 @@ def run(): print( ''' module top ( + (* CLOCK_BUFFER_TYPE = "NONE" *) + input wire clk, input wire [{N}:0] di, output wire [{N}:0] do ); +wire clk_buf = clk; + wire [{N}:0] di_buf; wire [{N}:0] do_buf; '''.format(**{"N": len(tiles) - 1})) @@ -111,6 +114,12 @@ wire [{N}:0] do_buf; "\"" + random.choice(["TRUE", "FALSE"]) + "\"", "PIPE_SEL": "\"" + random.choice(["TRUE", "FALSE"]) + "\"", + "IS_C_INVERTED": + random.randint(0, 1), + "IS_DATAIN_INVERTED": + random.randint(0, 1), + "IS_IDATAIN_INVERTED": + random.randint(0, 1), } if params["IDELAY_TYPE"] != "\"VAR_LOAD_PIPE\"": @@ -122,7 +131,8 @@ wire [{N}:0] do_buf; if params["IDELAY_TYPE"] == "\"VAR_LOAD_PIPE\"": params["IDELAY_VALUE"] = 0 - # SIGNAL_PATTERN and HIGH_PERFORMANCE_MODE have no bits + if params["IDELAY_TYPE"] == "\"FIXED\"": + params["IS_C_INVERTED"] = 0 param_str = ",".join(".%s(%s)" % (k, v) for k, v in params.items()) @@ -132,8 +142,8 @@ wire [{N}:0] do_buf; print('(* LOC="%s", KEEP, DONT_TOUCH *)' % iob_o) print('OBUF obuf_%03d (.I(do_buf[%3d]), .O(do[%3d]));' % (i, i, i)) print( - 'mod #(%s) mod_%03d (.I(di_buf[%3d]), .O(do_buf[%3d]));' % - (param_str, i, i, i)) + 'mod #(%s) mod_%03d (.clk(clk_buf), .I(di_buf[%3d]), .O(do_buf[%3d]));' + % (param_str, i, i, i)) data.append(params) @@ -151,6 +161,7 @@ endmodule (* KEEP, DONT_TOUCH *) module mod( + input wire clk, input wire I, output wire O ); @@ -163,6 +174,9 @@ parameter HIGH_PERFORMANCE_MODE = "TRUE"; parameter SIGNAL_PATTERN = "DATA"; parameter CINVCTRL_SEL = "FALSE"; parameter PIPE_SEL = "FALSE"; +parameter IS_C_INVERTED = 0; +parameter IS_DATAIN_INVERTED = 0; +parameter IS_IDATAIN_INVERTED = 0; wire x; @@ -175,11 +189,14 @@ IDELAYE2 #( .HIGH_PERFORMANCE_MODE(HIGH_PERFORMANCE_MODE), .SIGNAL_PATTERN(SIGNAL_PATTERN), .CINVCTRL_SEL(CINVCTRL_SEL), - .PIPE_SEL(PIPE_SEL) + .PIPE_SEL(PIPE_SEL), + .IS_C_INVERTED(IS_C_INVERTED), + .IS_DATAIN_INVERTED(IS_DATAIN_INVERTED), + .IS_IDATAIN_INVERTED(IS_IDATAIN_INVERTED) ) idelay ( - .C(), + .C(clk), .REGRST(), .LD(), .CE(), From 813f3a8570c17ffa0e391c4f07ae444533f1e000 Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Wed, 17 Jul 2019 14:40:19 +0200 Subject: [PATCH 7/9] Fixed a bug in Makefile Signed-off-by: Maciej Kurc --- fuzzers/035a-iob-idelay/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fuzzers/035a-iob-idelay/Makefile b/fuzzers/035a-iob-idelay/Makefile index 60040127..09fd9a31 100644 --- a/fuzzers/035a-iob-idelay/Makefile +++ b/fuzzers/035a-iob-idelay/Makefile @@ -11,10 +11,10 @@ build/segbits_xiob33.db: build/segbits_xiob33.rdb ${XRAY_MASKMERGE} build/mask_xiob33.db $$(find -name segdata_*.txt) pushdb: - ${XRAY_MERGEDB} liob33 build/segbits_xiob33.db - ${XRAY_MERGEDB} riob33 build/segbits_xiob33.db - ${XRAY_MERGEDB} mask_liob33 build/mask_xiob33.db - ${XRAY_MERGEDB} mask_riob33 build/mask_xiob33.db + ${XRAY_MERGEDB} lioi3 build/segbits_xiob33.db + ${XRAY_MERGEDB} rioi3 build/segbits_xiob33.db + ${XRAY_MERGEDB} mask_lioi3 build/mask_xiob33.db + ${XRAY_MERGEDB} mask_rioi3 build/mask_xiob33.db .PHONY: database pushdb From 4bf494b76e21bdf421f30760c349d5b2b979f185 Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Fri, 19 Jul 2019 09:19:56 +0200 Subject: [PATCH 8/9] Fixed top.py Signed-off-by: Maciej Kurc --- fuzzers/035a-iob-idelay/top.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fuzzers/035a-iob-idelay/top.py b/fuzzers/035a-iob-idelay/top.py index 3fe2e4a3..1d5f5a8a 100644 --- a/fuzzers/035a-iob-idelay/top.py +++ b/fuzzers/035a-iob-idelay/top.py @@ -34,11 +34,7 @@ def gen_sites(): continue tile_list.append(tile_name) - def key(name): - x, y = get_loc(name) - return y + x * 10000 - - tile_list.sort(key=key) + tile_list.sort(key=get_loc) for iob_tile_name in tile_list: iob_gridinfo = grid.gridinfo_at_loc( From b659a168dab078371389962f7c03bdaeb69811fb Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Sun, 21 Jul 2019 20:30:09 +0200 Subject: [PATCH 9/9] Changed function for getting XY location of a site. Signed-off-by: Maciej Kurc --- fuzzers/035a-iob-idelay/top.py | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/fuzzers/035a-iob-idelay/top.py b/fuzzers/035a-iob-idelay/top.py index 1d5f5a8a..2ba01d59 100644 --- a/fuzzers/035a-iob-idelay/top.py +++ b/fuzzers/035a-iob-idelay/top.py @@ -12,18 +12,6 @@ from prjxray.db import Database # ============================================================================= -def get_loc(name): - m = re.match("^\S+_X([0-9]+)Y([0-9]+)$", name) - assert m != None - - x = int(m.group(1)) - y = int(m.group(2)) - return ( - x, - y, - ) - - def gen_sites(): db = Database(util.get_db_root()) grid = db.grid() @@ -34,7 +22,8 @@ def gen_sites(): continue tile_list.append(tile_name) - tile_list.sort(key=get_loc) + get_xy = util.create_xy_fun('[LR]IOB33_') + tile_list.sort(key=get_xy) for iob_tile_name in tile_list: iob_gridinfo = grid.gridinfo_at_loc(