tilegrid: merge in KR WIP IOB

Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
John McMaster 2018-12-03 17:49:08 -08:00
parent 621ad8a575
commit 49aa56712f
1 changed files with 142 additions and 99 deletions

View File

@ -56,8 +56,9 @@ def load_baseaddrs(deltas_fns):
# clb/design_SLICE_X10Y100.delta # clb/design_SLICE_X10Y100.delta
# site = arg[7:-6] # site = arg[7:-6]
site = re.match(r".*/design_(.*).delta", arg).group(1) site = re.match(r".*/design_(.*).delta", arg).group(1)
frame = int(line[5:5 + 8], 16) # +bit_00400026_100_02
# was "0x%08x" _, frame_str, _, _ = line.split('_')
frame = int(frame_str, 16)
site_baseaddr[site] = frame & ~0x7f site_baseaddr[site] = frame & ~0x7f
return site_baseaddr return site_baseaddr
@ -126,7 +127,6 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
Create segments data structure Create segments data structure
Indicates how tiles are related to bitstream locations Indicates how tiles are related to bitstream locations
Also modify database to annotate which segment the tiles belong to Also modify database to annotate which segment the tiles belong to
segments key examples: segments key examples:
SEG_CLBLM_R_X13Y72 SEG_CLBLM_R_X13Y72
SEG_BRAM3_L_X6Y85 SEG_BRAM3_L_X6Y85
@ -139,6 +139,22 @@ 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):
assert name not in segments
segment = segments.setdefault(name, {})
segment["tiles"] = tiles
segment["type"] = segtype
if baseaddr:
verbose and print(
'make_segment: %s baseaddr %s' % (
name,
baseaddr,
))
segment["baseaddr"] = baseaddr
for tile_name in tiles:
database[tile_name]["segment"] = name
def process_clb(): def process_clb():
if tile_type in ["CLBLL_L", "CLBLM_L"]: if tile_type in ["CLBLL_L", "CLBLM_L"]:
int_tile_name = tiles_by_grid[(grid_x + 1, grid_y)] int_tile_name = tiles_by_grid[(grid_x + 1, grid_y)]
@ -146,24 +162,51 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
int_tile_name = tiles_by_grid[(grid_x - 1, grid_y)] int_tile_name = tiles_by_grid[(grid_x - 1, grid_y)]
add_segment( add_segment(
database=database,
segments=segments,
name="SEG_" + tile_name, name="SEG_" + tile_name,
tiles=[tile_name, int_tile_name], tiles=[tile_name, int_tile_name],
segtype=tile_type.lower(), segtype=tile_type.lower(),
baseaddr=tile_baseaddrs.get(tile_name, None), baseaddr=tile_baseaddrs.get(tile_name, None))
verbose=verbose,
)
def process_hclk(): def process_hclk():
add_segment( add_segment(
database=database,
segments=segments,
name="SEG_" + tile_name, name="SEG_" + tile_name,
tiles=[tile_name], tiles=[tile_name],
segtype=tile_type.lower())
def process_iob2():
tiles = [tile_name]
if tile_type.startswith('LIOB'):
# Two INT_L's
tiles.append(tiles_by_grid[(grid_x + 4, grid_y)])
tiles.append(tiles_by_grid[(grid_x + 4, grid_y - 1)])
# One IO interface tile
tiles.append(tiles_by_grid[(grid_x + 1, grid_y)])
else:
# Two INT_R's
tiles.append(tiles_by_grid[(grid_x - 4, grid_y)])
tiles.append(tiles_by_grid[(grid_x - 4, grid_y - 1)])
# One IO interface tile
tiles.append(tiles_by_grid[(grid_x - 1, grid_y)])
add_segment(
name="SEG_" + tile_name,
tiles=tiles,
segtype=tile_type.lower(), segtype=tile_type.lower(),
verbose=verbose, baseaddr=tile_baseaddrs.get(tile_name, None))
)
def process_iob():
if tile_type.startswith('LIOB'):
int_tile_name = tiles_by_grid[(grid_x + 4, grid_y)]
io_interface_tile_name = tiles_by_grid[(grid_x + 1, grid_y)]
else:
int_tile_name = tiles_by_grid[(grid_x - 4, grid_y)]
io_interface_tile_name = tiles_by_grid[(grid_x - 1, grid_y)]
add_segment(
name="SEG_" + tile_name,
tiles=[tile_name, io_interface_tile_name, int_tile_name],
segtype=tile_type.lower(),
baseaddr=tile_baseaddrs.get(tile_name, None))
def process_bram_dsp(): def process_bram_dsp():
for k in range(5): for k in range(5):
@ -190,16 +233,12 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
baseaddr = None baseaddr = None
add_segment( add_segment(
database=database,
segments=segments,
# BRAM_L_X6Y70 => SEG_BRAM4_L_X6Y70 # BRAM_L_X6Y70 => SEG_BRAM4_L_X6Y70
name="SEG_" + tile_name.replace("_", "%d_" % k, 1), name="SEG_" + tile_name.replace("_", "%d_" % k, 1),
tiles=tiles, tiles=tiles,
# BRAM_L => bram4_l # BRAM_L => bram4_l
segtype=tile_type.lower().replace("_", "%d_" % k, 1), segtype=tile_type.lower().replace("_", "%d_" % k, 1),
baseaddr=baseaddr, baseaddr=baseaddr)
verbose=verbose,
)
def process_default(): def process_default():
#verbose and nolr(tile_type) not in ('VBRK', 'INT', 'NULL') and print('make_segment: drop %s' % (tile_type,)) #verbose and nolr(tile_type) not in ('VBRK', 'INT', 'NULL') and print('make_segment: drop %s' % (tile_type,))
@ -211,6 +250,10 @@ 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,
"RIOB33": process_iob2,
"LIOB33": process_iob2,
"RIOB33_SING": process_iob,
"LIOB33_SIGN": process_iob,
}.get(nolr(tile_type), process_default)() }.get(nolr(tile_type), process_default)()
return segments return segments
@ -218,12 +261,9 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
def get_inttile(database, segment): def get_inttile(database, segment):
'''Return interconnect tile for given segment''' '''Return interconnect tile for given segment'''
inttiles = [ return (
tile for tile in segment["tiles"] tile for tile in segment["tiles"]
if database[tile]["type"] in ["INT_L", "INT_R"] if database[tile]["type"] in ["INT_L", "INT_R"])
]
assert len(inttiles) == 1
return inttiles[0]
def get_bramtile(database, segment): def get_bramtile(database, segment):
@ -290,7 +330,7 @@ def seg_base_addr_lr_INT(database, segments, tiles_by_grid, verbose=False):
verbose and print(' Skip non CLB') verbose and print(' Skip non CLB')
continue continue
inttile = get_inttile(database, segment) for inttile in get_inttile(database, segment):
grid_x = database[inttile]["grid_x"] grid_x = database[inttile]["grid_x"]
grid_y = database[inttile]["grid_y"] grid_y = database[inttile]["grid_y"]
@ -317,11 +357,8 @@ def seg_base_addr_lr_INT(database, segments, tiles_by_grid, verbose=False):
else: else:
assert 0 assert 0
if 'segment' not in database[tile]: if "segment" not in database[tile]:
if database[tile]['type'] in ['T_TERM_INT']:
continue continue
create_segment_for_int_lr(
database, segments, tile, tiles_by_grid, verbose)
seg = database[tile]["segment"] seg = database[tile]["segment"]
@ -366,50 +403,46 @@ def seg_base_addr_up_INT(database, segments, tiles_by_grid, verbose=False):
Use it to locate in the grid, and find other segments related by tile offset Use it to locate in the grid, and find other segments related by tile offset
''' '''
inttile = get_inttile(database, src_segment) for inttile in get_inttile(database, src_segment):
verbose and print( verbose and print(
' up_INT CLK_IO_CLK: %s => inttile %s' % ' up_INT CLK_IO_CLK: %s => inttile %s' %
(src_segment_name, inttile)) (src_segment_name, inttile),
file=sys.stderr)
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 i in range(50):
grid_y -= 1 grid_y -= 1
if grid_y < 0: loc = (grid_x, grid_y)
break
dst_tile = database[tiles_by_grid[(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: if wordbase == 50:
wordbase += 1 wordbase += 1
else: else:
wordbase += 2 wordbase += 2
if 'segment' not in dst_tile:
if dst_tile['type'] in ['T_TERM_INT']:
continue
create_segment_for_int_lr(
database, segments, tiles_by_grid[(grid_x,
grid_y)],
tiles_by_grid, verbose)
#verbose and print(' dst_tile', dst_tile) #verbose and print(' dst_tile', dst_tile)
dst_segment_name = dst_tile["segment"] 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", {})[block_type] = [framebase, wordbase] "baseaddr",
{})[block_type] = [framebase, wordbase]
def process_BLOCK_RAM(wordbase): def process_BLOCK_RAM(wordbase):
''' '''
Lookup BRAM0 tile associated with this segment Lookup BRAM0 tile associated with this segment
Use it to locate in the grid, and find other BRAM0 related by tile offset Use it to locate in the grid, and find other BRAM0 related by tile offset
From minitest: From minitest:
build/roi_bramd_bit01.diff (lowest BRAM coordinate) build/roi_bramd_bit01.diff (lowest BRAM coordinate)
> bit_00c00000_000_00 > bit_00c00000_000_00
build/roi_bramds_bit01.diff build/roi_bramds_bit01.diff
> bit_00c00000_000_00 > bit_00c00000_000_00
> bit_00c00000_010_00 > bit_00c00000_010_00
@ -437,9 +470,6 @@ def seg_base_addr_up_INT(database, segments, tiles_by_grid, verbose=False):
grid_y -= 1 grid_y -= 1
wordbase += 1 wordbase += 1
if (grid_x, grid_y) not in tiles_by_grid:
continue
dst_tile = database[tiles_by_grid[(grid_x, grid_y)]] dst_tile = database[tiles_by_grid[(grid_x, grid_y)]]
assert nolr(dst_tile['type']) == 'BRAM', dst_tile assert nolr(dst_tile['type']) == 'BRAM', dst_tile
@ -459,7 +489,6 @@ def add_tile_bits(tile_db, baseaddr, offset, frames, words, height=None):
''' '''
Record data structure geometry for the given tile baseaddr Record data structure geometry for the given tile baseaddr
For most tiles there is only one baseaddr, but some like BRAM have multiple For most tiles there is only one baseaddr, but some like BRAM have multiple
Notes on multiple block types: Notes on multiple block types:
https://github.com/SymbiFlow/prjxray/issues/145 https://github.com/SymbiFlow/prjxray/issues/145
''' '''
@ -514,6 +543,20 @@ def db_add_bits(database, segments):
("DSP", "CLB_IO_CLK"): (28, 2, 10), ("DSP", "CLB_IO_CLK"): (28, 2, 10),
("INT_INTERFACE", "CLB_IO_CLK"): (28, 2, None), ("INT_INTERFACE", "CLB_IO_CLK"): (28, 2, None),
("BRAM_INT_INTERFACE", "CLB_IO_CLK"): (28, 2, None), ("BRAM_INT_INTERFACE", "CLB_IO_CLK"): (28, 2, None),
# TODO: These are all guesses copied from CLBLL.
("RIOI3", "CLB_IO_CLK"): (36, 2, 2),
("LIOI3", "CLB_IO_CLK"): (36, 2, 2),
("RIOI3_SING", "CLB_IO_CLK"): (36, 2, 2),
("LIOI3_SING", "CLB_IO_CLK"): (36, 2, 2),
("RIOI3_TBYTESRC", "CLB_IO_CLK"): (36, 2, 2),
("LIOI3_TBYTESRC", "CLB_IO_CLK"): (36, 2, 2),
("RIOI3_TBYTETERM", "CLB_IO_CLK"): (36, 2, 2),
("LIOI3_TBYTETERM", "CLB_IO_CLK"): (36, 2, 2),
("LIOB33", "CLB_IO_CLK"): (36, 2, 2),
("RIOB33", "CLB_IO_CLK"): (36, 2, 2),
("LIOB33", "CLB_IO_CLK"): (36, 2, 2),
("RIOB33_SING", "CLB_IO_CLK"): (36, 2, 2),
("LIOB33_SING", "CLB_IO_CLK"): (36, 2, 2),
}.get((nolr(tile_type), block_type), None) }.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