diff --git a/fuzzers/035-iob-ilogic/Makefile b/fuzzers/035-iob-ilogic/Makefile index e0e708a0..39842133 100644 --- a/fuzzers/035-iob-ilogic/Makefile +++ b/fuzzers/035-iob-ilogic/Makefile @@ -10,11 +10,16 @@ include ../fuzzer.mk database: build/segbits_xioi3.db -build/segbits_xioi3.rdb: $(SPECIMENS_OK) - ${XRAY_SEGMATCH} -c 6 -o build/segbits_xioi3.rdb $$(find -name segdata_*) +build/segbits_xioi3.rdb2: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -c 6 -o build/segbits_xioi3.rdb2 $$(find -name segdata_*) + +build/segbits_xioi3.rdb: build/segbits_xioi3.rdb2 + # Filter out ISERDES features. Also filter DYN_CLK_INV_EN as they should + # belong to ISEDRES and are solved by fuzzer 035b. + grep -v ".ISERDES." $^ | grep -v "DYN_" >$@ build/segbits_xioi3.db: build/segbits_xioi3.rdb - ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@ + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --groups tag_groups.txt --seg-fn-in $^ --seg-fn-out $@ ${XRAY_MASKMERGE} build/mask_xioi3.db $$(find -name segdata_*) pushdb: diff --git a/fuzzers/035-iob-ilogic/bits.dbf b/fuzzers/035-iob-ilogic/bits.dbf index 37275398..e69de29b 100644 --- a/fuzzers/035-iob-ilogic/bits.dbf +++ b/fuzzers/035-iob-ilogic/bits.dbf @@ -1,2 +0,0 @@ -27_110 27_112 26_109 ,IOB33.IOB_Y0.ISERDES.DATA_WIDTH.W2 -26_15 26_17 27_18 ,IOB33.IOB_Y1.ISERDES.DATA_WIDTH.W2 diff --git a/fuzzers/035-iob-ilogic/tag_groups.txt b/fuzzers/035-iob-ilogic/tag_groups.txt new file mode 100644 index 00000000..d4525fbd --- /dev/null +++ b/fuzzers/035-iob-ilogic/tag_groups.txt @@ -0,0 +1,13 @@ +IOI3.ILOGIC_Y0.IDELMUXE3.P0 IOI3.ILOGIC_Y0.IDELMUXE3.P1 + +IOI3.ILOGIC_Y0.IFF.SRTYPE.ASYNC IOI3.ILOGIC_Y0.IFF.SRTYPE.SYNC + +IOI3.ILOGIC_Y0.IFF.DDR_CLK_EDGE.OPPOSITE_EDGE IOI3.ILOGIC_Y0.IFF.DDR_CLK_EDGE.SAME_EDGE + +IOI3.ILOGIC_Y1.IDELMUXE3.P0 IOI3.ILOGIC_Y1.IDELMUXE3.P1 + +IOI3.ILOGIC_Y1.IFF.SRTYPE.ASYNC IOI3.ILOGIC_Y1.IFF.SRTYPE.SYNC + +IOI3.ILOGIC_Y1.IFF.DDR_CLK_EDGE.OPPOSITE_EDGE IOI3.ILOGIC_Y1.IFF.DDR_CLK_EDGE.SAME_EDGE + + diff --git a/fuzzers/035b-iob-iserdes/Makefile b/fuzzers/035b-iob-iserdes/Makefile new file mode 100644 index 00000000..443b22be --- /dev/null +++ b/fuzzers/035b-iob-iserdes/Makefile @@ -0,0 +1,39 @@ +# Copyright (C) 2017-2020 The Project X-Ray Authors. +# +# Use of this source code is governed by a ISC-style +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/ISC +# +# SPDX-License-Identifier: ISC +N := 50 +include ../fuzzer.mk + +database: build/segbits_xioi3.db + +build/segbits_xioi3.rdb2: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -c 20 -m 1 -M 1 -o build/segbits_xioi3.rdb2 $$(find -name segdata_*.txt) + +build/segbits_xioi3.rdb: build/segbits_xioi3.rdb2 + # Keep only solution for ISERDES related features. + grep -e ".ISERDES." $^ >$@ + +build/segbits_xioi3.db: build/segbits_xioi3.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --groups tag_groups.txt --seg-fn-in $^ --seg-fn-out $@ + ${XRAY_MASKMERGE} build/mask_xioi3.db $$(find -name segdata_*.txt) + +pushdb: + ${XRAY_MERGEDB} lioi3 build/segbits_xioi3.db + ${XRAY_MERGEDB} lioi3_tbytesrc build/segbits_xioi3.db + ${XRAY_MERGEDB} lioi3_tbyteterm build/segbits_xioi3.db + ${XRAY_MERGEDB} rioi3 build/segbits_xioi3.db + ${XRAY_MERGEDB} rioi3_tbytesrc build/segbits_xioi3.db + ${XRAY_MERGEDB} rioi3_tbyteterm build/segbits_xioi3.db + ${XRAY_MERGEDB} mask_lioi3 build/mask_xioi3.db + ${XRAY_MERGEDB} mask_lioi3_tbytesrc build/mask_xioi3.db + ${XRAY_MERGEDB} mask_lioi3_tbyteterm build/mask_xioi3.db + ${XRAY_MERGEDB} mask_rioi3 build/mask_xioi3.db + ${XRAY_MERGEDB} mask_rioi3_tbytesrc build/mask_xioi3.db + ${XRAY_MERGEDB} mask_rioi3_tbyteterm build/mask_xioi3.db + +.PHONY: database pushdb + diff --git a/fuzzers/035b-iob-iserdes/bits.dbf b/fuzzers/035b-iob-iserdes/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/035b-iob-iserdes/generate.py b/fuzzers/035b-iob-iserdes/generate.py new file mode 100644 index 00000000..daa3469a --- /dev/null +++ b/fuzzers/035b-iob-iserdes/generate.py @@ -0,0 +1,287 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (C) 2017-2020 The Project X-Ray Authors. +# +# Use of this source code is governed by a ISC-style +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/ISC +# +# SPDX-License-Identifier: ISC +import json +import re + +from prjxray.segmaker import Segmaker +from prjxray import util +from prjxray import verilog + +iface_types = [ + "NETWORKING", "OVERSAMPLE", "MEMORY", "MEMORY_DDR3", "MEMORY_QDR" +] + +data_rates = ["SDR", "DDR"] + +data_widths = { + "SDR": [2, 3, 4, 5, 6, 7, 8], + "DDR": [4, 6, 8, 10, 14], +} + + +def run(): + + segmk = Segmaker("design.bits") + + # Load tags + with open("params.json", "r") as fp: + data = json.load(fp) + + loc_to_tile_site_map = {} + + # Output tags + for param_list in data: + for params in param_list: + loc = verilog.unquote(params["SITE_LOC"]) + + get_xy = util.create_xy_fun('IOB_') + x, y = get_xy(loc.replace("ILOGIC", "IOB")) + + loc_to_tile_site_map[loc] = params["TILE_NAME"] + ".IOB_Y%d" % ( + y % 2) + + # Site not used at all + if not params["IS_USED"]: + + segmk.add_site_tag(loc, "ISERDES.SHIFTOUT_USED", 0) + + segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 0) + segmk.add_site_tag(loc, "ISERDES.IN_USE", 0) + segmk.add_site_tag(loc, "IFF.IN_USE", 0) + + segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 0) + segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 0) + + for i in iface_types: + if i == "NETWORKING": + for j in data_rates: + for k in data_widths[j]: + tag = "ISERDES.%s.%s.%s" % (i, j, k) + segmk.add_site_tag(loc, tag, 0) + else: + segmk.add_site_tag(loc, "ISERDES.%s.DDR.4" % i, 0) + + segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 0) + segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0) + + for i in range(1, 4 + 1): + segmk.add_site_tag(loc, "IFF.ZINIT_Q%d" % i, 0) + + for i in range(1, 4 + 1): + segmk.add_site_tag(loc, "IFF.ZSRVAL_Q%d" % i, 0) + + # segmk.add_site_tag(loc, "ISERDES.IS_CLKB_INVERTED", 0) + # segmk.add_site_tag(loc, "ISERDES.IS_CLK_INVERTED", 1) + + segmk.add_site_tag(loc, "ISERDES.DYN_CLKDIV_INV_EN", 0) + segmk.add_site_tag(loc, "ISERDES.DYN_CLK_INV_EN", 0) + + segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0) + segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1) + segmk.add_site_tag(loc, "IDELMUXE3.P0", 0) + segmk.add_site_tag(loc, "IDELMUXE3.P1", 1) + + segmk.add_site_tag(loc, "ISERDES.OFB_USED", 0) + + # Site used as ISERDESE2 + elif verilog.unquote(params["BEL_TYPE"]) == "ISERDESE2": + + segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 1) + segmk.add_site_tag(loc, "IFF.IN_USE", 0) + segmk.add_site_tag(loc, "ISERDES.IN_USE", 1) + + if "SHIFTOUT_USED" in params: + if params["CHAINED"]: + value = params["SHIFTOUT_USED"] + segmk.add_site_tag(loc, "ISERDES.SHIFTOUT_USED", value) + + if "SERDES_MODE" in params: + value = verilog.unquote(params["SERDES_MODE"]) + if value == "MASTER": + segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 1) + segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 0) + if value == "SLAVE": + segmk.add_site_tag(loc, "ISERDES.MODE.MASTER", 0) + segmk.add_site_tag(loc, "ISERDES.MODE.SLAVE", 1) + + iface_type = verilog.unquote(params["INTERFACE_TYPE"]) + data_rate = verilog.unquote(params["DATA_RATE"]) + data_width = int(params["DATA_WIDTH"]) + + for i in iface_types: + if i == "NETWORKING": + for j in data_rates: + for k in data_widths[j]: + tag = "ISERDES.%s.%s.%s" % (i, j, k) + val = 0 + + if i == iface_type: + if j == data_rate: + if k == data_width: + segmk.add_site_tag(loc, tag, 1) + else: + if i == iface_type: + segmk.add_site_tag(loc, "ISERDES.%s.DDR.4" % i, 1) + + if "NUM_CE" in params: + value = params["NUM_CE"] + if value == 1: + segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 1) + segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0) + if value == 2: + segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 0) + segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 1) + + for i in range(1, 4 + 1): + if ("INIT_Q%d" % i) in params: + segmk.add_site_tag( + loc, "IFF.ZINIT_Q%d" % i, + not params["INIT_Q%d" % i]) + + for i in range(1, 4 + 1): + if ("SRVAL_Q%d" % i) in params: + segmk.add_site_tag( + loc, "IFF.ZSRVAL_Q%d" % i, + not params["SRVAL_Q%d" % i]) + + for inv in ["CLK", "CLKB", "OCLK", "OCLKB", "CLKDIV", + "CLKDIVP"]: + if "IS_{}_INVERTED".format(inv) in params: + segmk.add_site_tag( + loc, "ISERDES.INV_{}".format(inv), + params["IS_{}_INVERTED".format(inv)]) + segmk.add_site_tag( + loc, "ISERDES.ZINV_{}".format(inv), + not params["IS_{}_INVERTED".format(inv)]) + + if "DYN_CLKDIV_INV_EN" in params: + value = verilog.unquote(params["DYN_CLKDIV_INV_EN"]) + segmk.add_site_tag( + loc, "ISERDES.DYN_CLKDIV_INV_EN", int(value == "TRUE")) + if "DYN_CLK_INV_EN" in params: + value = verilog.unquote(params["DYN_CLK_INV_EN"]) + segmk.add_site_tag( + loc, "ISERDES.DYN_CLK_INV_EN", int(value == "TRUE")) + + # This parameter actually controls muxes used both in ILOGIC and + # ISERDES mode. + if "IOBDELAY" in params: + value = verilog.unquote(params["IOBDELAY"]) + if value == "NONE": + segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0) + segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1) + segmk.add_site_tag(loc, "IDELMUXE3.P0", 0) + segmk.add_site_tag(loc, "IDELMUXE3.P1", 1) + if value == "IBUF": + segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0) + segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1) + segmk.add_site_tag(loc, "IDELMUXE3.P0", 1) + segmk.add_site_tag(loc, "IDELMUXE3.P1", 0) + if value == "IFD": + segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1) + segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0) + segmk.add_site_tag(loc, "IDELMUXE3.P0", 0) + segmk.add_site_tag(loc, "IDELMUXE3.P1", 1) + if value == "BOTH": + segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1) + segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0) + segmk.add_site_tag(loc, "IDELMUXE3.P0", 1) + segmk.add_site_tag(loc, "IDELMUXE3.P1", 0) + + if "OFB_USED" in params: + value = verilog.unquote(params["OFB_USED"]) + segmk.add_site_tag( + loc, "ISERDES.OFB_USED", int(value == "TRUE")) + + # Site used as IDDR + elif verilog.unquote(params["BEL_TYPE"]) == "IDDR": + + segmk.add_site_tag(loc, "IDDR_OR_ISERDES.IN_USE", 1) + segmk.add_site_tag(loc, "IFF.IN_USE", 1) + segmk.add_site_tag(loc, "ISERDES.IN_USE", 0) + + if "DDR_CLK_EDGE" in params: + value = verilog.unquote(params["DDR_CLK_EDGE"]) + segmk.add_site_tag( + loc, "IFF.DDR_CLK_EDGE.OPPOSITE_EDGE", + int(value == "OPPOSITE_EDGE")) + segmk.add_site_tag( + loc, "IFF.DDR_CLK_EDGE.SAME_EDGE", + int(value == "SAME_EDGE")) + segmk.add_site_tag( + loc, "IFF.DDR_CLK_EDGE.SAME_EDGE_PIPELINED", + int(value == "SAME_EDGE_PIPELINED")) + + if "SRTYPE" in params: + value = verilog.unquote(params["SRTYPE"]) + if value == "ASYNC": + segmk.add_site_tag(loc, "IFF.SRTYPE.ASYNC", 1) + segmk.add_site_tag(loc, "IFF.SRTYPE.SYNC", 0) + if value == "SYNC": + segmk.add_site_tag(loc, "IFF.SRTYPE.ASYNC", 0) + segmk.add_site_tag(loc, "IFF.SRTYPE.SYNC", 1) + + if "IDELMUX" in params: + if params["IDELMUX"] == 1: + segmk.add_site_tag(loc, "IDELMUXE3.P0", 1) + segmk.add_site_tag(loc, "IDELMUXE3.P1", 0) + else: + segmk.add_site_tag(loc, "IDELMUXE3.P0", 0) + segmk.add_site_tag(loc, "IDELMUXE3.P1", 1) + + if "IFFDELMUX" in params: + if params["IFFDELMUX"] == 1: + segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 1) + segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 0) + else: + segmk.add_site_tag(loc, "IFFDELMUXE3.P0", 0) + segmk.add_site_tag(loc, "IFFDELMUXE3.P1", 1) + + for inv in ["C", "D"]: + if "IS_{}_INVERTED".format(inv) in params: + segmk.add_site_tag( + loc, "INV_{}".format(inv), + params["IS_{}_INVERTED".format(inv)]) + segmk.add_site_tag( + loc, "ZINV_{}".format(inv), + not params["IS_{}_INVERTED".format(inv)]) + + segmk.add_site_tag(loc, "ISERDES.NUM_CE.N1", 1) + segmk.add_site_tag(loc, "ISERDES.NUM_CE.N2", 0) + + # Should not happen + else: + print("Unknown BEL_TYPE '{}'".format(params["BEL_TYPE"])) + exit(-1) + + # Write segments and tags for later check + def_tags = {t: 0 for d in segmk.site_tags.values() for t in d.keys()} + + with open("tags.json", "w") as fp: + tags = {} + for l, d in segmk.site_tags.items(): + d1 = dict(def_tags) + d1.update({k: int(v) for k, v in d.items()}) + tags[loc_to_tile_site_map[l]] = d1 + + json.dump(tags, fp, sort_keys=True, indent=1) + + def bitfilter(frame_idx, bit_idx): + if frame_idx < 26 or frame_idx > 29: + return False + return True + + segmk.compile(bitfilter=bitfilter) + segmk.write() + + +if __name__ == "__main__": + run() diff --git a/fuzzers/035b-iob-iserdes/generate.tcl b/fuzzers/035b-iob-iserdes/generate.tcl new file mode 100644 index 00000000..2765eba9 --- /dev/null +++ b/fuzzers/035b-iob-iserdes/generate.tcl @@ -0,0 +1,34 @@ +# Copyright (C) 2017-2020 The Project X-Ray Authors +# +# Use of this source code is governed by a ISC-style +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/ISC +# +# SPDX-License-Identifier: ISC +set_param general.maxThreads 1 + +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 {NDRV-1}] +set_property IS_ENABLED 0 [get_drc_checks {UCIO-1}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-98}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-109}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-111}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-103}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-79}] +set_property IS_ENABLED 0 [get_drc_checks {PDRC-26}] +set_property IS_ENABLED 0 [get_drc_checks {REQP-105}] + +place_design +route_design + +write_checkpoint -force design.dcp +write_bitstream -force design.bit diff --git a/fuzzers/035b-iob-iserdes/tag_groups.txt b/fuzzers/035b-iob-iserdes/tag_groups.txt new file mode 100644 index 00000000..c6461d82 --- /dev/null +++ b/fuzzers/035b-iob-iserdes/tag_groups.txt @@ -0,0 +1,11 @@ +IOI3.ILOGIC_Y0.ISERDES.MEMORY.DDR.4 IOI3.ILOGIC_Y0.ISERDES.MEMORY_DDR3.DDR.4 IOI3.ILOGIC_Y0.ISERDES.MEMORY_QDR.DDR.4 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.DDR.10 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.DDR.14 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.DDR.4 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.DDR.6 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.DDR.8 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.SDR.2 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.SDR.3 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.SDR.4 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.SDR.5 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.SDR.6 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.SDR.7 IOI3.ILOGIC_Y0.ISERDES.NETWORKING.SDR.8 IOI3.ILOGIC_Y0.ISERDES.OVERSAMPLE.DDR.4 + +IOI3.ILOGIC_Y0.ISERDES.MODE.MASTER IOI3.ILOGIC_Y0.ISERDES.MODE.SLAVE + +IOI3.ILOGIC_Y0.ISERDES.NUM_CE.N1 IOI3.ILOGIC_Y0.ISERDES.NUM_CE.N2 + +IOI3.ILOGIC_Y1.ISERDES.MEMORY.DDR.4 IOI3.ILOGIC_Y1.ISERDES.MEMORY_DDR3.DDR.4 IOI3.ILOGIC_Y1.ISERDES.MEMORY_QDR.DDR.4 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.DDR.10 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.DDR.14 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.DDR.4 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.DDR.6 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.DDR.8 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.SDR.2 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.SDR.3 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.SDR.4 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.SDR.5 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.SDR.6 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.SDR.7 IOI3.ILOGIC_Y1.ISERDES.NETWORKING.SDR.8 IOI3.ILOGIC_Y1.ISERDES.OVERSAMPLE.DDR.4 + +IOI3.ILOGIC_Y1.ISERDES.MODE.MASTER IOI3.ILOGIC_Y1.ISERDES.MODE.SLAVE + +IOI3.ILOGIC_Y1.ISERDES.NUM_CE.N1 IOI3.ILOGIC_Y1.ISERDES.NUM_CE.N2 diff --git a/fuzzers/035b-iob-iserdes/top.py b/fuzzers/035b-iob-iserdes/top.py new file mode 100644 index 00000000..3e216ba7 --- /dev/null +++ b/fuzzers/035b-iob-iserdes/top.py @@ -0,0 +1,480 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# Copyright (C) 2017-2020 The Project X-Ray Authors. +# +# Use of this source code is governed by a ISC-style +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/ISC +# +# SPDX-License-Identifier: ISC +import os, random +random.seed(int(os.getenv("SEED"), 16)) + +import re +import json + +from prjxray import util +from prjxray import verilog +from prjxray.db import Database + +# ============================================================================= + + +def gen_sites(): + db = Database(util.get_db_root(), util.get_part()) + 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) + + 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( + 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 + + 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] + + top_sites = { + "IOB": iob33m, + "ILOGIC": iob33m.replace("IOB", "ILOGIC"), + "IDELAY": iob33m.replace("IOB", "IDELAY"), + } + + bot_sites = { + "IOB": iob33s, + "ILOGIC": iob33s.replace("IOB", "ILOGIC"), + "IDELAY": iob33s.replace("IOB", "IDELAY"), + } + + yield iob_tile_name, top_sites, bot_sites + + +def gen_iserdes(loc): + + # Site params + params = { + "SITE_LOC": verilog.quote(loc), + "USE_IDELAY": random.randint(0, 1), + "BEL_TYPE": verilog.quote("ISERDESE2"), + "INIT_Q1": random.randint(0, 1), + "INIT_Q2": random.randint(0, 1), + "INIT_Q3": random.randint(0, 1), + "INIT_Q4": random.randint(0, 1), + "SRVAL_Q1": random.randint(0, 1), + "SRVAL_Q2": random.randint(0, 1), + "SRVAL_Q3": random.randint(0, 1), + "SRVAL_Q4": random.randint(0, 1), + "NUM_CE": random.randint(1, 2), + + # The following one shows negative correlation (0 - not inverted) + "IS_D_INVERTED": random.randint(0, 1), + + # No bits were found for parameters below + "IS_OCLKB_INVERTED": random.randint(0, 1), + "IS_OCLK_INVERTED": random.randint(0, 1), + "IS_CLKDIVP_INVERTED": random.randint(0, 1), + "IS_CLKDIV_INVERTED": random.randint(0, 1), + "IS_CLKB_INVERTED": random.randint(0, 1), + "IS_CLK_INVERTED": random.randint(0, 1), + "DYN_CLKDIV_INV_EN": verilog.quote(random.choice(["TRUE", "FALSE"])), + "DYN_CLK_INV_EN": verilog.quote(random.choice(["TRUE", "FALSE"])), + "IOBDELAY": verilog.quote( + random.choice(["NONE", "IBUF", "IFD", "BOTH"])), + "OFB_USED": verilog.quote( + random.choice(["TRUE"] + ["FALSE"] * 9)), # Force more FALSEs + } + + iface_type = random.choice( + ["NETWORKING", "OVERSAMPLE", "MEMORY", "MEMORY_DDR3", "MEMORY_QDR"]) + data_rate = random.choice(["SDR", "DDR"]) + serdes_mode = random.choice(["MASTER", "SLAVE"]) + + params["INTERFACE_TYPE"] = verilog.quote(iface_type) + params["DATA_RATE"] = verilog.quote(data_rate) + params["SERDES_MODE"] = verilog.quote(serdes_mode) + + # Networking mode + if iface_type == "NETWORKING": + data_widths = { + "SDR": [2, 3, 4, 5, 6, 7, 8], + "DDR": [4, 6, 8, 10, 14], + } + params["DATA_WIDTH"] = random.choice(data_widths[data_rate]) + + # Others + else: + params["DATA_WIDTH"] = 4 + + if verilog.unquote(params["OFB_USED"]) == "TRUE": + params["IOBDELAY"] = verilog.quote("NONE") + + return params + + +def gen_iddr(loc): + + # Site params + params = { + "SITE_LOC": + verilog.quote(loc), + "USE_IDELAY": + random.randint(0, 1), + "BEL_TYPE": + verilog.quote("IDDR"), + "INIT_Q1": + random.randint(0, 1), + "INIT_Q2": + random.randint(0, 1), + "SRTYPE": + verilog.quote(random.choice(["ASYNC", "SYNC"])), + "DDR_CLK_EDGE": + verilog.quote( + random.choice( + ["OPPOSITE_EDGE", "SAME_EDGE", "SAME_EDGE_PIPELINED"])), + "CE1USED": + random.randint(0, 1), + "SR_MODE": + verilog.quote(random.choice(["NONE", "SET", "RST"])), + "IS_C_INVERTED": + random.randint(0, 1), + "IS_D_INVERTED": + random.randint(0, 1), + } + + if params["USE_IDELAY"]: + params["IDELMUX"] = random.randint(0, 1) + params["IFFDELMUX"] = random.randint(0, 1) + else: + params["IDELMUX"] = 0 + params["IFFDELMUX"] = 0 + + return params + + +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( + ''' +module top ( + (* CLOCK_BUFFER_TYPE = "NONE" *) + input wire clk1, + (* CLOCK_BUFFER_TYPE = "NONE" *) + input wire clk2, + input wire ce, + input wire rst, + input wire [{N}:0] di, + output wire [{N}:0] do +); + +wire [{N}:0] di_buf; +wire [{N}:0] do_buf; + +// IDELAYCTRL +(* KEEP, DONT_TOUCH *) +IDELAYCTRL idelayctrl(); + '''.format(**{"N": len(tiles) - 1})) + + # LOCes IOBs + data = [] + for i, sites in enumerate(tiles): + tile_name = sites[0] + + # Use site + if random.randint(0, 19) > 0: # Use more often + + # Top sites + if random.randint(0, 1): + this_sites = sites[1] + other_sites = sites[2] + # Bottom sites + else: + this_sites = sites[2] + other_sites = sites[1] + + # Generate cell + bel_types = ["IDDR", "ISERDESE2"] + bel_type = bel_types[int( + random.randint(0, 2) > 0)] # ISERDES more often + if bel_type == "ISERDESE2": + params = gen_iserdes(this_sites["ILOGIC"]) + if bel_type == "IDDR": + params = gen_iddr(this_sites["ILOGIC"]) + + params["IDELAY_LOC"] = verilog.quote(this_sites["IDELAY"]) + params["IS_USED"] = 1 + + # Instantiate the cell + print('') + print('// This : ' + " ".join(this_sites.values())) + print('// Other: ' + " ".join(other_sites.values())) + print('(* LOC="%s", KEEP, DONT_TOUCH *)' % this_sites["IOB"]) + print('IBUF ibuf_%03d (.I(di[%3d]), .O(di_buf[%3d]));' % (i, i, i)) + print('(* LOC="%s", KEEP, DONT_TOUCH *)' % other_sites["IOB"]) + print('OBUF obuf_%03d (.I(do_buf[%3d]), .O(do[%3d]));' % (i, i, i)) + + clk1_conn = random.choice(["clk1", ""]) + + param_str = ",".join(".%s(%s)" % (k, v) for k, v in params.items()) + print( + 'ilogic_single #(%s) ilogic_%03d (.clk1(%s), .clk2(clk2), .ce(ce), .rst(rst), .I(di_buf[%3d]), .O(do_buf[%3d]));' + % (param_str, i, clk1_conn, i, i)) + + params["CHAINED"] = 0 + params["TILE_NAME"] = tile_name + + # Params for the second site + other_params = { + "TILE_NAME": tile_name, + "SITE_LOC": verilog.quote(other_sites["ILOGIC"]), + "IDELAY_LOC": verilog.quote(other_sites["IDELAY"]), + "IS_USED": 0, + } + + # Append to data list + data.append([params, other_params]) + + # Don't use sites + else: + + params_list = [ + { + "TILE_NAME": tile_name, + "SITE_LOC": verilog.quote(sites[1]["ILOGIC"]), + "IDELAY_LOC": verilog.quote(sites[1]["IDELAY"]), + "IS_USED": 0, + }, + { + "TILE_NAME": tile_name, + "SITE_LOC": verilog.quote(sites[2]["ILOGIC"]), + "IDELAY_LOC": verilog.quote(sites[2]["IDELAY"]), + "IS_USED": 0, + } + ] + + data.append(params_list) + + # Store params + with open("params.json", "w") as fp: + json.dump(data, fp, sort_keys=True, indent=1) + + print( + ''' +endmodule + +(* KEEP, DONT_TOUCH *) +module ilogic_single( + input wire clk1, + input wire clk2, + input wire ce, + input wire rst, + input wire I, + output wire O, + input wire [1:0] shiftin, + output wire [1:0] shiftout +); + +parameter SITE_LOC = ""; +parameter IS_USED = 1; +parameter BEL_TYPE = "ISERDESE2"; +parameter IDELAY_LOC = ""; +parameter USE_IDELAY = 0; +parameter IDELMUX = 0; +parameter IFFDELMUX = 0; +parameter INTERFACE_TYPE = "NETWORKING"; +parameter DATA_RATE = "DDR"; +parameter DATA_WIDTH = 4; +parameter SERDES_MODE = "MASTER"; +parameter NUM_CE = 2; +parameter INIT_Q1 = 0; +parameter INIT_Q2 = 0; +parameter INIT_Q3 = 0; +parameter INIT_Q4 = 0; +parameter SRVAL_Q1 = 0; +parameter SRVAL_Q2 = 0; +parameter SRVAL_Q3 = 0; +parameter SRVAL_Q4 = 0; +parameter IS_D_INVERTED = 0; +parameter IS_OCLK_INVERTED = 0; +parameter IS_OCLKB_INVERTED = 0; +parameter IS_CLK_INVERTED = 0; +parameter IS_CLKB_INVERTED = 0; +parameter IS_CLKDIV_INVERTED = 0; +parameter IS_CLKDIVP_INVERTED = 0; +parameter DYN_CLKDIV_INV_EN = "FALSE"; +parameter DYN_CLK_INV_EN = "FALSE"; +parameter IOBDELAY = "NONE"; +parameter OFB_USED = "FALSE"; +parameter DDR_CLK_EDGE = "OPPOSITE_EDGE"; +parameter SRTYPE = "ASYNC"; +parameter CE1USED = 0; +parameter SR_MODE = "NONE"; +parameter IS_C_INVERTED = 0; + +wire [8:0] x; +wire ddly; + +(* KEEP, DONT_TOUCH *) +generate if (IS_USED && USE_IDELAY) begin + + // IDELAY + (* LOC=IDELAY_LOC, KEEP, DONT_TOUCH *) + IDELAYE2 idelay + ( + .C(clk), + .REGRST(), + .LD(), + .CE(), + .INC(), + .CINVCTRL(), + .CNTVALUEIN(), + .IDATAIN(I), + .DATAIN(), + .LDPIPEEN(), + .DATAOUT(ddly), + .CNTVALUEOUT() + ); + +end else begin + + assign ddly = 0; + +end endgenerate + +(* KEEP, DONT_TOUCH *) +generate if (IS_USED && BEL_TYPE == "ISERDESE2") begin + + // ISERDES + (* LOC=SITE_LOC, KEEP, DONT_TOUCH *) + ISERDESE2 # + ( + .INTERFACE_TYPE(INTERFACE_TYPE), + .DATA_RATE(DATA_RATE), + .DATA_WIDTH(DATA_WIDTH), + .SERDES_MODE(SERDES_MODE), + .NUM_CE(NUM_CE), + .IS_D_INVERTED(IS_D_INVERTED), + .IS_OCLK_INVERTED(IS_OCLK_INVERTED), + .IS_OCLKB_INVERTED(IS_OCLKB_INVERTED), + .IS_CLK_INVERTED(IS_CLK_INVERTED), + .IS_CLKB_INVERTED(IS_CLKB_INVERTED), + .IS_CLKDIV_INVERTED(IS_CLKDIV_INVERTED), + .IS_CLKDIVP_INVERTED(IS_CLKDIVP_INVERTED), + .INIT_Q1(INIT_Q1), + .INIT_Q2(INIT_Q2), + .INIT_Q3(INIT_Q3), + .INIT_Q4(INIT_Q4), + .SRVAL_Q1(SRVAL_Q1), + .SRVAL_Q2(SRVAL_Q2), + .SRVAL_Q3(SRVAL_Q3), + .SRVAL_Q4(SRVAL_Q4), + .DYN_CLKDIV_INV_EN(DYN_CLKDIV_INV_EN), + .DYN_CLK_INV_EN(DYN_CLK_INV_EN), + .IOBDELAY(IOBDELAY), + .OFB_USED(OFB_USED) + ) + isedres + ( + .D(I), + .DDLY(), + .OFB(), + //.TFB(), + .CE1(), + .CE2(), + .DYNCLKSEL(), + .CLK(clk1), + .CLKB(clk2), + .OCLK(), + .OCLKB(), + .DYNCLKDIVSEL(), + .CLKDIV(), + .CLKDIVP(), + .RST(), + .BITSLIP(), + .O(x[8]), + .Q1(x[0]), + .Q2(x[1]), + .Q3(x[2]), + .Q4(x[3]), + .Q5(x[4]), + .Q6(x[5]), + .Q7(x[6]), + .Q8(x[7]), + .SHIFTIN1(shiftin[0]), + .SHIFTIN2(shiftin[1]), + .SHIFTOUT1(shiftout[0]), + .SHIFTOUT2(shiftout[1]) + ); + +end else if (IS_USED && BEL_TYPE == "IDDR") begin + + // IDDR + (* LOC=SITE_LOC, KEEP, DONT_TOUCH *) + IDDR # + ( + .IS_C_INVERTED(IS_C_INVERTED), + .IS_D_INVERTED(IS_D_INVERTED), + .DDR_CLK_EDGE(DDR_CLK_EDGE), + .INIT_Q1(INIT_Q1), + .INIT_Q2(INIT_Q2), + .SRTYPE(SRTYPE) + ) + iddr + ( + .C(clk1), + .CE( (CE1USED) ? ce : 1'hx ), + .D( (IFFDELMUX) ? ddly : I ), + .S( (SR_MODE == "SET") ? rst : 1'd0 ), + .R( (SR_MODE == "RST") ? rst : 1'd0 ), + .Q1(x[0]), + .Q2(x[1]) + ); + + assign x[8] = (IDELMUX) ? ddly : I; + assign x[7:2] = 0; + +end else begin + + assign x[0] = I; + assign x[1] = I; + assign x[2] = I; + assign x[3] = I; + assign x[4] = I; + assign x[5] = I; + assign x[6] = I; + assign x[7] = I; + assign x[8] = I; + +end endgenerate + +// Output +assign O = |x; + +endmodule + + ''') + + +run() diff --git a/fuzzers/Makefile b/fuzzers/Makefile index c09f6b23..794e430d 100644 --- a/fuzzers/Makefile +++ b/fuzzers/Makefile @@ -117,8 +117,9 @@ $(eval $(call fuzzer,032-cmt-pll,005-tilegrid,all)) $(eval $(call fuzzer,034-cmt-pll-pips,005-tilegrid 071-ppips,all)) $(eval $(call fuzzer,035-iob-ilogic,005-tilegrid,all)) $(eval $(call fuzzer,035a-iob-idelay,005-tilegrid,all)) +$(eval $(call fuzzer,035b-iob-iserdes,005-tilegrid,all)) $(eval $(call fuzzer,036-iob-ologic,005-tilegrid,all)) -$(eval $(call fuzzer,037-iob-pips,005-tilegrid,all)) +$(eval $(call fuzzer,037-iob-pips,005-tilegrid 035b-iob-iserdes,all)) $(eval $(call fuzzer,038-cfg,005-tilegrid,all)) $(eval $(call fuzzer,039-hclk-config,005-tilegrid,all)) $(eval $(call fuzzer,040-clk-hrow-config,005-tilegrid,all))