diff --git a/fuzzers/005-tilegrid/add_tdb.py b/fuzzers/005-tilegrid/add_tdb.py index 9c4c4428..021f14f7 100644 --- a/fuzzers/005-tilegrid/add_tdb.py +++ b/fuzzers/005-tilegrid/add_tdb.py @@ -123,6 +123,7 @@ def run(fn_in, fn_out, verbose=False): ("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 @@ def run(fn_in, fn_out, verbose=False): 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 7492ea4e..4022edc0 100644 --- a/fuzzers/005-tilegrid/generate_full.py +++ b/fuzzers/005-tilegrid/generate_full.py @@ -49,7 +49,8 @@ def make_tiles_by_grid(database): 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 @@ def propagate_INT_lr_bits(database, tiles_by_grid, verbose=False): 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 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): 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 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): 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 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): 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 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): 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 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): 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 @@ def propagate_INT_bits_in_column(database, tiles_by_grid): 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 @@ def propagate_INT_INTERFACE_bits_in_column( 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 @@ def propagate_INT_INTERFACE_bits_in_column( 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 @@ def run(json_in_fn, json_out_fn, verbose=False): 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 421f7b3b..0f65e00a 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 get_int_params(): 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 @@ def add_tile_bits( 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, (