From bbc908d6d8654a76e2b69d85048ecf1baf3d9604 Mon Sep 17 00:00:00 2001 From: Maciej Kurc Date: Sat, 13 Jul 2019 11:43:31 +0200 Subject: [PATCH] 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()