005-tilegrid: add gtp_int_interface tile baseaddress

Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
This commit is contained in:
Alessandro Comodi 2021-02-01 17:04:36 +01:00
parent 2262775279
commit f1bc93089e
6 changed files with 303 additions and 0 deletions

View File

@ -36,6 +36,7 @@ ifeq (${XRAY_DATABASE}, artix7)
TILEGRID_TDB_DEPENDENCIES += pcie/$(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
endif
ifeq (${XRAY_DATABASE}, zynq7)
@ -148,6 +149,9 @@ gtp_common/$(BUILD_FOLDER)/segbits_tilegrid.tdb: ${BASICDB_TILEGRID}
gtp_channel/$(BUILD_FOLDER)/segbits_tilegrid.tdb: ${BASICDB_TILEGRID}
cd gtp_channel && $(MAKE)
gtp_int_interface/$(BUILD_FOLDER)/segbits_tilegrid.tdb: ${BASICDB_TILEGRID}
cd gtp_int_interface && $(MAKE)
$(BUILD_FOLDER)/tilegrid_tdb.json: add_tdb.py $(TILEGRID_TDB_DEPENDENCIES)
python3 add_tdb.py \
--fn-in ${BASICDB_TILEGRID} \
@ -190,6 +194,7 @@ clean:
cd pcie && $(MAKE) clean
cd gtp_common && $(MAKE) clean
cd gtp_channel && $(MAKE) clean
cd gtp_int_interface && $(MAKE) clean
clean_all:
rm -rf build_* run.*.ok
@ -219,6 +224,7 @@ clean_all:
cd pcie && $(MAKE) clean_all
cd gtp_common && $(MAKE) clean_all
cd gtp_channel && $(MAKE) clean_all
cd gtp_int_interface && $(MAKE) clean_all
.PHONY: database pushdb clean clean_all run

View File

@ -109,6 +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),
("clb_int", int_frames, int_words),
("iob_int", int_frames, int_words),
("bram_int", int_frames, int_words),

View File

@ -221,6 +221,99 @@ def propagate_INT_bits_in_column(database, tiles_by_grid):
tile = database[tile_name]
def propagate_INT_INTERFACE_bits_in_column(
database, tiles_by_grid, int_interface_name):
""" Propigate INT offsets up and down INT columns.
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.
"""
seen_int = set()
int_frames, int_words, _ = localutil.get_entry('INT', 'CLB_IO_CLK')
hclk_frames, hclk_words, _ = localutil.get_entry('HCLK', 'CLB_IO_CLK')
for tile_name in sorted(database.keys()):
tile = database[tile_name]
if not tile['type'].startswith(int_interface_name):
continue
if not tile['bits']:
continue
if tile_name in seen_int:
continue
# Walk down INT column
down_tile = tile
down_tile_name = tile_name
while True:
seen_int.add(down_tile_name)
baseaddr = int(down_tile['bits']['CLB_IO_CLK']['baseaddr'], 0)
offset = down_tile['bits']['CLB_IO_CLK']['offset']
extra_offset = 0
next_tile = tiles_by_grid[(
down_tile['grid_x'], down_tile['grid_y'] + 1)]
if next_tile.startswith("HCLK"):
next_tile = tiles_by_grid[(
down_tile['grid_x'], down_tile['grid_y'] + 2)]
extra_offset = hclk_words
next_tile_type = database[next_tile]['type']
if next_tile_type != tile['type']:
break
if next_tile_type == down_tile['type']:
# INT next to INT
offset -= (int_words + extra_offset)
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
int_frames, int_words)
down_tile_name = next_tile
down_tile = database[down_tile_name]
# Walk up INT column
up_tile = tile
up_tile_name = tile_name
while True:
seen_int.add(up_tile_name)
baseaddr = int(up_tile['bits']['CLB_IO_CLK']['baseaddr'], 0)
offset = up_tile['bits']['CLB_IO_CLK']['offset']
extra_offset = 0
next_tile = tiles_by_grid[(
up_tile['grid_x'], up_tile['grid_y'] - 1)]
if next_tile.startswith("HCLK"):
next_tile = tiles_by_grid[(
up_tile['grid_x'], up_tile['grid_y'] - 2)]
extra_offset = hclk_words
next_tile_type = database[next_tile]['type']
if next_tile_type != tile['type']:
break
if next_tile_type == up_tile['type']:
# INT next to INT
offset += (int_words + extra_offset)
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
int_frames, int_words)
up_tile_name = next_tile
up_tile = database[up_tile_name]
def propagate_rebuf(database, tiles_by_grid):
""" Writing a fuzzer for the CLK_BUFG_REBUF tiles is hard, so propigate from CLK_HROW tiles.
@ -454,6 +547,8 @@ def run(json_in_fn, json_out_fn, verbose=False):
propagate_INT_lr_bits(database, tiles_by_grid, verbose=verbose)
propagate_INT_bits_in_column(database, tiles_by_grid)
propagate_INT_INTERFACE_bits_in_column(
database, tiles_by_grid, "GTP_INT_INTERFACE")
propagate_rebuf(database, tiles_by_grid)
propagate_IOB_SING(database, tiles_by_grid)
propagate_IOI_SING(database, tiles_by_grid)

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,87 @@
# 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
}
set parts [split $line ","]
dict lappend params_map [lindex $parts 2] [lindex $parts 1]
}
puts $params_map
return $params_map
}
proc route_through_delay {} {
set params_map [parse_csv]
dict for { key value } $params_map {
if { $value == 0 } {
continue
}
if { $key == "" } {
puts "Dictionary key is incorrect, continuing"
continue
}
set net_name "PLL0LOCKEN_$key"
set net [get_nets $net_name]
set wire [get_wires -of_objects $net -filter {TILE_NAME =~ "*GTP_INT_INTERFACE*" && NAME =~ "*IMUX_OUT42*"}]
set wire_parts [split $wire "/"]
set gtp_int_tile [lindex $wire_parts 0]
set node [get_nodes -of_object [get_tiles $gtp_int_tile] -filter { NAME =~ "*DELAY42" }]
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

View File

@ -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
GTP_INT_Y_RE = re.compile("GTP_INT_INTERFACE.*X[0-9]+Y([0-9]+)")
def get_gtp_int_tile(clock_region, grid):
for tile_name in sorted(grid.tiles()):
if not tile_name.startswith("GTP_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 = GTP_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 ['GTPE2_COMMON']:
gtp_int_tile = get_gtp_int_tile(gridinfo.clock_region, grid)
yield gtp_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 gtp_int_tile, site_name in sites:
isone = random.randint(0, 1)
params[gtp_int_tile] = (site_name, isone)
print(
'''
wire PLL0LOCKEN_{site};
(* KEEP, DONT_TOUCH *)
LUT1 lut_{site} (.O(PLL0LOCKEN_{site}));
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
GTPE2_COMMON gtpe2_common_{site} (
.PLL0LOCKEN(PLL0LOCKEN_{site})
);'''.format(site=site_name))
print("endmodule")
write_params(params)
if __name__ == '__main__':
run()