diff --git a/fuzzers/005-tilegrid/Makefile b/fuzzers/005-tilegrid/Makefile index 98566187..9dee480c 100644 --- a/fuzzers/005-tilegrid/Makefile +++ b/fuzzers/005-tilegrid/Makefile @@ -34,6 +34,7 @@ GENERATE_FULL_ARGS= ifeq (${XRAY_DATABASE}, artix7) # Artix7 only TILEGRID_TDB_DEPENDENCIES += pcie/$(BUILD_FOLDER)/segbits_tilegrid.tdb +TILEGRID_TDB_DEPENDENCIES += pcie_int_interface/$(BUILD_FOLDER)/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += gtp_common/$(BUILD_FOLDER)/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += gtp_channel/$(BUILD_FOLDER)/segbits_tilegrid.tdb TILEGRID_TDB_DEPENDENCIES += gtp_int_interface/$(BUILD_FOLDER)/segbits_tilegrid.tdb @@ -143,6 +144,9 @@ hclk_ioi/$(BUILD_FOLDER)/segbits_tilegrid.tdb: ${BASICDB_TILEGRID} pcie/$(BUILD_FOLDER)/segbits_tilegrid.tdb: ${BASICDB_TILEGRID} cd pcie && $(MAKE) +pcie_int_interface/$(BUILD_FOLDER)/segbits_tilegrid.tdb: ${BASICDB_TILEGRID} + cd pcie_int_interface && $(MAKE) + gtp_common/$(BUILD_FOLDER)/segbits_tilegrid.tdb: ${BASICDB_TILEGRID} cd gtp_common && $(MAKE) @@ -192,6 +196,7 @@ clean: cd hclk_cmt && $(MAKE) clean cd hclk_ioi && $(MAKE) clean cd pcie && $(MAKE) clean + cd pcie_int_interface && $(MAKE) clean cd gtp_common && $(MAKE) clean cd gtp_channel && $(MAKE) clean cd gtp_int_interface && $(MAKE) clean @@ -222,6 +227,7 @@ clean_all: cd hclk_cmt && $(MAKE) clean_all cd hclk_ioi && $(MAKE) clean_all cd pcie && $(MAKE) clean_all + cd pcie_int_interface && $(MAKE) clean_all cd gtp_common && $(MAKE) clean_all cd gtp_channel && $(MAKE) clean_all cd gtp_int_interface && $(MAKE) clean_all diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py index f293d00d..9e3ab410 100644 --- a/fuzzers/005-tilegrid/add_tdb.py +++ b/fuzzers/005-tilegrid/add_tdb.py @@ -109,7 +109,7 @@ def run(fn_in, fn_out, verbose=False): ("hclk_ioi", 42, 1), ("pcie", 36, 101), ("gtp_common", 42, 101), - ("gtp_int_interface", int_frames, int_words), + ("gtp_channel", 32, 22), ("clb_int", int_frames, int_words), ("iob_int", int_frames, int_words), ("bram_int", int_frames, int_words), @@ -119,7 +119,8 @@ def run(fn_in, fn_out, verbose=False): ("cfg_int", int_frames, int_words), ("monitor_int", int_frames, int_words), ("orphan_int_column", int_frames, int_words), - ("gtp_channel", 32, 22), + ("gtp_int_interface", int_frames, int_words), + ("pcie_int_interface", int_frames, int_words), ] for (subdir, frames, words) in tdb_fns: diff --git a/fuzzers/005-tilegrid/generate_full.py b/fuzzers/005-tilegrid/generate_full.py index 5fc1978c..7492ea4e 100644 --- a/fuzzers/005-tilegrid/generate_full.py +++ b/fuzzers/005-tilegrid/generate_full.py @@ -223,13 +223,17 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): def propagate_INT_INTERFACE_bits_in_column( database, tiles_by_grid, int_interface_name): - """ Propigate INT offsets up and down INT columns. + """ Propagate INT_INTERFACE column for a given INT_INTERFACE tile name. - INT columns appear to be fairly regular, where starting from offset 0, - INT tiles next to INT tiles increase the word offset by 2. The HCLK tile - is surrounded above and sometimes below by an INT tile. Because the HCLK - tile only useds one word, the offset increase by one at the HCLK. + INT_INTERFACE tiles do not usually have any PIPs or baseaddresses, + except for a few cases such as PCIE or GTP INTERFACE tiles. + These are very regular tiles, except for the horizontal clock line, + which adds a one-word offset. + + This function replicates the baseaddress and calculates the correct offset + for each INT INTERFACE tile in a column, starting from a tile in the column + that has the baseaddress calculated from the corresponding tilegrid fuzzer. """ seen_int = set() @@ -549,6 +553,8 @@ def run(json_in_fn, json_out_fn, verbose=False): propagate_INT_bits_in_column(database, tiles_by_grid) propagate_INT_INTERFACE_bits_in_column( database, tiles_by_grid, "GTP_INT_INTERFACE") + propagate_INT_INTERFACE_bits_in_column( + database, tiles_by_grid, "PCIE_INT_INTERFACE") propagate_rebuf(database, tiles_by_grid) propagate_IOB_SING(database, tiles_by_grid) propagate_IOI_SING(database, tiles_by_grid) diff --git a/fuzzers/005-tilegrid/gtp_int_interface/generate.tcl b/fuzzers/005-tilegrid/gtp_int_interface/generate.tcl index c682d573..ec8d5b84 100644 --- a/fuzzers/005-tilegrid/gtp_int_interface/generate.tcl +++ b/fuzzers/005-tilegrid/gtp_int_interface/generate.tcl @@ -23,12 +23,16 @@ proc parse_csv {} { continue } + # Skip empty lines + if { $line == "" } { + continue + } + set parts [split $line ","] dict lappend params_map [lindex $parts 2] [lindex $parts 1] } - puts $params_map return $params_map } @@ -41,11 +45,6 @@ proc route_through_delay {} { continue } - if { $key == "" } { - puts "Dictionary key is incorrect, continuing" - continue - } - set net_name "PLL0LOCKEN_$key" set net [get_nets $net_name] diff --git a/fuzzers/005-tilegrid/pcie_int_interface/Makefile b/fuzzers/005-tilegrid/pcie_int_interface/Makefile new file mode 100644 index 00000000..aa8911ce --- /dev/null +++ b/fuzzers/005-tilegrid/pcie_int_interface/Makefile @@ -0,0 +1,10 @@ +# 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 --dword 0 --auto-frame" +include ../fuzzaddr/common.mk diff --git a/fuzzers/005-tilegrid/pcie_int_interface/generate.tcl b/fuzzers/005-tilegrid/pcie_int_interface/generate.tcl new file mode 100644 index 00000000..86b08a1e --- /dev/null +++ b/fuzzers/005-tilegrid/pcie_int_interface/generate.tcl @@ -0,0 +1,91 @@ +# 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 0] [lindex $parts 1] + } + + return $params_map +} + + +proc route_through_delay {} { + set params_map [parse_csv] + set nets [get_nets] + + dict for { key value } $params_map { + if { $value == 0 } { + continue + } + + foreach net $nets { + set wire [get_wires -of_objects $net -filter {TILE_NAME =~ "*PCIE_INT_INTERFACE*" && NAME =~ "*OUT0*"}] + + if { $wire == "" || ![regexp $key $wire] } { + continue + } + + set wire_parts [split $wire "/"] + + set pcie_int_tile [lindex $wire_parts 0] + set node [get_nodes -of_object [get_tiles $pcie_int_tile] -filter { NAME =~ "*DELAY0" }] + + 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 + + place_design + route_design + + write_checkpoint -force design_pre_force_route.dcp + + route_through_delay + + write_checkpoint -force design.dcp + write_bitstream -force design.bit +} + +run diff --git a/fuzzers/005-tilegrid/pcie_int_interface/top.py b/fuzzers/005-tilegrid/pcie_int_interface/top.py new file mode 100644 index 00000000..129ef8e9 --- /dev/null +++ b/fuzzers/005-tilegrid/pcie_int_interface/top.py @@ -0,0 +1,138 @@ +#!/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 + +GTP_INT_Y_RE = re.compile("PCIE_INT_INTERFACE.*X[0-9]+Y([0-9]+)") + + +def get_pcie_int_tiles(grid, pcie_loc): + def get_site_at_loc(loc): + gridinfo = grid.gridinfo_at_loc(loc) + + sites = list(gridinfo.sites.keys()) + + if len(sites) and sites[0].startswith("SLICE"): + return sites[0] + + return None + + pcie_int_tiles = list() + + for tile_name in sorted(grid.tiles()): + if not tile_name.startswith("PCIE_INT_INTERFACE"): + continue + + m = GTP_INT_Y_RE.match(tile_name) + + assert m + + int_y = int(m.group(1)) + + if int_y % 50 == 0: + loc = grid.loc_of_tilename(tile_name) + is_left = loc.grid_x < pcie_loc.grid_x + + if is_left: + for i in range(1, loc.grid_x): + loc_grid_x = loc.grid_x - i + + site = get_site_at_loc(GridLoc(loc_grid_x, loc.grid_y)) + + if site: + break + else: + _, x_max, _, _ = grid.dims() + for i in range(1, x_max - loc.grid_x): + loc_grid_x = loc.grid_x + i + + site = get_site_at_loc(GridLoc(loc_grid_x, loc.grid_y)) + + if site: + break + + pcie_int_tiles.append((tile_name, is_left, site)) + + return pcie_int_tiles + + +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 ['PCIE_2_1']: + pcie_int_tiles = get_pcie_int_tiles(grid, loc) + + yield pcie_int_tiles, 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 pcie_int_tiles, site_name in sites: + left_side = None + right_side = None + + for tile, is_left, site in pcie_int_tiles: + isone = random.randint(0, 1) + params[tile] = (site_name, isone) + + if is_left: + left_side = site + else: + right_side = site + + assert left_side and right_side + + print( + ''' +wire [1:0] PLDIRECTEDLINKCHANGE; +wire [68:0] MIMTXRDATA; + +(* KEEP, DONT_TOUCH, LOC = "{left}" *) +LUT1 left_lut_{left} (.O(MIMTXRDATA[0])); + +(* KEEP, DONT_TOUCH, LOC = "{right}" *) +LUT1 right_lut_{right} (.O(PLDIRECTEDLINKCHANGE[0])); + +(* KEEP, DONT_TOUCH, LOC = "{site}" *) +PCIE_2_1 pcie_2_1_{site} ( + .PLDIRECTEDLINKCHANGE(PLDIRECTEDLINKCHANGE), + .MIMTXRDATA(MIMTXRDATA) +);'''.format(site=site_name, right=right_side, left=left_side)) + + print("endmodule") + write_params(params) + + +if __name__ == '__main__': + run()