mirror of https://github.com/openXC7/prjxray.git
Add back INT propagation.
All INT tiles are now populated for artix7 and the INT propagation sanity checks output of fuzzers to ensure consistency. Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
3a4fc5eedc
commit
da08dfb99f
|
|
@ -13,6 +13,7 @@ TILEGRID_TDB_DEPENDENCIES += clb/build/segbits_tilegrid.tdb
|
||||||
TILEGRID_TDB_DEPENDENCIES += clb_int/build/segbits_tilegrid.tdb
|
TILEGRID_TDB_DEPENDENCIES += clb_int/build/segbits_tilegrid.tdb
|
||||||
TILEGRID_TDB_DEPENDENCIES += dsp/build/segbits_tilegrid.tdb
|
TILEGRID_TDB_DEPENDENCIES += dsp/build/segbits_tilegrid.tdb
|
||||||
TILEGRID_TDB_DEPENDENCIES += dsp_int/build/segbits_tilegrid.tdb
|
TILEGRID_TDB_DEPENDENCIES += dsp_int/build/segbits_tilegrid.tdb
|
||||||
|
TILEGRID_TDB_DEPENDENCIES += fifo_int/build/segbits_tilegrid.tdb
|
||||||
GENERATE_FULL_ARGS=
|
GENERATE_FULL_ARGS=
|
||||||
|
|
||||||
ifeq (${XRAY_DATABASE}, zynq7)
|
ifeq (${XRAY_DATABASE}, zynq7)
|
||||||
|
|
@ -73,6 +74,9 @@ dsp/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||||
dsp_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
dsp_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||||
cd dsp_int && $(MAKE)
|
cd dsp_int && $(MAKE)
|
||||||
|
|
||||||
|
fifo_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||||
|
cd fifo_int && $(MAKE)
|
||||||
|
|
||||||
build/tilegrid_tdb.json: add_tdb.py $(TILEGRID_TDB_DEPENDENCIES)
|
build/tilegrid_tdb.json: add_tdb.py $(TILEGRID_TDB_DEPENDENCIES)
|
||||||
python3 add_tdb.py \
|
python3 add_tdb.py \
|
||||||
--fn-in build/basicdb/tilegrid.json \
|
--fn-in build/basicdb/tilegrid.json \
|
||||||
|
|
@ -102,6 +106,7 @@ clean:
|
||||||
cd bram_int && $(MAKE) clean
|
cd bram_int && $(MAKE) clean
|
||||||
cd dsp && $(MAKE) clean
|
cd dsp && $(MAKE) clean
|
||||||
cd dsp_int && $(MAKE) clean
|
cd dsp_int && $(MAKE) clean
|
||||||
|
cd fifo_int && $(MAKE) clean
|
||||||
cd monitor && $(MAKE) clean
|
cd monitor && $(MAKE) clean
|
||||||
|
|
||||||
.PHONY: database pushdb clean run
|
.PHONY: database pushdb clean run
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ def run(fn_in, fn_out, verbose=False):
|
||||||
("iob_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),
|
("bram_int/build/segbits_tilegrid.tdb", int_frames, int_words),
|
||||||
("dsp_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),
|
||||||
]
|
]
|
||||||
|
|
||||||
for (tdb_fn, frames, words) in tdb_fns:
|
for (tdb_fn, frames, words) in tdb_fns:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
N ?= 16
|
N ?= 16
|
||||||
GENERATE_ARGS?="--oneval 0 --design params.csv --dword 1 --dframe 15"
|
GENERATE_ARGS?="--oneval 0 --design params.csv --dword 0 --dframe 15"
|
||||||
include ../fuzzaddr/common.mk
|
include ../fuzzaddr/common.mk
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,15 +23,14 @@ def gen_fifos():
|
||||||
int_tile_type = 'INT_R'
|
int_tile_type = 'INT_R'
|
||||||
|
|
||||||
int_tile_locs = [
|
int_tile_locs = [
|
||||||
(int_grid_x, loc.grid_y+idx-5) for idx in range(12)
|
(int_grid_x, loc.grid_y + idx - 5) for idx in range(12)
|
||||||
]
|
]
|
||||||
|
|
||||||
int_tiles = []
|
int_tiles = []
|
||||||
for int_tile_loc in int_tile_locs:
|
for int_tile_loc in int_tile_locs:
|
||||||
int_gridinfo = grid.gridinfo_at_loc(int_tile_loc)
|
int_gridinfo = grid.gridinfo_at_loc(int_tile_loc)
|
||||||
assert int_gridinfo.tile_type == int_tile_type, (
|
assert int_gridinfo.tile_type == int_tile_type, (
|
||||||
int_tile_loc,
|
int_tile_loc, int_gridinfo.tile_type, int_tile_type)
|
||||||
int_gridinfo.tile_type, int_tile_type)
|
|
||||||
|
|
||||||
int_tiles.append(grid.tilename_at_loc(int_tile_loc))
|
int_tiles.append(grid.tilename_at_loc(int_tile_loc))
|
||||||
|
|
||||||
|
|
@ -68,11 +67,11 @@ module top();
|
||||||
#
|
#
|
||||||
# INT[idx].IMUX_L40 = IN.D{idx}[1]
|
# INT[idx].IMUX_L40 = IN.D{idx}[1]
|
||||||
# INT[idx].IMUX_L42 = IN.D{idx}[3]
|
# INT[idx].IMUX_L42 = IN.D{idx}[3]
|
||||||
CHANNEL = [0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9]
|
CHANNEL = [0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 8, 9]
|
||||||
HOLD_BIT_0 = [1, 1, 1, 1, 1, 1, 5, 5, 1, 1, 1, 1]
|
HOLD_BIT_0 = [1, 1, 1, 1, 1, 1, 5, 5, 1, 1, 1, 1]
|
||||||
TOGGLE_BIT = [3, 3, 3, 3, 3, 3, 7, 7, 3, 3, 3, 3]
|
TOGGLE_BIT = [3, 3, 3, 3, 3, 3, 7, 7, 3, 3, 3, 3]
|
||||||
# 0 1 2 3 4 5 6 7 8 9
|
# 0 1 2 3 4 5 6 7 8 9
|
||||||
WIDTH = [4, 4, 4, 4, 4, 8, 8, 4, 4, 4]
|
WIDTH = [4, 4, 4, 4, 4, 8, 8, 4, 4, 4]
|
||||||
|
|
||||||
bits_set = set()
|
bits_set = set()
|
||||||
|
|
||||||
|
|
@ -81,29 +80,33 @@ module top();
|
||||||
bits_set.add((CHANNEL[idx], TOGGLE_BIT[idx]))
|
bits_set.add((CHANNEL[idx], TOGGLE_BIT[idx]))
|
||||||
|
|
||||||
assigns.append(' // {}'.format(int_tile))
|
assigns.append(' // {}'.format(int_tile))
|
||||||
assigns.append(' assign {site}_in_d{channel}[{bit}] = 0;'.format(
|
assigns.append(
|
||||||
site=site,
|
' assign {site}_in_d{channel}[{bit}] = 0;'.format(
|
||||||
channel=CHANNEL[idx],
|
site=site,
|
||||||
bit=HOLD_BIT_0[idx],
|
channel=CHANNEL[idx],
|
||||||
|
bit=HOLD_BIT_0[idx],
|
||||||
))
|
))
|
||||||
assigns.append(' assign {site}_in_d{channel}[{bit}] = {toggle_bit};'.format(
|
assigns.append(
|
||||||
site=site,
|
' assign {site}_in_d{channel}[{bit}] = {toggle_bit};'
|
||||||
channel=CHANNEL[idx],
|
.format(
|
||||||
bit=TOGGLE_BIT[idx],
|
site=site,
|
||||||
toggle_bit=bit,
|
channel=CHANNEL[idx],
|
||||||
|
bit=TOGGLE_BIT[idx],
|
||||||
|
toggle_bit=bit,
|
||||||
))
|
))
|
||||||
params[int_tile] = (bit,)
|
params[int_tile] = (bit, )
|
||||||
|
|
||||||
assigns.append('')
|
assigns.append('')
|
||||||
|
|
||||||
|
|
||||||
for channel, width in enumerate(WIDTH):
|
for channel, width in enumerate(WIDTH):
|
||||||
for bit in range(width):
|
for bit in range(width):
|
||||||
if (channel, bit) not in bits_set:
|
if (channel, bit) not in bits_set:
|
||||||
assigns.append(' assign {site}_in_d{channel}[{bit}] = 1;'.format(
|
assigns.append(
|
||||||
site=site,
|
' assign {site}_in_d{channel}[{bit}] = 1;'.
|
||||||
channel=channel,
|
format(
|
||||||
bit=bit,
|
site=site,
|
||||||
|
channel=channel,
|
||||||
|
bit=bit,
|
||||||
))
|
))
|
||||||
|
|
||||||
print(
|
print(
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import sys, json
|
import json
|
||||||
from utils import xjson
|
from utils import xjson
|
||||||
'''
|
'''
|
||||||
Historically we grouped data into "segments"
|
Historically we grouped data into "segments"
|
||||||
|
|
@ -12,7 +12,6 @@ Decoding was then shifted to instead describe how each title is encoded
|
||||||
A post processing step verifies that two tiles don't reference the same bitstream area
|
A post processing step verifies that two tiles don't reference the same bitstream area
|
||||||
'''
|
'''
|
||||||
|
|
||||||
from generate import load_tiles
|
|
||||||
import util as localutil
|
import util as localutil
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -60,109 +59,10 @@ def make_tiles_by_grid(database):
|
||||||
return tiles_by_grid
|
return tiles_by_grid
|
||||||
|
|
||||||
|
|
||||||
def add_int_bits(database, tile, baseaddr, offset):
|
def propagate_INT_lr_bits(database, tiles_by_grid, verbose=False):
|
||||||
"""
|
|
||||||
Add INT bits for given tile.
|
|
||||||
"""
|
|
||||||
if database[tile]['type'] not in ["INT_L", "INT_R"]:
|
|
||||||
return
|
|
||||||
|
|
||||||
localutil.add_tile_bits(
|
|
||||||
tile, database[tile], baseaddr, offset, frames=28, words=2, height=2)
|
|
||||||
|
|
||||||
|
|
||||||
def add_adjacent_int_tiles(database, tiles_by_grid, verbose=False):
|
|
||||||
'''
|
|
||||||
Attaches INT tiles adjacent to tiles.
|
|
||||||
'''
|
|
||||||
|
|
||||||
def add_int_tile(inttile, parent_tile):
|
|
||||||
if not database[parent_tile]['bits']:
|
|
||||||
return
|
|
||||||
|
|
||||||
grid_x = database[inttile]["grid_x"]
|
|
||||||
grid_y = database[inttile]["grid_y"]
|
|
||||||
|
|
||||||
framebase = int(
|
|
||||||
database[parent_tile]['bits']['CLB_IO_CLK']['baseaddr'], 0)
|
|
||||||
parent_wordbase = database[parent_tile]['bits']['CLB_IO_CLK']['offset']
|
|
||||||
|
|
||||||
for dst_tile, wordbase in localutil.propagate_up_INT(
|
|
||||||
grid_x, grid_y, database, tiles_by_grid, parent_wordbase):
|
|
||||||
dst_x = dst_tile['grid_x']
|
|
||||||
dst_y = dst_tile['grid_y']
|
|
||||||
|
|
||||||
add_int_bits(
|
|
||||||
database, tiles_by_grid[(dst_x, dst_y)], framebase, wordbase)
|
|
||||||
|
|
||||||
verbose and print('')
|
|
||||||
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"]
|
|
||||||
|
|
||||||
def process_clb():
|
|
||||||
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)]
|
|
||||||
|
|
||||||
add_int_tile(int_tile_name, tile_name)
|
|
||||||
|
|
||||||
def process_iob():
|
|
||||||
if tile_type.startswith('LIOB'):
|
|
||||||
# Two INT_L's
|
|
||||||
#add_int_tile(tiles_by_grid[(grid_x + 4, grid_y)], tile_name)
|
|
||||||
#add_int_tile(tiles_by_grid[(grid_x + 4, grid_y - 1)], tile_name)
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# Two INT_R's
|
|
||||||
#add_int_tile(tiles_by_grid[(grid_x - 4, grid_y)], tile_name)
|
|
||||||
#add_int_tile(tiles_by_grid[(grid_x - 4, grid_y - 1)], tile_name)
|
|
||||||
pass
|
|
||||||
|
|
||||||
def process_iob_sing():
|
|
||||||
if tile_type.startswith('LIOB'):
|
|
||||||
add_int_tile(tiles_by_grid[(grid_x + 4, grid_y)], tile_name)
|
|
||||||
else:
|
|
||||||
add_int_tile(tiles_by_grid[(grid_x - 4, grid_y)], tile_name)
|
|
||||||
|
|
||||||
def process_bram_dsp():
|
|
||||||
for k in range(5):
|
|
||||||
if tile_type in ["BRAM_L", "DSP_L"]:
|
|
||||||
int_tile_name = tiles_by_grid[(grid_x + 2, grid_y - k)]
|
|
||||||
elif tile_type in ["BRAM_R", "DSP_R"]:
|
|
||||||
int_tile_name = tiles_by_grid[(grid_x - 2, grid_y - k)]
|
|
||||||
else:
|
|
||||||
assert 0
|
|
||||||
|
|
||||||
add_int_tile(int_tile_name, tile_name)
|
|
||||||
|
|
||||||
def process_default():
|
|
||||||
verbose and nolr(tile_type) not in (
|
|
||||||
'VBRK', 'INT', 'NULL') and print(
|
|
||||||
'make_segment: drop %s' % (tile_type, ))
|
|
||||||
pass
|
|
||||||
|
|
||||||
{
|
|
||||||
"CLBLL": process_clb,
|
|
||||||
"CLBLM": process_clb,
|
|
||||||
"HCLK": lambda: None,
|
|
||||||
"BRAM": lambda: None,
|
|
||||||
"DSP": lambda: None,
|
|
||||||
"RIOB33": process_iob,
|
|
||||||
"LIOB33": process_iob,
|
|
||||||
"RIOB33_SING": process_iob_sing,
|
|
||||||
"LIOB33_SING": process_iob_sing,
|
|
||||||
}.get(nolr(tile_type), process_default)()
|
|
||||||
|
|
||||||
|
|
||||||
def seg_base_addr_lr_INT(database, tiles_by_grid, verbose=False):
|
|
||||||
'''Populate segment base addresses: L/R along INT column'''
|
'''Populate segment base addresses: L/R along INT column'''
|
||||||
'''
|
|
||||||
Create BRAM base addresses based on nearby CLBs
|
int_frames, int_words, _ = localutil.get_entry('INT', 'CLB_IO_CLK')
|
||||||
ie if we have a BRAM_L, compute as nearby CLB_R base address + offset
|
|
||||||
'''
|
|
||||||
|
|
||||||
verbose and print('')
|
verbose and print('')
|
||||||
for tile in database:
|
for tile in database:
|
||||||
|
|
@ -174,17 +74,17 @@ def seg_base_addr_lr_INT(database, tiles_by_grid, verbose=False):
|
||||||
|
|
||||||
grid_x = database[tile]["grid_x"]
|
grid_x = database[tile]["grid_x"]
|
||||||
grid_y = database[tile]["grid_y"]
|
grid_y = database[tile]["grid_y"]
|
||||||
framebase = int(database[tile]["bits"]["CLB_IO_CLK"]["baseaddr"], 0)
|
baseaddr = int(database[tile]["bits"]["CLB_IO_CLK"]["baseaddr"], 0)
|
||||||
wordbase = database[tile]["bits"]["CLB_IO_CLK"]["offset"]
|
offset = database[tile]["bits"]["CLB_IO_CLK"]["offset"]
|
||||||
|
|
||||||
if database[tile]["type"] == "INT_L":
|
if database[tile]["type"] == "INT_L":
|
||||||
grid_x += 1
|
grid_x += 1
|
||||||
framebase = framebase + 0x80
|
baseaddr = baseaddr + 0x80
|
||||||
elif database[tile]["type"] == "INT_R":
|
elif database[tile]["type"] == "INT_R":
|
||||||
grid_x -= 1
|
grid_x -= 1
|
||||||
framebase = framebase - 0x80
|
baseaddr = baseaddr - 0x80
|
||||||
else:
|
else:
|
||||||
assert 0
|
assert 0, database[tile]["type"]
|
||||||
|
|
||||||
# ROI at edge?
|
# ROI at edge?
|
||||||
if (grid_x, grid_y) not in tiles_by_grid:
|
if (grid_x, grid_y) not in tiles_by_grid:
|
||||||
|
|
@ -200,203 +100,125 @@ def seg_base_addr_lr_INT(database, tiles_by_grid, verbose=False):
|
||||||
else:
|
else:
|
||||||
assert 0
|
assert 0
|
||||||
|
|
||||||
add_int_bits(database, other_tile, framebase, wordbase)
|
localutil.add_tile_bits(
|
||||||
|
other_tile, database[other_tile], baseaddr, offset,
|
||||||
|
int_frames, int_words)
|
||||||
|
|
||||||
|
|
||||||
def seg_base_addr_up_INT(database, segments, tiles_by_grid, verbose=False):
|
def propagate_INT_bits_in_column(database, tiles_by_grid):
|
||||||
'''Populate segment base addresses: Up along INT/HCLK columns'''
|
""" Propigate INT offsets up and down INT columns.
|
||||||
|
|
||||||
verbose and print('')
|
INT columns appear to be fairly regular, where starting from offset 0,
|
||||||
# Copy the initial list containing only base addresses
|
INT tiles next to INT tiles increase the word offset by 2. The HCLK tile
|
||||||
# and soon to have derived addresses
|
is surrounded above and sometimes below by an INT tile. Because the HCLK
|
||||||
src_segment_names = list()
|
tile only useds one word, the offset increase by one at the HCLK.
|
||||||
for segment_name in segments.keys():
|
|
||||||
if "baseaddr" in segments[segment_name]:
|
|
||||||
src_segment_names.append(segment_name)
|
|
||||||
|
|
||||||
verbose and print('up_INT: %u base addresses' % len(src_segment_names))
|
|
||||||
|
|
||||||
for src_segment_name in sorted(src_segment_names):
|
|
||||||
src_segment = segments[src_segment_name]
|
|
||||||
|
|
||||||
for block_type, (framebase,
|
|
||||||
wordbase) in sorted(src_segment["baseaddr"].items()):
|
|
||||||
verbose and print(
|
|
||||||
'up_INT: %s: %s.0x%08X:%u' %
|
|
||||||
(src_segment_name, block_type, framebase, wordbase))
|
|
||||||
|
|
||||||
def process_CLB_IO_CLK(wordbase):
|
|
||||||
'''
|
|
||||||
Lookup interconnect tile associated with this segment
|
|
||||||
Use it to locate in the grid, and find other segments related by tile offset
|
|
||||||
'''
|
|
||||||
|
|
||||||
for inttile in list(get_inttile(database, src_segment)) + list(
|
|
||||||
get_iobtile(database, src_segment)):
|
|
||||||
verbose and print(
|
|
||||||
' up_INT CLB_IO_CLK: %s => inttile %s' %
|
|
||||||
(src_segment_name, inttile),
|
|
||||||
file=sys.stderr)
|
|
||||||
grid_x = database[inttile]["grid_x"]
|
|
||||||
grid_y = database[inttile]["grid_y"]
|
|
||||||
|
|
||||||
for dst_tile, wordbase in localutil.propagate_up_INT(
|
|
||||||
grid_x, grid_y, database, tiles_by_grid, wordbase):
|
|
||||||
if 'segment' not in dst_tile:
|
|
||||||
print(
|
|
||||||
'WARNING: Missing segment for {} ({}, {}) {}'.
|
|
||||||
format(
|
|
||||||
tiles_by_grid[(grid_x, grid_y)], grid_x,
|
|
||||||
grid_y, dst_tile))
|
|
||||||
continue
|
|
||||||
|
|
||||||
#verbose and print(' dst_tile', dst_tile)
|
|
||||||
if 'segment' in dst_tile:
|
|
||||||
dst_segment_name = dst_tile["segment"]
|
|
||||||
#verbose and print('up_INT: %s => %s' % (src_segment_name, dst_segment_name))
|
|
||||||
segments[dst_segment_name].setdefault(
|
|
||||||
"baseaddr",
|
|
||||||
{})[block_type] = [framebase, wordbase]
|
|
||||||
|
|
||||||
def process_BLOCK_RAM(wordbase):
|
|
||||||
'''
|
|
||||||
Lookup BRAM0 tile associated with this segment
|
|
||||||
Use it to locate in the grid, and find other BRAM0 related by tile offset
|
|
||||||
From minitest:
|
|
||||||
build/roi_bramd_bit01.diff (lowest BRAM coordinate)
|
|
||||||
> bit_00c00000_000_00
|
|
||||||
build/roi_bramds_bit01.diff
|
|
||||||
> bit_00c00000_000_00
|
|
||||||
> bit_00c00000_010_00
|
|
||||||
> bit_00c00000_020_00
|
|
||||||
> bit_00c00000_030_00
|
|
||||||
> bit_00c00000_040_00
|
|
||||||
> bit_00c00000_051_00
|
|
||||||
> bit_00c00000_061_00
|
|
||||||
> bit_00c00000_071_00
|
|
||||||
> bit_00c00000_081_00
|
|
||||||
> bit_00c00000_091_00
|
|
||||||
'''
|
|
||||||
src_tile_name = get_bramtile(database, src_segment)
|
|
||||||
verbose and print(
|
|
||||||
' up_INT BLOCK_RAM: %s => %s' %
|
|
||||||
(src_segment_name, src_tile_name))
|
|
||||||
grid_x = database[src_tile_name]["grid_x"]
|
|
||||||
grid_y = database[src_tile_name]["grid_y"]
|
|
||||||
|
|
||||||
for i in range(9):
|
|
||||||
grid_y -= 5
|
|
||||||
wordbase += 10
|
|
||||||
# Skip HCLK
|
|
||||||
if i == 4:
|
|
||||||
grid_y -= 1
|
|
||||||
wordbase += 1
|
|
||||||
|
|
||||||
# FIXME: PCIE block cuts out some BRAM
|
|
||||||
# this messes up algorithm as is and may cause this to fail
|
|
||||||
if grid_y < 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
dst_tile_name = tiles_by_grid[(grid_x, grid_y)]
|
|
||||||
|
|
||||||
dst_tile = database[dst_tile_name]
|
|
||||||
assert nolr(dst_tile['type']) == 'BRAM', dst_tile
|
|
||||||
|
|
||||||
dst_segment_name = dst_tile["segment"]
|
|
||||||
verbose and print(
|
|
||||||
' up_INT BLOCK_RAM: %s => %s' %
|
|
||||||
(dst_segment_name, dst_tile_name))
|
|
||||||
assert 'BRAM0' in dst_segment_name
|
|
||||||
segments[dst_segment_name].setdefault(
|
|
||||||
"baseaddr", {})[block_type] = [framebase, wordbase]
|
|
||||||
|
|
||||||
{
|
|
||||||
'CLB_IO_CLK': process_CLB_IO_CLK,
|
|
||||||
'BLOCK_RAM': process_BLOCK_RAM,
|
|
||||||
}[block_type](
|
|
||||||
wordbase)
|
|
||||||
|
|
||||||
|
|
||||||
def db_add_bits(database, segments):
|
|
||||||
'''Transfer segment data into tiles'''
|
|
||||||
for segment_name in segments.keys():
|
|
||||||
if 'baseaddr' not in segments[segment_name]:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for block_type, (baseaddr,
|
|
||||||
offset) in segments[segment_name]["baseaddr"].items():
|
|
||||||
for tile_name in segments[segment_name]["tiles"]:
|
|
||||||
tile_type = database[tile_name]["type"]
|
|
||||||
|
|
||||||
entry = localutil.get_entry(nolr(tile_type), block_type)
|
|
||||||
|
|
||||||
if entry is None:
|
|
||||||
# Other types are rare, not expected to have these
|
|
||||||
if block_type == "CLB_IO_CLK":
|
|
||||||
raise ValueError("Unknown tile type %s" % tile_type)
|
|
||||||
continue
|
|
||||||
|
|
||||||
frames, words, height = entry
|
|
||||||
if frames:
|
|
||||||
# if we have a width, we should have a height
|
|
||||||
assert frames and words
|
|
||||||
localutil.add_tile_bits(
|
|
||||||
tile_name, database[tile_name], baseaddr, offset,
|
|
||||||
frames, words, height)
|
|
||||||
|
|
||||||
|
|
||||||
def add_hclk_bits(database, tiles_by_grid):
|
|
||||||
""" Propigate HCLK baseaddr and wordbase from INT tiles above and below.
|
|
||||||
|
|
||||||
HCLK tiles are located between two INT tiles. The offset seperate between
|
|
||||||
these two tiles should be 3. The HCLK tile has an offset of 2 from the
|
|
||||||
lower INT offset and an offset of 1 from the upper INT offset.
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_, int_words, _ = localutil.get_entry('INT', 'CLB_IO_CLK')
|
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')
|
hclk_frames, hclk_words, _ = localutil.get_entry('HCLK', 'CLB_IO_CLK')
|
||||||
|
|
||||||
for tile_name in sorted(database.keys()):
|
for tile_name in sorted(database.keys()):
|
||||||
tile = database[tile_name]
|
tile = database[tile_name]
|
||||||
|
|
||||||
if tile['type'] not in ['HCLK_L', 'HCLK_R']:
|
if tile['type'] not in ['INT_L', 'INT_R']:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
tile_below = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 1)]
|
l_or_r = tile['type'][-1]
|
||||||
tile_above = tiles_by_grid[(tile['grid_x'], tile['grid_y'] - 1)]
|
|
||||||
|
|
||||||
expected_tile_type = 'INT_{}'.format(tile['type'][-1])
|
if not tile['bits']:
|
||||||
|
|
||||||
assert database[tile_below]['type'] == expected_tile_type, (
|
|
||||||
tile_name, tile_below)
|
|
||||||
assert database[tile_above]['type'] == expected_tile_type, (
|
|
||||||
tile_name, tile_above)
|
|
||||||
|
|
||||||
if not database[tile_below]['bits']:
|
|
||||||
continue
|
|
||||||
if not database[tile_above]['bits']:
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
bits_below = database[tile_below]['bits']['CLB_IO_CLK']
|
if tile_name in seen_int:
|
||||||
bits_above = database[tile_above]['bits']['CLB_IO_CLK']
|
continue
|
||||||
|
|
||||||
assert bits_below['baseaddr'] == bits_above['baseaddr'], (
|
# Walk down INT column
|
||||||
tile_name, bits_below['baseaddr'], bits_above['baseaddr'])
|
while True:
|
||||||
|
seen_int.add(tile_name)
|
||||||
|
|
||||||
offset_below = bits_below['offset']
|
next_tile = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 1)]
|
||||||
offset_above = bits_above['offset']
|
next_tile_type = database[next_tile]['type']
|
||||||
|
|
||||||
assert offset_above - offset_below == (int_words + hclk_words), (
|
if tile['bits']['CLB_IO_CLK']['offset'] == 0:
|
||||||
tile_name, offset_below, offset_above, int_words + hclk_words)
|
assert next_tile_type in ['B_TERM_INT', 'BRKH_INT', 'BRKH_B_TERM_INT'], next_tile_type
|
||||||
|
break
|
||||||
|
|
||||||
localutil.add_tile_bits(
|
baseaddr = int(tile['bits']['CLB_IO_CLK']['baseaddr'], 0)
|
||||||
tile_name,
|
offset = tile['bits']['CLB_IO_CLK']['offset']
|
||||||
database[tile_name],
|
|
||||||
baseaddr=int(bits_below['baseaddr'], 0),
|
if tile['type'].startswith('INT_') and next_tile_type == tile['type']:
|
||||||
offset=offset_below + int_words,
|
# INT next to INT
|
||||||
frames=hclk_frames,
|
offset -= int_words
|
||||||
words=hclk_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'], 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 run(json_in_fn, json_out_fn, int_tdb=None, verbose=False):
|
def run(json_in_fn, json_out_fn, int_tdb=None, verbose=False):
|
||||||
|
|
@ -404,7 +226,8 @@ def run(json_in_fn, json_out_fn, int_tdb=None, verbose=False):
|
||||||
database = json.load(open(json_in_fn, "r"))
|
database = json.load(open(json_in_fn, "r"))
|
||||||
tiles_by_grid = make_tiles_by_grid(database)
|
tiles_by_grid = make_tiles_by_grid(database)
|
||||||
|
|
||||||
add_hclk_bits(database, tiles_by_grid)
|
propagate_INT_lr_bits(database, tiles_by_grid, verbose=verbose)
|
||||||
|
propagate_INT_bits_in_column(database, tiles_by_grid)
|
||||||
|
|
||||||
# Save
|
# Save
|
||||||
xjson.pprint(open(json_out_fn, "w"), database)
|
xjson.pprint(open(json_out_fn, "w"), database)
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ proc loc_pins {} {
|
||||||
set tile [get_tiles -of_objects $site]
|
set tile [get_tiles -of_objects $site]
|
||||||
|
|
||||||
set pin [dict get $io_pin_sites $site]
|
set pin [dict get $io_pin_sites $site]
|
||||||
|
|
||||||
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" $port
|
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" $port
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import random
|
||||||
random.seed(int(os.getenv("SEED"), 16))
|
random.seed(int(os.getenv("SEED"), 16))
|
||||||
from prjxray import util
|
from prjxray import util
|
||||||
from prjxray.db import Database
|
from prjxray.db import Database
|
||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
def gen_sites():
|
def gen_sites():
|
||||||
|
|
@ -31,7 +32,9 @@ def gen_sites():
|
||||||
if len(sites) == 0:
|
if len(sites) == 0:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
sites.sort()
|
sites_y = [int(re.match('IDELAY_X[0-9]+Y([0-9]+)', site).group(1)) for site in sites]
|
||||||
|
|
||||||
|
sites, _ = zip(*sorted(zip(sites, sites_y), key=lambda x: x[1]))
|
||||||
|
|
||||||
if gridinfo.tile_type[0] == 'L':
|
if gridinfo.tile_type[0] == 'L':
|
||||||
int_grid_x = loc.grid_x + 3
|
int_grid_x = loc.grid_x + 3
|
||||||
|
|
@ -47,7 +50,10 @@ def gen_sites():
|
||||||
]
|
]
|
||||||
|
|
||||||
pad_gridinfo = grid.gridinfo_at_loc((pad_grid_x, loc.grid_y))
|
pad_gridinfo = grid.gridinfo_at_loc((pad_grid_x, loc.grid_y))
|
||||||
pad_sites = sorted(pad_gridinfo.sites.keys())
|
|
||||||
|
pad_sites = pad_gridinfo.sites.keys()
|
||||||
|
pad_sites_y = [int(re.match('IOB_X[0-9]+Y([0-9]+)', site).group(1)) for site in pad_sites]
|
||||||
|
pad_sites, _ = zip(*sorted(zip(pad_sites, pad_sites_y), key=lambda x: x[1]))
|
||||||
|
|
||||||
if not gridinfo.tile_type.endswith("_SING"):
|
if not gridinfo.tile_type.endswith("_SING"):
|
||||||
int_tile_locs.append((int_grid_x, loc.grid_y - 1))
|
int_tile_locs.append((int_grid_x, loc.grid_y - 1))
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@ def main():
|
||||||
if 'INT_INTERFACE' in tile_type:
|
if 'INT_INTERFACE' in tile_type:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if 'BRKH' in tile_type:
|
||||||
|
continue
|
||||||
|
|
||||||
have_bits = 0
|
have_bits = 0
|
||||||
for tile_name, gridinfo in tiles:
|
for tile_name, gridinfo in tiles:
|
||||||
total_tile_count += 1
|
total_tile_count += 1
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue