mirror of https://github.com/openXC7/prjxray.git
005-tilegrid/generate_full.py: post db fix
Added possibility to add INT baseaddresses which are not adjacent to any CLB/BRAM. The addition is performed after the database is populated with the 'segments' information. Signed-off-by: Alessandro Comodi <acomodi@antmicro.com>
This commit is contained in:
parent
9c93f89662
commit
dfdb23e177
|
|
@ -14,7 +14,6 @@ from generate import load_tiles
|
||||||
from prjxray import util
|
from prjxray import util
|
||||||
import util as localutil
|
import util as localutil
|
||||||
|
|
||||||
|
|
||||||
def nolr(tile_type):
|
def nolr(tile_type):
|
||||||
'''
|
'''
|
||||||
Remove _L or _R suffix tile_type suffix, if present
|
Remove _L or _R suffix tile_type suffix, if present
|
||||||
|
|
@ -44,10 +43,29 @@ def load_baseaddrs(deltas_fns):
|
||||||
return site_baseaddr
|
return site_baseaddr
|
||||||
|
|
||||||
|
|
||||||
|
def load_tdb_baseaddr(database, int_tdb, verbose=False):
|
||||||
|
tdb_tile_baseaddrs = dict()
|
||||||
|
for line in open(int_tdb, 'r'):
|
||||||
|
line = line.strip()
|
||||||
|
parts = line.split(' ')
|
||||||
|
# INT_L_X0Y50.DWORD:0.DBIT:17.DFRAME:14
|
||||||
|
tagstr = parts[0]
|
||||||
|
# 00000914_000_17 00000918_000_17 ...
|
||||||
|
addrlist = parts[1:]
|
||||||
|
localutil.check_frames(addrlist)
|
||||||
|
frame = localutil.parse_addr(addrlist[0], get_base_frame=True)
|
||||||
|
tparts = tagstr.split('.')
|
||||||
|
# INT_L_X0Y50
|
||||||
|
tile = tparts[0]
|
||||||
|
assert tile in database.keys(), "Tile not in Database"
|
||||||
|
localutil.add_baseaddr(tdb_tile_baseaddrs, tile, frame, verbose)
|
||||||
|
|
||||||
|
return tdb_tile_baseaddrs
|
||||||
|
|
||||||
|
|
||||||
def make_tile_baseaddrs(tiles, site_baseaddr, verbose=False):
|
def make_tile_baseaddrs(tiles, site_baseaddr, verbose=False):
|
||||||
# Look up a base address by tile name
|
# Look up a base address by tile name
|
||||||
tile_baseaddrs = dict()
|
tile_baseaddrs = dict()
|
||||||
|
|
||||||
verbose and print('')
|
verbose and print('')
|
||||||
verbose and print('%u tiles' % len(tiles))
|
verbose and print('%u tiles' % len(tiles))
|
||||||
verbose and print("%u baseaddrs" % len(site_baseaddr))
|
verbose and print("%u baseaddrs" % len(site_baseaddr))
|
||||||
|
|
@ -57,17 +75,7 @@ def make_tile_baseaddrs(tiles, site_baseaddr, verbose=False):
|
||||||
if site_name not in site_baseaddr:
|
if site_name not in site_baseaddr:
|
||||||
continue
|
continue
|
||||||
framebaseaddr = site_baseaddr[site_name]
|
framebaseaddr = site_baseaddr[site_name]
|
||||||
bt = util.addr2btype(framebaseaddr)
|
localutil.add_baseaddr(tile_baseaddrs, tile["name"], framebaseaddr, verbose)
|
||||||
tile_baseaddr = tile_baseaddrs.setdefault(tile["name"], {})
|
|
||||||
if bt in tile_baseaddr:
|
|
||||||
# actually lets just fail these, better to remove at tcl level to speed up processing
|
|
||||||
assert 0, 'duplicate base address'
|
|
||||||
assert tile_baseaddr[bt] == [framebaseaddr, 0]
|
|
||||||
else:
|
|
||||||
tile_baseaddr[bt] = [framebaseaddr, 0]
|
|
||||||
verbose and print(
|
|
||||||
"baseaddr: %s.%s @ %s.0x%08x" %
|
|
||||||
(tile["name"], site_name, bt, framebaseaddr))
|
|
||||||
added += 1
|
added += 1
|
||||||
|
|
||||||
assert added, "Failed to add any base addresses"
|
assert added, "Failed to add any base addresses"
|
||||||
|
|
@ -119,7 +127,7 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
|
||||||
grid_x = tile_data["grid_x"]
|
grid_x = tile_data["grid_x"]
|
||||||
grid_y = tile_data["grid_y"]
|
grid_y = tile_data["grid_y"]
|
||||||
|
|
||||||
def add_segment(name, tiles, segtype, baseaddr=None):
|
def add_segment(tiles, segtype, name=None, baseaddr=None):
|
||||||
assert name not in segments
|
assert name not in segments
|
||||||
segment = segments.setdefault(name, {})
|
segment = segments.setdefault(name, {})
|
||||||
segment["tiles"] = tiles
|
segment["tiles"] = tiles
|
||||||
|
|
@ -225,11 +233,6 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
|
||||||
segtype=tile_type.lower().replace("_", "%d_" % k, 1),
|
segtype=tile_type.lower().replace("_", "%d_" % k, 1),
|
||||||
baseaddr=baseaddr)
|
baseaddr=baseaddr)
|
||||||
|
|
||||||
def process_int():
|
|
||||||
assert "INT" in tile_type, "Tile is not of type INT_L/R"
|
|
||||||
create_segment_for_int_lr(
|
|
||||||
database, segments, tile_name, tiles_by_grid, verbose)
|
|
||||||
|
|
||||||
def process_default():
|
def process_default():
|
||||||
verbose and nolr(tile_type) not in (
|
verbose and nolr(tile_type) not in (
|
||||||
'VBRK', 'INT', 'NULL') and print(
|
'VBRK', 'INT', 'NULL') and print(
|
||||||
|
|
@ -249,7 +252,6 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
|
||||||
"HCLK": process_hclk,
|
"HCLK": process_hclk,
|
||||||
"BRAM": process_bram_dsp,
|
"BRAM": process_bram_dsp,
|
||||||
"DSP": process_bram_dsp,
|
"DSP": process_bram_dsp,
|
||||||
"INT": process_int,
|
|
||||||
}.get(nolr(tile_type), process_default)()
|
}.get(nolr(tile_type), process_default)()
|
||||||
|
|
||||||
return segments
|
return segments
|
||||||
|
|
@ -307,7 +309,6 @@ def create_segment_for_int_lr(
|
||||||
verbose=verbose,
|
verbose=verbose,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def seg_base_addr_lr_INT(database, segments, tiles_by_grid, verbose=False):
|
def seg_base_addr_lr_INT(database, segments, tiles_by_grid, verbose=False):
|
||||||
'''Populate segment base addresses: L/R along INT column'''
|
'''Populate segment base addresses: L/R along INT column'''
|
||||||
'''
|
'''
|
||||||
|
|
@ -412,26 +413,12 @@ def seg_base_addr_up_INT(database, segments, tiles_by_grid, verbose=False):
|
||||||
grid_x = database[inttile]["grid_x"]
|
grid_x = database[inttile]["grid_x"]
|
||||||
grid_y = database[inttile]["grid_y"]
|
grid_y = database[inttile]["grid_y"]
|
||||||
|
|
||||||
for i in range(50):
|
for dst_tile, wordbase in localutil.propagate_up_INT(grid_x, grid_y, database, tiles_by_grid, wordbase):
|
||||||
grid_y -= 1
|
assert 'segment' in dst_tile, ((grid_x, grid_y), dst_tile, tiles_by_grid[(grid_x, grid_y)])
|
||||||
loc = (grid_x, grid_y)
|
|
||||||
|
|
||||||
if loc not in tiles_by_grid:
|
|
||||||
continue
|
|
||||||
|
|
||||||
dst_tile = database[tiles_by_grid[loc]]
|
|
||||||
|
|
||||||
if 'segment' not in dst_tile:
|
|
||||||
continue
|
|
||||||
#assert 'segment' in dst_tile, ((grid_x, grid_y), dst_tile, tiles_by_grid[(grid_x, grid_y)])
|
|
||||||
|
|
||||||
if wordbase == 50:
|
|
||||||
wordbase += 1
|
|
||||||
else:
|
|
||||||
wordbase += 2
|
|
||||||
|
|
||||||
#verbose and print(' dst_tile', dst_tile)
|
#verbose and print(' dst_tile', dst_tile)
|
||||||
dst_segment_name = dst_tile["segment"]
|
if 'segment' in dst_tile:
|
||||||
|
dst_segment_name = dst_tile["segment"]
|
||||||
#verbose and print('up_INT: %s => %s' % (src_segment_name, dst_segment_name))
|
#verbose and print('up_INT: %s => %s' % (src_segment_name, dst_segment_name))
|
||||||
segments[dst_segment_name].setdefault(
|
segments[dst_segment_name].setdefault(
|
||||||
"baseaddr",
|
"baseaddr",
|
||||||
|
|
@ -503,52 +490,8 @@ def db_add_bits(database, segments):
|
||||||
offset) in segments[segment_name]["baseaddr"].items():
|
offset) in segments[segment_name]["baseaddr"].items():
|
||||||
for tile_name in segments[segment_name]["tiles"]:
|
for tile_name in segments[segment_name]["tiles"]:
|
||||||
tile_type = database[tile_name]["type"]
|
tile_type = database[tile_name]["type"]
|
||||||
"""
|
|
||||||
FIXME: review IOB
|
|
||||||
# IOB
|
|
||||||
# design_IOB_X0Y100.delta:+bit_00020027_000_29
|
|
||||||
# design_IOB_X0Y104.delta:+bit_00020027_008_29
|
|
||||||
# design_IOB_X0Y112.delta:+bit_00020027_024_29
|
|
||||||
# design_IOB_X0Y120.delta:+bit_00020027_040_29
|
|
||||||
# design_IOB_X0Y128.delta:+bit_00020027_057_29
|
|
||||||
# design_IOB_X0Y136.delta:+bit_00020027_073_29
|
|
||||||
# design_IOB_X0Y144.delta:+bit_00020027_089_29
|
|
||||||
# $XRAY_BLOCKWIDTH design_IOB_X0Y100.bit |grep 00020000
|
|
||||||
# 0x00020000: 0x2A (42)
|
|
||||||
("RIOI3", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("LIOI3", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("RIOI3_SING", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("LIOI3_SING", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("RIOI3_TBYTESRC", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("LIOI3_TBYTESRC", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("RIOI3_TBYTETERM", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("LIOI3_TBYTETERM", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("LIOB33", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("RIOB33", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("LIOB33", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("RIOB33_SING", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
("LIOB33_SING", "CLB_IO_CLK"): (42, 2, 4),
|
|
||||||
"""
|
|
||||||
|
|
||||||
is_not_segint = "SEG_INT" not in segment_name
|
entry = localutil.get_entry(nolr(tile_type), block_type)
|
||||||
|
|
||||||
if is_not_segint:
|
|
||||||
entry = {
|
|
||||||
# (tile_type, block_type): (frames, words, height)
|
|
||||||
("CLBLL", "CLB_IO_CLK"): (36, 2, 2),
|
|
||||||
("CLBLM", "CLB_IO_CLK"): (36, 2, 2),
|
|
||||||
("HCLK", "CLB_IO_CLK"): (26, 1, 1),
|
|
||||||
("INT", "CLB_IO_CLK"): (28, 2, 2),
|
|
||||||
("BRAM", "CLB_IO_CLK"): (28, 10, None),
|
|
||||||
("BRAM", "BLOCK_RAM"): (128, 10, None),
|
|
||||||
("DSP", "CLB_IO_CLK"): (28, 2, 10),
|
|
||||||
("INT_INTERFACE", "CLB_IO_CLK"): (28, 2, None),
|
|
||||||
("BRAM_INT_INTERFACE", "CLB_IO_CLK"): (28, 2, None),
|
|
||||||
}.get((nolr(tile_type), block_type), None)
|
|
||||||
else:
|
|
||||||
entry = {
|
|
||||||
("INT", "CLB_IO_CLK"): (36, 2, 2),
|
|
||||||
}.get((nolr(tile_type), block_type), None)
|
|
||||||
|
|
||||||
if entry is None:
|
if entry is None:
|
||||||
# Other types are rare, not expected to have these
|
# Other types are rare, not expected to have these
|
||||||
|
|
@ -576,11 +519,30 @@ def db_add_segments(database, segments):
|
||||||
tiledata["segment_type"] = segments[segment]["type"]
|
tiledata["segment_type"] = segments[segment]["type"]
|
||||||
|
|
||||||
|
|
||||||
def run(json_in_fn, json_out_fn, tiles_fn, deltas_fns, verbose=False):
|
def db_int_fixup(database, tiles, tiles_by_grid):
|
||||||
|
for tile_name in tiles.keys():
|
||||||
|
tiles_to_add = dict()
|
||||||
|
|
||||||
|
tile = database[tile_name]
|
||||||
|
grid_x = tile["grid_x"]
|
||||||
|
grid_y = tile["grid_y"]
|
||||||
|
|
||||||
|
tile_type = tile["type"]
|
||||||
|
|
||||||
|
block_type, (baseaddr, offset) = sorted(tiles[tile_name].items())[0]
|
||||||
|
|
||||||
|
frames, words, height = localutil.get_entry(nolr(tile_type), block_type)
|
||||||
|
# Adding first bottom INT tile
|
||||||
|
localutil.add_tile_bits(tile_name, tile, baseaddr, offset, frames, words, height)
|
||||||
|
|
||||||
|
for tile, offset in localutil.propagate_up_INT(grid_x, grid_y, database, tiles_by_grid, offset):
|
||||||
|
localutil.add_tile_bits(tile_name, tile, baseaddr, offset, frames, words, height)
|
||||||
|
|
||||||
|
|
||||||
|
def run(json_in_fn, json_out_fn, tiles_fn, deltas_fns, int_tdb, verbose=False):
|
||||||
# Load input files
|
# Load input files
|
||||||
tiles = load_tiles(tiles_fn)
|
tiles = load_tiles(tiles_fn)
|
||||||
site_baseaddr = load_baseaddrs(deltas_fns)
|
site_baseaddr = load_baseaddrs(deltas_fns)
|
||||||
|
|
||||||
database = json.load(open(json_in_fn, "r"))
|
database = json.load(open(json_in_fn, "r"))
|
||||||
|
|
||||||
tile_baseaddrs = make_tile_baseaddrs(tiles, site_baseaddr, verbose=verbose)
|
tile_baseaddrs = make_tile_baseaddrs(tiles, site_baseaddr, verbose=verbose)
|
||||||
|
|
@ -596,6 +558,9 @@ def run(json_in_fn, json_out_fn, tiles_fn, deltas_fns, verbose=False):
|
||||||
db_add_bits(database, segments)
|
db_add_bits(database, segments)
|
||||||
db_add_segments(database, segments)
|
db_add_segments(database, segments)
|
||||||
|
|
||||||
|
tile_baseaddrs_fixup = load_tdb_baseaddr(database, int_tdb)
|
||||||
|
db_int_fixup(database, tile_baseaddrs_fixup, tiles_by_grid)
|
||||||
|
|
||||||
# Save
|
# Save
|
||||||
json.dump(
|
json.dump(
|
||||||
database,
|
database,
|
||||||
|
|
@ -623,13 +588,15 @@ def main():
|
||||||
'--tiles', default='tiles.txt', help='Input tiles.txt tcl output')
|
'--tiles', default='tiles.txt', help='Input tiles.txt tcl output')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"deltas", nargs="*", help=".bit diffs to create base addresses from")
|
"deltas", nargs="*", help=".bit diffs to create base addresses from")
|
||||||
|
parser.add_argument(
|
||||||
|
"--int-tdb", help=".tdb diffs to fill the interconnects without any adjacent CLB")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
deltas = args.deltas
|
deltas = args.deltas
|
||||||
if not args.deltas:
|
if not args.deltas:
|
||||||
deltas = glob.glob("*.delta")
|
deltas = glob.glob("*.delta")
|
||||||
|
|
||||||
run(args.json_in, args.json_out, args.tiles, deltas, verbose=args.verbose)
|
run(args.json_in, args.json_out, args.tiles, deltas, args.int_tdb, verbose=args.verbose)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue