prjxray/fuzzers/005-tilegrid/generate.py

247 lines
8.1 KiB
Python

#!/usr/bin/env python3
import os, sys, json, re
#######################################
# Read
tiles = list()
site_baseaddr = dict()
tile_baseaddr = dict()
with open("tiles.txt") as f:
for line in f:
tiles.append(line.split())
for arg in sys.argv[1:]:
with open(arg) as f:
line = f.read().strip()
site = arg[7:-6]
frame = int(line[5:5 + 8], 16)
site_baseaddr[site] = "0x%08x" % (frame & ~0x7f)
#######################################
# Create initial database
database = dict()
segments = dict()
tiles_by_grid = dict()
for record in tiles:
tile_type, tile_name, grid_x, grid_y = record[0:4]
grid_x, grid_y = int(grid_x), int(grid_y)
tiles_by_grid[(grid_x, grid_y)] = tile_name
framebaseaddr = None
database[tile_name] = {
"type": tile_type,
"sites": dict(),
"grid_x": grid_x,
"grid_y": grid_y
}
if len(record) > 4:
for i in range(4, len(record), 2):
site_type, site_name = record[i:i + 2]
if site_name in site_baseaddr:
framebaseaddr = site_baseaddr[site_name]
database[tile_name]["sites"][site_name] = site_type
if framebaseaddr is not None:
tile_baseaddr[tile_name] = [framebaseaddr, 0]
#######################################
# Add Segments
for tile_name, tile_data in database.items():
tile_type = tile_data["type"]
grid_x = tile_data["grid_x"]
grid_y = tile_data["grid_y"]
if tile_type in ["CLBLL_L", "CLBLL_R", "CLBLM_L", "CLBLM_R"]:
if tile_type in ["CLBLL_L", "CLBLM_L"]:
int_tile_name = tiles_by_grid[(grid_x + 1, grid_y)]
else:
int_tile_name = tiles_by_grid[(grid_x - 1, grid_y)]
segment_name = "SEG_" + tile_name
segtype = tile_type.lower()
segments[segment_name] = dict()
segments[segment_name]["tiles"] = [
tile_name, int_tile_name
]
segments[segment_name]["type"] = segtype
segments[segment_name]["frames"] = 36
segments[segment_name]["words"] = 2
if tile_name in tile_baseaddr:
segments[segment_name]["baseaddr"] = tile_baseaddr[
tile_name]
database[tile_name]["segment"] = segment_name
database[int_tile_name]["segment"] = segment_name
if tile_type in ["HCLK_L", "HCLK_R"]:
segment_name = "SEG_" + tile_name
segtype = tile_type.lower()
segments[segment_name] = dict()
segments[segment_name]["tiles"] = [tile_name]
segments[segment_name]["type"] = segtype
segments[segment_name]["frames"] = 26
segments[segment_name]["words"] = 1
database[tile_name]["segment"] = segment_name
if tile_type in ["BRAM_L", "DSP_L", "BRAM_R", "DSP_R"]:
for k in range(5):
if tile_type in ["BRAM_L", "DSP_L"]:
interface_tile_name = tiles_by_grid[(grid_x + 1, grid_y - k)]
int_tile_name = tiles_by_grid[(grid_x + 2, grid_y - k)]
else:
interface_tile_name = tiles_by_grid[(grid_x - 1, grid_y - k)]
int_tile_name = tiles_by_grid[(grid_x - 2, grid_y - k)]
segment_name = "SEG_" + tile_name.replace("_", "%d_" % k, 1)
segtype = tile_type.lower().replace("_", "%d_" % k, 1)
segments[segment_name] = dict()
segments[segment_name]["type"] = segtype
segments[segment_name]["frames"] = 28
segments[segment_name]["words"] = 2
if k == 0:
segments[segment_name]["tiles"] = [
tile_name, interface_tile_name, int_tile_name
]
database[tile_name]["segment"] = segment_name
database[interface_tile_name][
"segment"] = segment_name
database[int_tile_name]["segment"] = segment_name
else:
segments[segment_name]["tiles"] = [
interface_tile_name, int_tile_name
]
database[interface_tile_name][
"segment"] = segment_name
database[int_tile_name]["segment"] = segment_name
#######################################
# Populate segment base addresses: L/R along INT column
for segment_name in segments.keys():
if "baseaddr" in segments[segment_name]:
framebase, wordbase = segments[segment_name]["baseaddr"]
inttile = [
tile for tile in segments[segment_name]["tiles"]
if database[tile]["type"] in ["INT_L", "INT_R"]
][0]
grid_x = database[inttile]["grid_x"]
grid_y = database[inttile]["grid_y"]
if database[inttile]["type"] == "INT_L":
grid_x += 1
framebase = "0x%08x" % (int(framebase, 16) + 0x80)
else:
grid_x -= 1
framebase = "0x%08x" % (int(framebase, 16) - 0x80)
if (grid_x, grid_y) not in tiles_by_grid:
continue
tile = tiles_by_grid[(grid_x, grid_y)]
if database[inttile]["type"] == "INT_L":
assert database[tile]["type"] == "INT_R"
elif database[inttile]["type"] == "INT_R":
assert database[tile]["type"] == "INT_L"
else:
assert 0
assert "segment" in database[tile]
seg = database[tile]["segment"]
if "baseaddr" in segments[seg]:
assert segments[seg]["baseaddr"] == [
framebase, wordbase
]
else:
segments[seg]["baseaddr"] = [framebase, wordbase]
#######################################
# Populate segment base addresses: Up along INT/HCLK columns
start_segments = list()
for segment_name in segments.keys():
if "baseaddr" in segments[segment_name]:
start_segments.append(segment_name)
for segment_name in start_segments:
framebase, wordbase = segments[segment_name]["baseaddr"]
inttile = [
tile for tile in segments[segment_name]["tiles"]
if database[tile]["type"] in ["INT_L", "INT_R"]
][0]
grid_x = database[inttile]["grid_x"]
grid_y = database[inttile]["grid_y"]
for i in range(50):
grid_y -= 1
if wordbase == 50:
wordbase += 1
else:
wordbase += 2
segname = database[tiles_by_grid[(grid_x, grid_y)]]["segment"]
segments[segname]["baseaddr"] = [framebase, wordbase]
#######################################
# Transfer segment data into tiles
for segment_name in segments.keys():
try:
baseaddr, offset = segments[segment_name]["baseaddr"]
except:
print('Failed on segment name %s' % segment_name)
raise
for tile_name in segments[segment_name]["tiles"]:
tile_type = database[tile_name]["type"]
if tile_type in ["CLBLL_L", "CLBLL_R", "CLBLM_L", "CLBLM_R", "INT_L",
"INT_R"]:
database[tile_name]["baseaddr"] = baseaddr
database[tile_name]["offset"] = offset
database[tile_name]["height"] = 2
elif tile_type in ["HCLK_L", "HCLK_R"]:
database[tile_name]["baseaddr"] = baseaddr
database[tile_name]["offset"] = offset
database[tile_name]["height"] = 1
elif tile_type in ["BRAM_L", "BRAM_R", "DSP_L", "DSP_R"]:
database[tile_name]["baseaddr"] = baseaddr
database[tile_name]["offset"] = offset
database[tile_name]["height"] = 10
elif tile_type in ["INT_INTERFACE_L", "INT_INTERFACE_R",
"BRAM_INT_INTERFACE_L", "BRAM_INT_INTERFACE_R"]:
continue
else:
# print(tile_type, offset)
assert False
# TODO: Migrate to new tilegrid format via library. This data is added for
# compability with unconverted tools. Update tools then remove this data from
# tilegrid.json.
for tiledata in database.values():
if "segment" in tiledata:
segment = tiledata["segment"]
tiledata["frames"] = segments[segment]["frames"]
tiledata["words"] = segments[segment]["words"]
tiledata["segment_type"] = segments[segment]["type"]
#######################################
# Write
print(json.dumps(database, sort_keys=True, indent="\t"))