Merge pull request #1606 from antmicro/auto_frames_count
005-tilegrid: Extract frames count information from part's json
diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py
index 9c4c442..021f14f 100644
--- a/fuzzers/005-tilegrid/add_tdb.py
+++ b/fuzzers/005-tilegrid/add_tdb.py
@@ -123,6 +123,7 @@
("pcie_int_interface", int_frames, int_words),
]
+ tile_frames_map = localutil.TileFrames()
for (subdir, frames, words) in tdb_fns:
tdb_fn = os.path.join(
subdir, 'build_{}'.format(os.environ['XRAY_PART']),
@@ -134,7 +135,8 @@
for (tile, frame, wordidx) in load_db(tdb_fn):
tilej = database[tile]
verbose and print("Add %s %08X_%03u" % (tile, frame, wordidx))
- localutil.add_tile_bits(tile, tilej, frame, wordidx, frames, words)
+ localutil.add_tile_bits(
+ tile, tilej, frame, wordidx, frames, words, tile_frames_map)
# Save
xjson.pprint(open(fn_out, "w"), database)
diff --git a/fuzzers/005-tilegrid/generate_full.py b/fuzzers/005-tilegrid/generate_full.py
index 7492ea4..4022edc 100644
--- a/fuzzers/005-tilegrid/generate_full.py
+++ b/fuzzers/005-tilegrid/generate_full.py
@@ -49,7 +49,8 @@
return tiles_by_grid
-def propagate_INT_lr_bits(database, tiles_by_grid, verbose=False):
+def propagate_INT_lr_bits(
+ database, tiles_by_grid, tile_frames_map, verbose=False):
'''Populate segment base addresses: L/R along INT column'''
int_frames, int_words, _ = localutil.get_entry('INT', 'CLB_IO_CLK')
@@ -92,10 +93,10 @@
localutil.add_tile_bits(
other_tile, database[other_tile], baseaddr, offset, int_frames,
- int_words)
+ int_words, tile_frames_map)
-def propagate_INT_bits_in_column(database, tiles_by_grid):
+def propagate_INT_bits_in_column(database, tiles_by_grid, tile_frames_map):
""" Propigate INT offsets up and down INT columns.
INT columns appear to be fairly regular, where starting from offset 0,
@@ -146,7 +147,7 @@
offset -= int_words
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
- int_frames, int_words)
+ int_frames, int_words, tile_frames_map)
elif tile['type'].startswith('INT_'):
# INT above HCLK
assert next_tile_type.startswith(
@@ -155,7 +156,7 @@
offset -= hclk_words
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
- hclk_frames, hclk_words)
+ hclk_frames, hclk_words, tile_frames_map)
else:
# HCLK above INT
assert tile['type'].startswith(
@@ -164,7 +165,7 @@
offset -= int_words
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
- int_frames, int_words)
+ int_frames, int_words, tile_frames_map)
else:
# Handle special case column where the PCIE tile is present.
assert next_tile_type in ['PCIE_NULL'], next_tile_type
@@ -195,7 +196,7 @@
offset += int_words
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
- int_frames, int_words)
+ int_frames, int_words, tile_frames_map)
elif tile['type'].startswith('INT_'):
# INT below HCLK
assert next_tile_type.startswith(
@@ -204,7 +205,7 @@
offset += int_words
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
- hclk_frames, hclk_words)
+ hclk_frames, hclk_words, tile_frames_map)
else:
# HCLK below INT
assert tile['type'].startswith(
@@ -215,14 +216,14 @@
offset += hclk_words
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
- int_frames, int_words)
+ int_frames, int_words, tile_frames_map)
tile_name = next_tile
tile = database[tile_name]
def propagate_INT_INTERFACE_bits_in_column(
- database, tiles_by_grid, int_interface_name):
+ database, tiles_by_grid, int_interface_name, tile_frames_map):
""" Propagate INT_INTERFACE column for a given INT_INTERFACE tile name.
INT_INTERFACE tiles do not usually have any PIPs or baseaddresses,
@@ -280,7 +281,7 @@
offset -= (int_words + extra_offset)
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
- int_frames, int_words)
+ int_frames, int_words, tile_frames_map)
down_tile_name = next_tile
down_tile = database[down_tile_name]
@@ -312,7 +313,7 @@
offset += (int_words + extra_offset)
localutil.add_tile_bits(
next_tile, database[next_tile], baseaddr, offset,
- int_frames, int_words)
+ int_frames, int_words, tile_frames_map)
up_tile_name = next_tile
up_tile = database[up_tile_name]
@@ -549,12 +550,14 @@
database = json.load(open(json_in_fn, "r"))
tiles_by_grid = make_tiles_by_grid(database)
- propagate_INT_lr_bits(database, tiles_by_grid, verbose=verbose)
- propagate_INT_bits_in_column(database, tiles_by_grid)
+ tile_frames_map = localutil.TileFrames()
+ propagate_INT_lr_bits(
+ database, tiles_by_grid, tile_frames_map, verbose=verbose)
+ propagate_INT_bits_in_column(database, tiles_by_grid, tile_frames_map)
propagate_INT_INTERFACE_bits_in_column(
- database, tiles_by_grid, "GTP_INT_INTERFACE")
+ database, tiles_by_grid, "GTP_INT_INTERFACE", tile_frames_map)
propagate_INT_INTERFACE_bits_in_column(
- database, tiles_by_grid, "PCIE_INT_INTERFACE")
+ database, tiles_by_grid, "PCIE_INT_INTERFACE", tile_frames_map)
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/util.py b/fuzzers/005-tilegrid/util.py
index 421f7b3..0f65e00 100644
--- a/fuzzers/005-tilegrid/util.py
+++ b/fuzzers/005-tilegrid/util.py
@@ -10,11 +10,51 @@
# SPDX-License-Identifier: ISC
from prjxray import util
+import os
+import json
'''
Local utils script to hold shared code of the 005-tilegrid fuzzer scripts
'''
+class TileFrames:
+ """
+ Class for getting the number of frames used for configuring a tile
+ with the specified baseaddress using the information from the part's json file
+ """
+
+ def __init__(self):
+ self.tile_address_to_frames = dict()
+
+ def get_baseaddress(self, region, bus, row, column):
+ assert bus == 'BLOCK_RAM' or bus == 'CLB_IO_CLK', 'Incorrect block type'
+ address = (row << 17) + (column << 7) + (
+ (1 << 22) if region == 'bottom' else 0) + (
+ (1 << 23) if bus == 'BLOCK_RAM' else 0)
+ return address
+
+ def initialize_address_to_frames(self):
+ with open(os.path.join(os.getenv('XRAY_FAMILY_DIR'),
+ os.getenv('XRAY_PART'), 'part.json')) as pf:
+ part_json = json.load(pf)
+ for clock_region, rows in part_json['global_clock_regions'].items():
+ for row, buses in rows['rows'].items():
+ for bus, columns in buses['configuration_buses'].items():
+ for column, frames in columns[
+ 'configuration_columns'].items():
+ address = self.get_baseaddress(
+ clock_region, bus, int(row), int(column))
+ assert address not in self.tile_address_to_frames
+ self.tile_address_to_frames[address] = frames[
+ 'frame_count']
+
+ def get_tile_frames(self, baseaddress):
+ if len(self.tile_address_to_frames) == 0:
+ self.initialize_address_to_frames()
+ assert baseaddress in self.tile_address_to_frames, "Base address not found in the part's json file"
+ return self.tile_address_to_frames[baseaddress]
+
+
def get_entry(tile_type, block_type):
""" Get frames and words for a given tile_type (e.g. CLBLL) and block_type (CLB_IO_CLK, BLOCK_RAM, etc). """
return {
@@ -35,7 +75,14 @@
def add_tile_bits(
- tile_name, tile_db, baseaddr, offset, frames, words, verbose=False):
+ tile_name,
+ tile_db,
+ baseaddr,
+ offset,
+ frames,
+ words,
+ tile_frames,
+ verbose=False):
'''
Record data structure geometry for the given tile baseaddr
For most tiles there is only one baseaddr, but some like BRAM have multiple
@@ -45,6 +92,17 @@
bits = tile_db['bits']
block_type = util.addr2btype(baseaddr)
+ # Extract the information about the maximal number of frames from the part's json
+ max_frames = tile_frames.get_tile_frames(baseaddr)
+ if frames > max_frames:
+ print(
+ "Warning: The number of frames specified for the tile {} ({}) exceeds the maximum allowed value ({}). Falling back to the maximum value."
+ .format(tile_name, frames, max_frames))
+ frames = max_frames
+ # If frames count is None then use the maximum
+ if frames is None:
+ frames = max_frames
+
assert offset <= 100, (tile_name, offset)
# Few rare cases at X=0 for double width tiles split in half => small negative offset
assert offset >= 0 or "IOB" in tile_name, (