005-tilegrid/gtx_int_interface fuzzer works
Signed-off-by: Hans Baier <foss@hans-baier.de>
diff --git a/fuzzers/005-tilegrid/gtx_int_interface/Makefile b/fuzzers/005-tilegrid/gtx_int_interface/Makefile
new file mode 100644
index 0000000..eb459dc
--- /dev/null
+++ b/fuzzers/005-tilegrid/gtx_int_interface/Makefile
@@ -0,0 +1,17 @@
+# 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 ?= 8
+GENERATE_ARGS?="--oneval 1 --design params.csv --dframe 1b --dword 0 --dbit 4"
+include ../fuzzaddr/common.mk
+SEGBITS=$(BUILD_DIR)/segbits_tilegrid.tdb
+$(SEGBITS): $(SPECIMENS_OK)
+ # multiple bits match for the changes, but all of those except the ones with addresses ending with 0x9b are known
+ # and not related to GTX_INT_INTERFACE
+ ${XRAY_SEGMATCH} -c 6 -o $(BUILD_DIR)/segbits_tilegrid.tdb $$(find $(BUILD_DIR) -name "segdata_tilegrid.txt")
+ tr ' ' '\n' < $(SEGBITS) | grep -E 'GTX|9B' | paste -d " " - - > $(SEGBITS).tmp
+ mv -fv $(SEGBITS).tmp $(SEGBITS)
diff --git a/fuzzers/005-tilegrid/gtx_int_interface/generate.tcl b/fuzzers/005-tilegrid/gtx_int_interface/generate.tcl
new file mode 100644
index 0000000..798d66b
--- /dev/null
+++ b/fuzzers/005-tilegrid/gtx_int_interface/generate.tcl
@@ -0,0 +1,86 @@
+# 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
+source "$::env(XRAY_DIR)/utils/utils.tcl"
+
+proc parse_csv {} {
+ set fp [open "params.csv"]
+ set file_data [read $fp]
+ close $fp
+
+ set file_data [split $file_data "\n"]
+
+ set params_map [dict create]
+
+ set is_first_line true
+ foreach line $file_data {
+ if { $is_first_line } {
+ set is_first_line false
+ continue
+ }
+
+ # Skip empty lines
+ if { $line == "" } {
+ continue
+ }
+
+ set parts [split $line ","]
+
+ dict lappend params_map [lindex $parts 2] [lindex $parts 1]
+ }
+
+ return $params_map
+}
+
+
+proc route_through_delay {} {
+ set params_map [parse_csv]
+
+ dict for { key value } $params_map {
+ if { $value == 0 } {
+ continue
+ }
+
+ set net_name "QPLLLOCKEN_$key"
+ set net [get_nets $net_name]
+
+ set wire [get_wires -of_objects $net -filter {TILE_NAME =~ "*GTX_INT_INTERFACE*" && NAME =~ "*IMUX_OUT24*"}]
+ set wire_parts [split $wire "/"]
+
+ set gtx_int_tile [lindex $wire_parts 0]
+ set node [get_nodes -of_object [get_tiles $gtx_int_tile] -filter { NAME =~ "*DELAY24" }]
+
+ route_design -unroute -nets $net
+ puts "Attempting to route net $net through $node."
+ route_via $net [list $node]
+ }
+}
+
+
+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]
+
+ # Disable MMCM frequency etc sanity checks
+ set_property IS_ENABLED 0 [get_drc_checks {REQP-47}]
+ set_property IS_ENABLED 0 [get_drc_checks {REQP-48}]
+
+ place_design
+ route_design
+
+ route_through_delay
+
+ write_checkpoint -force design.dcp
+ write_bitstream -force design.bit
+}
+
+run
diff --git a/fuzzers/005-tilegrid/gtx_int_interface/top.py b/fuzzers/005-tilegrid/gtx_int_interface/top.py
new file mode 100644
index 0000000..2ee27e0
--- /dev/null
+++ b/fuzzers/005-tilegrid/gtx_int_interface/top.py
@@ -0,0 +1,104 @@
+#!/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
+import re
+import random
+random.seed(int(os.getenv("SEED"), 16))
+from prjxray import util
+from prjxray.db import Database
+from prjxray.grid_types import GridLoc
+
+GTX_INT_Y_RE = re.compile("GTX_INT_INTERFACE.*X[0-9]+Y([0-9]+)")
+
+
+def get_gtx_int_tile(clock_region, grid):
+ for tile_name in sorted(grid.tiles()):
+ if not tile_name.startswith("GTX_INT_INTERFACE"):
+ continue
+
+ loc = grid.loc_of_tilename(tile_name)
+
+ left_gridinfo = grid.gridinfo_at_loc(
+ GridLoc(loc.grid_x - 1, loc.grid_y))
+ right_gridinfo = grid.gridinfo_at_loc(
+ GridLoc(loc.grid_x + 1, loc.grid_y))
+
+ if left_gridinfo.tile_type in ["INT_L", "INT_R"]:
+ cmt = left_gridinfo.clock_region
+ elif right_gridinfo.tile_type in ["INT_L", "INT_R"]:
+ cmt = right_gridinfo.clock_region
+ else:
+ assert False
+
+ gridinfo = grid.gridinfo_at_loc(loc)
+
+ m = GTX_INT_Y_RE.match(tile_name)
+
+ assert m
+
+ int_y = int(m.group(1))
+
+ if clock_region == cmt and int_y % 50 == 26:
+ return tile_name
+
+
+def gen_sites():
+ db = Database(util.get_db_root(), util.get_part())
+ 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_name, site_type in gridinfo.sites.items():
+ if site_type in ['GTXE2_COMMON']:
+ gtx_int_tile = get_gtx_int_tile(gridinfo.clock_region, grid)
+
+ yield gtx_int_tile, site_name
+
+
+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 gtx_int_tile, site_name in sites:
+ isone = random.randint(0, 1)
+
+ params[gtx_int_tile] = (site_name, isone)
+
+ print(
+ '''
+wire QPLLLOCKEN_{site};
+
+(* KEEP, DONT_TOUCH *)
+LUT1 lut_{site} (.O(QPLLLOCKEN_{site}));
+
+(* KEEP, DONT_TOUCH, LOC = "{site}" *)
+GTXE2_COMMON gtxe2_common_{site} (
+ .QPLLLOCKEN(QPLLLOCKEN_{site})
+);'''.format(site=site_name))
+
+ print("endmodule")
+ write_params(params)
+
+
+if __name__ == '__main__':
+ run()