def propagate_XIPHY_bits_in_column(database, tiles_by_grid, tile_frames_map): xiphy_frames, xiphy_words = localutil.get_entry('XIPHY', 'CLB_IO_CLK') rclk_frames, rclk_words = localutil.get_entry('RCLK_INT_L', 'CLB_IO_CLK') _, ecc_words = localutil.get_entry('ECC', 'CLB_IO_CLK') for tile, tile_data in database.items(): if tile_data['type'] != 'RCLK_XIPHY_OUTER_RIGHT': continue above_tile = tiles_by_grid[tile_data['grid_x'], tile_data['grid_y'] - 1] below_tile = tiles_by_grid[tile_data['grid_x'], tile_data['grid_y'] + 15] assert database[above_tile]['type'] == 'XIPHY_BYTE_RIGHT' assert database[below_tile]['type'] == 'XIPHY_BYTE_RIGHT' baseaddr1 = int(database[above_tile]['bits']['CLB_IO_CLK']['baseaddr'], 0) offset1 = database[above_tile]['bits']['CLB_IO_CLK']['offset'] offset1 -= rclk_words localutil.add_tile_bits(tile, database[tile], baseaddr1, offset1, rclk_frames, rclk_words, tile_frames_map) baseaddr2 = int(database[below_tile]['bits']['CLB_IO_CLK']['baseaddr'], 0) offset2 = database[below_tile]['bits']['CLB_IO_CLK']['offset'] offset2 += xiphy_words offset2 += ecc_words localutil.add_tile_bits(tile, database[tile], baseaddr2, offset2, rclk_frames, rclk_words, tile_frames_map)
def run(fn_in, fn_out, verbose=False): database = json.load(open(fn_in, "r")) int_frames, int_words = localutil.get_entry('INT', 'CLB_IO_CLK') rclk_frames, rclk_words = localutil.get_entry('RCLK_INT_L', 'CLB_IO_CLK') ps8_intf_frames, ps8_intf_words = localutil.get_entry( "PS8_INTF", "CLB_IO_CLK") xiphy_frames, xiphy_words = localutil.get_entry("XIPHY", "CLB_IO_CLK") build_dir = "build_" + os.getenv('URAY_PART') tdb_fns = [ ("cle/" + build_dir + "/segbits_tilegrid.tdb", 16, 3), ("clem_r/" + build_dir + "/segbits_tilegrid.tdb", 16, 3), ("clel_int/" + build_dir + "/segbits_tilegrid.tdb", int_frames, int_words), ("clem_int/" + build_dir + "/segbits_tilegrid.tdb", int_frames, int_words), ("rclk_int/" + build_dir + "/segbits_tilegrid.tdb", rclk_frames, rclk_words), ("rclk_other/" + build_dir + "/segbits_tilegrid.tdb", rclk_frames, rclk_words), ("rclk_hdio/" + build_dir + "/segbits_tilegrid.tdb", rclk_frames, rclk_words), ("rclk_dsp_intf_clkbuf/" + build_dir + "/segbits_tilegrid.tdb", rclk_frames, rclk_words), ("rclk_pss_alto/" + build_dir + "/segbits_tilegrid.tdb", rclk_frames, rclk_words), ("intf_r_pcie4_hdio/" + build_dir + "/segbits_tilegrid.tdb", None, 3), ("ps8_intf/" + build_dir + "/segbits_tilegrid.tdb", ps8_intf_frames, ps8_intf_words), ("cmt_right/" + build_dir + "/segbits_tilegrid.tdb", None, 10), ("pss_alto/" + build_dir + "/segbits_tilegrid.tdb", None, 93 * 2), ("hdio_top_right/" + build_dir + "/segbits_tilegrid.tdb", None, 87), ("hdio_bot_right/" + build_dir + "/segbits_tilegrid.tdb", None, 87), ("hpio_right/" + build_dir + "/segbits_tilegrid.tdb", None, 85), ("bitslice_tiles/" + build_dir + "/segbits_tilegrid.tdb", xiphy_frames, xiphy_words), ("bram/" + build_dir + "/segbits_tilegrid.tdb", None, 15), ("bram_block/" + build_dir + "/segbits_tilegrid.tdb", None, 15), ] tile_frames_map = localutil.TileFrames() for (tdb_fn, frames, words) in tdb_fns: if not os.path.exists(tdb_fn): verbose and print('Skipping {}, file not found!'.format(tdb_fn)) continue 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, tile_frames_map) # Save json.dump(database, open(fn_out, "w"), sort_keys=True, indent=4, separators=(",", ": "))
def run(fn_in, fn_out, verbose=False): database = json.load(open(fn_in, "r")) # Load a map of sites to base addresses # Need to figure out the # FIXME: generate frames from part file (or equivilent) # See https://github.com/SymbiFlow/prjxray/issues/327 # FIXME: generate words from pitch int_frames, int_words = localutil.get_int_params() tdb_fns = [ ("iob", 42, 4), ("ioi", 42, 4), ("mmcm", 30, 49), ("pll", 30, 27), ("monitor", 30, 101), ("bram", 28, 10), ("bram_block", 128, 10), ("clb", 36, 2), ("cfg", 30, 101), ("dsp", 28, 10), ("clk_hrow", 30, 18), ("clk_bufg", 30, 8), ("hclk_cmt", 30, 10), ("hclk_ioi", 42, 1), ("pcie", 36, 101), ("gtp_common", 32, 101), ("gtp_channel", 32, 22), ("clb_int", int_frames, int_words), ("iob_int", int_frames, int_words), ("bram_int", int_frames, int_words), ("dsp_int", int_frames, int_words), ("fifo_int", int_frames, int_words), ("ps7_int", int_frames, int_words), ("cfg_int", int_frames, int_words), ("monitor_int", int_frames, int_words), ("orphan_int_column", int_frames, int_words), ("gtp_int_interface", int_frames, int_words), ("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']), 'segbits_tilegrid.tdb') if not os.path.exists(tdb_fn): verbose and print('Skipping {}, file not found!'.format(tdb_fn)) continue 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, tile_frames_map) # Save xjson.pprint(open(fn_out, "w"), database)
def run(fn_in, fn_out, verbose=False): database = json.load(open(fn_in, "r")) # Load a map of sites to base addresses # Need to figure out the # FIXME: generate frames from part file (or equivilent) # See https://github.com/SymbiFlow/prjxray/issues/327 # FIXME: generate words from pitch int_frames, int_words = localutil.get_int_params() tdb_fns = [ ("iob/build/segbits_tilegrid.tdb", 42, 4), ("ioi/build/segbits_tilegrid.tdb", 42, 4), ("mmcm/build/segbits_tilegrid.tdb", 30, 101), ("pll/build/segbits_tilegrid.tdb", 30, 26), ("monitor/build/segbits_tilegrid.tdb", 30, 101), ("bram/build/segbits_tilegrid.tdb", 28, 10), ("bram_block/build/segbits_tilegrid.tdb", 128, 10), ("clb/build/segbits_tilegrid.tdb", 36, 2), ("cfg/build/segbits_tilegrid.tdb", 30, 101), ("dsp/build/segbits_tilegrid.tdb", 28, 10), ("clk_hrow/build/segbits_tilegrid.tdb", 30, 18), ("clk_bufg/build/segbits_tilegrid.tdb", 30, 8), ("hclk_cmt/build/segbits_tilegrid.tdb", 30, 10), ("hclk_ioi/build/segbits_tilegrid.tdb", 42, 1), ("clb_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("iob_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("bram_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("dsp_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("fifo_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("ps7_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("cfg_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("monitor_int/build/segbits_tilegrid.tdb", int_frames, int_words), ("orphan_int_column/build/segbits_tilegrid.tdb", int_frames, int_words), ] for (tdb_fn, frames, words) in tdb_fns: if not os.path.exists(tdb_fn): verbose and print('Skipping {}, file not found!'.format(tdb_fn)) continue 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) # Save json.dump(database, open(fn_out, "w"), sort_keys=True, indent=4, separators=(",", ": "))
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') verbose and print('') for tile in database: if database[tile]["type"] not in ["INT_L", "INT_R"]: continue if not database[tile]["bits"]: continue grid_x = database[tile]["grid_x"] grid_y = database[tile]["grid_y"] baseaddr = int(database[tile]["bits"]["CLB_IO_CLK"]["baseaddr"], 0) offset = database[tile]["bits"]["CLB_IO_CLK"]["offset"] if database[tile]["type"] == "INT_L": grid_x += 1 baseaddr = baseaddr + 0x80 elif database[tile]["type"] == "INT_R": grid_x -= 1 baseaddr = baseaddr - 0x80 else: assert 0, database[tile]["type"] # ROI at edge? if (grid_x, grid_y) not in tiles_by_grid: verbose and print(' Skip edge') continue other_tile = tiles_by_grid[(grid_x, grid_y)] if database[tile]["type"] == "INT_L": assert database[other_tile]["type"] == "INT_R" elif database[tile]["type"] == "INT_R": assert database[other_tile]["type"] == "INT_L" else: assert 0 localutil.add_tile_bits(other_tile, database[other_tile], baseaddr, offset, int_frames, int_words, tile_frames_map)
def propagate_RCLK_bits_in_row(database, tiles_by_grid, tile_frames_map): """ Propigate base address to some RCLK tiles that are hard to get base addresses directly for. It appears that RCLK <-> RCLK base addresses can be predicted by the x coordinate in some cases, so depend on that assumption for now. """ rclk_frames, rclk_words = localutil.get_entry('RCLK_INT_L', 'CLB_IO_CLK') _, ecc_words = localutil.get_entry('ECC', 'CLB_IO_CLK') for tile_name in sorted(database.keys()): tile = database[tile_name] if tile['type'] != 'RCLK_AMS_CFGIO': continue if 'CLB_IO_CLK' in tile['bits']: continue dx = 1 while True: other_tile = database[tiles_by_grid[(tile['grid_x'] - dx, tile['grid_y'])]] if other_tile['type'].startswith( 'RCLK_') and 'CLB_IO_CLK' in other_tile['bits']: break dx += 1 baseaddr = int(other_tile['bits']['CLB_IO_CLK']['baseaddr'], 0) offset = other_tile['bits']['CLB_IO_CLK']['offset'] localutil.add_tile_bits(tile_name, database[tile_name], baseaddr + dx * 0x100, offset, rclk_frames, rclk_words, tile_frames_map)
def propagate_INT_bits_in_column(database, tiles_by_grid): """ 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 tile['type'] not in ['INT_L', 'INT_R']: continue l_or_r = tile['type'][-1] if not tile['bits']: continue if tile_name in seen_int: continue # Walk down INT column while True: seen_int.add(tile_name) next_tile = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 1)] next_tile_type = database[next_tile]['type'] if tile['bits']['CLB_IO_CLK']['offset'] == 0: assert next_tile_type in [ 'B_TERM_INT', 'BRKH_INT', 'BRKH_B_TERM_INT' ], next_tile_type break baseaddr = int(tile['bits']['CLB_IO_CLK']['baseaddr'], 0) offset = tile['bits']['CLB_IO_CLK']['offset'] if tile['type'].startswith( 'INT_') and next_tile_type == tile['type']: # INT next to INT offset -= int_words localutil.add_tile_bits( next_tile, database[next_tile], baseaddr, offset, int_frames, int_words) elif tile['type'].startswith('INT_'): # INT above HCLK assert next_tile_type.startswith( 'HCLK_{}'.format(l_or_r)), next_tile_type offset -= hclk_words localutil.add_tile_bits( next_tile, database[next_tile], baseaddr, offset, hclk_frames, hclk_words) else: # HCLK above INT assert tile['type'].startswith( 'HCLK_{}'.format(l_or_r)), tile['type'] if next_tile_type == 'INT_{}'.format(l_or_r): offset -= int_words localutil.add_tile_bits( next_tile, database[next_tile], baseaddr, offset, int_frames, int_words) else: # Handle special case column where the PCIE tile is present. assert next_tile_type in ['PCIE_NULL'], next_tile_type break tile_name = next_tile tile = database[tile_name] # Walk up INT column while True: seen_int.add(tile_name) next_tile = tiles_by_grid[(tile['grid_x'], tile['grid_y'] - 1)] next_tile_type = database[next_tile]['type'] if tile['bits']['CLB_IO_CLK']['offset'] == 99: assert next_tile_type in [ 'T_TERM_INT', 'BRKH_INT', 'BRKH_TERM_INT', 'BRKH_INT_PSS' ], next_tile_type break baseaddr = int(tile['bits']['CLB_IO_CLK']['baseaddr'], 0) offset = tile['bits']['CLB_IO_CLK']['offset'] if tile['type'].startswith( 'INT_') and next_tile_type == tile['type']: # INT next to INT offset += int_words localutil.add_tile_bits( next_tile, database[next_tile], baseaddr, offset, int_frames, int_words) elif tile['type'].startswith('INT_'): # INT below HCLK assert next_tile_type.startswith( 'HCLK_{}'.format(l_or_r)), next_tile_type offset += int_words localutil.add_tile_bits( next_tile, database[next_tile], baseaddr, offset, hclk_frames, hclk_words) else: # HCLK below INT assert tile['type'].startswith( 'HCLK_{}'.format(l_or_r)), tile['type'] assert next_tile_type == 'INT_{}'.format( l_or_r), next_tile_type offset += hclk_words localutil.add_tile_bits( next_tile, database[next_tile], baseaddr, offset, int_frames, int_words) tile_name = next_tile tile = database[tile_name]
def propagate_INT_INTERFACE_bits_in_column( database, tiles_by_grid, int_interface_name): """ Propagate INT_INTERFACE column for a given INT_INTERFACE tile name. 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() 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_bits_in_column(database, tiles_by_grid, tile_type, term_b, term_t, rbrk, rclk_types, tile_frames, tile_words, tile_frames_map): """ Propigate offsets up and down columns, based on a fixed pattern. """ rclk_frames, rclk_words = localutil.get_entry('RCLK_INT_L', 'CLB_IO_CLK') _, ecc_words = localutil.get_entry('ECC', 'CLB_IO_CLK') seen_int = set() for tile_name in sorted(database.keys()): tile = database[tile_name] if tile['type'] != tile_type: continue if not tile['bits']: continue if tile_name in seen_int: continue # Walk down column while True: seen_int.add(tile_name) next_tile = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 1)] next_tile_type = database[next_tile]['type'] if tile['bits']['CLB_IO_CLK']['offset'] == 0: assert next_tile_type in [term_b, rbrk], next_tile_type break baseaddr = int(tile['bits']['CLB_IO_CLK']['baseaddr'], 0) offset = tile['bits']['CLB_IO_CLK']['offset'] if tile['type'] == tile_type and next_tile_type == tile['type']: # INT next to INT offset -= tile_words localutil.add_tile_bits(next_tile, database[next_tile], baseaddr, offset, tile_frames, tile_words, tile_frames_map) elif tile['type'] == tile_type: # INT above RCLK assert next_tile_type in rclk_types, next_tile_type offset -= rclk_words localutil.add_tile_bits(next_tile, database[next_tile], baseaddr, offset, rclk_frames, rclk_words, tile_frames_map) offset -= ecc_words else: # RCLK above INT assert tile['type'] in rclk_types, tile['type'] if next_tile_type == tile_type: offset -= ecc_words offset -= tile_words localutil.add_tile_bits(next_tile, database[next_tile], baseaddr, offset, tile_frames, tile_words, tile_frames_map) else: assert next_tile_type in [], next_tile_type break tile_name = next_tile tile = database[tile_name] # Walk up INT column while True: seen_int.add(tile_name) next_tile = tiles_by_grid[(tile['grid_x'], tile['grid_y'] - 1)] next_tile_type = database[next_tile]['type'] if tile['bits']['CLB_IO_CLK']['offset'] == 183: assert next_tile_type in [term_t, rbrk], next_tile_type break baseaddr = int(tile['bits']['CLB_IO_CLK']['baseaddr'], 0) offset = tile['bits']['CLB_IO_CLK']['offset'] if tile['type'] == tile_type and next_tile_type == tile['type']: # INT next to INT offset += tile_words localutil.add_tile_bits(next_tile, database[next_tile], baseaddr, offset, tile_frames, tile_words, tile_frames_map) elif tile['type'] == tile_type: # INT below RCLK assert next_tile_type in rclk_types, next_tile_type offset += tile_words offset += ecc_words localutil.add_tile_bits(next_tile, database[next_tile], baseaddr, offset, rclk_frames, rclk_words, tile_frames_map) else: # RCLK below INT assert tile['type'] in rclk_types, tile['type'] assert next_tile_type == tile_type, next_tile_type offset += rclk_words localutil.add_tile_bits(next_tile, database[next_tile], baseaddr, offset, tile_frames, tile_words, tile_frames_map) tile_name = next_tile tile = database[tile_name]