Merge pull request #1574 from antmicro/add-pcie-int-interface-tilegrid

005-tilegrid: add pcie_int_interface tile baseaddrs
This commit is contained in:
litghost 2021-02-05 09:00:23 -08:00 committed by GitHub
commit ab542f713b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 264 additions and 13 deletions

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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()