diff --git a/fuzzers/005-tilegrid/Makefile b/fuzzers/005-tilegrid/Makefile index 55d2e2c8..c801bb37 100644 --- a/fuzzers/005-tilegrid/Makefile +++ b/fuzzers/005-tilegrid/Makefile @@ -2,6 +2,7 @@ FUZDIR=$(shell pwd) BUILD_DIR=$(FUZDIR)/build TILEGRID_TDB_DEPENDENCIES= TILEGRID_TDB_DEPENDENCIES += iob/build/segbits_tilegrid.tdb +TILEGRID_TDB_DEPENDENCIES += iob_int/build/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += mmcm/build/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += pll/build/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += monitor/build/segbits_tilegrid.tdb @@ -39,6 +40,9 @@ clb_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json iob/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json cd iob && $(MAKE) +iob_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json + cd iob_int && $(MAKE) + mmcm/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json cd mmcm && $(MAKE) @@ -77,6 +81,7 @@ clean: cd clb && $(MAKE) clean cd clb_int && $(MAKE) clean cd iob && $(MAKE) clean + cd iob_int && $(MAKE) clean cd mmcm && $(MAKE) clean cd pll && $(MAKE) clean cd ps7_int && $(MAKE) clean diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py index fcb18f0e..f9253098 100644 --- a/fuzzers/005-tilegrid/add_tdb.py +++ b/fuzzers/005-tilegrid/add_tdb.py @@ -64,6 +64,7 @@ def run(fn_in, fn_out, verbose=False): ("bram_block/build/segbits_tilegrid.tdb", 128, 10), ("clb/build/segbits_tilegrid.tdb", 36, 2), ("clb_int/build/segbits_tilegrid.tdb", int_frames, int_words), + ("iob_int/build/segbits_tilegrid.tdb", int_frames, int_words), ] for (tdb_fn, frames, words) in tdb_fns: diff --git a/fuzzers/005-tilegrid/clb_int/top.py b/fuzzers/005-tilegrid/clb_int/top.py index 0f13ea0a..62be8763 100644 --- a/fuzzers/005-tilegrid/clb_int/top.py +++ b/fuzzers/005-tilegrid/clb_int/top.py @@ -46,6 +46,8 @@ module top(); util.gen_fuzz_states(len(sites))): params[tile_name] = (site_name, isone) + # Force HARD0 -> GFAN1 with I2 = 0 + # Toggle 1 pip with I1 = ? print( ''' wire lut_to_f7_{0}, f7_to_f8_{0}; diff --git a/fuzzers/005-tilegrid/iob_int/Makefile b/fuzzers/005-tilegrid/iob_int/Makefile new file mode 100644 index 00000000..cd564940 --- /dev/null +++ b/fuzzers/005-tilegrid/iob_int/Makefile @@ -0,0 +1,3 @@ +N ?= 35 +GENERATE_ARGS?="--oneval 0 --design params.csv --dframe 14 --dword 1" +include ../fuzzaddr/common.mk diff --git a/fuzzers/005-tilegrid/iob_int/generate.tcl b/fuzzers/005-tilegrid/iob_int/generate.tcl new file mode 100644 index 00000000..7b203db8 --- /dev/null +++ b/fuzzers/005-tilegrid/iob_int/generate.tcl @@ -0,0 +1,76 @@ +source "$::env(XRAY_DIR)/utils/utils.tcl" + +proc make_io_pin_sites {} { + # get all possible IOB pins + foreach pad [get_package_pins -filter "IS_GENERAL_PURPOSE == 1"] { + set site [get_sites -of_objects $pad] + if {[llength $site] == 0} { + continue + } + if [string match IOB33* [get_property SITE_TYPE $site]] { + dict append io_pin_sites $site $pad + } + } + return $io_pin_sites +} + +proc load_pin_lines {} { + # IOB_X0Y103 clk input + # IOB_X0Y129 do[0] output + + set fp [open "params.csv" r] + set pin_lines {} + for {gets $fp line} {$line != ""} {gets $fp line} { + lappend pin_lines [split $line ","] + } + close $fp + return $pin_lines +} + +proc loc_pins {} { + set pin_lines [load_pin_lines] + set io_pin_sites [make_io_pin_sites] + + puts "Looping" + for {set idx 0} {$idx < [llength $pin_lines]} {incr idx} { + set line [lindex $pin_lines $idx] + puts "$line" + + set site_str [lindex $line 3] + set pin_str [lindex $line 4] + + # Have: site + # Want: pin for site + + set site [get_sites $site_str] + set pad_bel [get_bels -of_objects $site -filter {TYPE =~ PAD && NAME =~ IOB_*}] + # set port [get_ports -of_objects $site] + set port [get_ports $pin_str] + set tile [get_tiles -of_objects $site] + + set pin [dict get $io_pin_sites $site] + + set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" $port + } +} + +proc run {} { + create_project -force -part $::env(XRAY_PART) design design + read_verilog top.v + synth_design -top top + + loc_pins + + 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-79}] + + place_design + route_design + + write_checkpoint -force design.dcp + write_bitstream -force design.bit +} + +run diff --git a/fuzzers/005-tilegrid/iob_int/top.py b/fuzzers/005-tilegrid/iob_int/top.py new file mode 100644 index 00000000..571ac7df --- /dev/null +++ b/fuzzers/005-tilegrid/iob_int/top.py @@ -0,0 +1,112 @@ +''' +Generate a primitive to place at every I/O +Unlike CLB tests, the LFSR for this is inside the ROI, not driving it +''' + +import os +import random +random.seed(int(os.getenv("SEED"), 16)) +from prjxray import util +from prjxray.db import Database + + +def gen_sites(): + ''' + IOB33S: main IOB of a diff pair + IOB33M: secondary IOB of a diff pair + IOB33: not a diff pair. Relatively rare (at least in ROI...2 of them?) + Focus on IOB33S to start + ''' + 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_name, site_type in gridinfo.sites.items(): + if site_type == 'IDELAYE2': + sites.append(site_name) + + if len(sites) == 0: + continue + + sites = sorted(sites) + + if gridinfo.tile_type[0] == 'L': + int_grid_x = loc.grid_x + 3 + pad_grid_x = loc.grid_x - 1 + int_tile_type = 'INT_L' + else: + int_grid_x = loc.grid_x - 3 + pad_grid_x = loc.grid_x + 1 + int_tile_type = 'INT_R' + + int_tile_locs = [ + (int_grid_x, loc.grid_y), + ] + + pad_gridinfo = grid.gridinfo_at_loc((pad_grid_x, loc.grid_y)) + pad_sites = sorted(pad_gridinfo.sites.keys()) + + if not gridinfo.tile_type.endswith("_SING"): + int_tile_locs.append((int_grid_x, loc.grid_y - 1)) + + assert len(sites) == len(int_tile_locs), (tile_name, sites, int_tile_locs) + assert len(sites) == len(pad_sites), (sites, pad_sites) + + for site_name, pad_site, int_tile_loc in zip(sites, pad_sites, int_tile_locs): + int_tile_name = grid.tilename_at_loc(int_tile_loc) + assert int_tile_name.startswith(int_tile_type), (int_tile_name, site_name, int_tile_loc) + yield int_tile_name, site_name, pad_site + + +def write_params(params): + pinstr = '' + for tile, (site, val, pad_site_name, pin) in sorted(params.items()): + pinstr += '%s,%s,%s,%s,%s\n' % (tile, val, site, pad_site_name, pin) + open('params.csv', 'w').write(pinstr) + + +def run(): + sites = list(gen_sites()) + print( + ''' +`define N_DI {} + +module top(input wire [`N_DI-1:0] di); + wire [`N_DI-1:0] di_buf; + + (* KEEP, DONT_TOUCH, IODELAY_GROUP = "iodelays" *) + IDELAYCTRL idelayctrl ( + .REFCLK() + ); + '''.format(len(sites))) + + params = {} + + for idx, ((tile_name, site_name, pad_site_name), isone) in enumerate(zip(sites, + util.gen_fuzz_states(len(sites)))): + params[tile_name] = (site_name, isone, pad_site_name, "di[%u]" % idx) + + # Force HARD0 -> GFAN1 with CNTVALUEIN4 = 0 + # Toggle 1 pip with CNTVALUEIN3 = ? + print( + ''' + + (* KEEP, DONT_TOUCH *) + IBUF ibuf_{0}(.I(di[{2}]), .O(di_buf[{2}])); + + (* KEEP, DONT_TOUCH, LOC = "{0}", IODELAY_GROUP = "iodelays" *) + IDELAYE2 idelay_{0} ( + .CNTVALUEIN(5'b0{1}111), + .IDATAIN(di_buf[{2}]) + ); +'''.format(site_name, isone, idx)) + + print("endmodule") + write_params(params) + + +if __name__ == '__main__': + run()