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 += dsp/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=
|
||||
|
||||
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
|
||||
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)
|
||||
python3 add_tdb.py \
|
||||
--fn-in build/basicdb/tilegrid.json \
|
||||
|
|
@ -102,6 +106,7 @@ clean:
|
|||
cd bram_int && $(MAKE) clean
|
||||
cd dsp && $(MAKE) clean
|
||||
cd dsp_int && $(MAKE) clean
|
||||
cd fifo_int && $(MAKE) clean
|
||||
cd monitor && $(MAKE) clean
|
||||
|
||||
.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),
|
||||
("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),
|
||||
]
|
||||
|
||||
for (tdb_fn, frames, words) in tdb_fns:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -23,15 +23,14 @@ def gen_fifos():
|
|||
int_tile_type = 'INT_R'
|
||||
|
||||
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 = []
|
||||
for int_tile_loc in int_tile_locs:
|
||||
int_gridinfo = grid.gridinfo_at_loc(int_tile_loc)
|
||||
assert int_gridinfo.tile_type == int_tile_type, (
|
||||
int_tile_loc,
|
||||
int_gridinfo.tile_type, int_tile_type)
|
||||
int_tile_loc, int_gridinfo.tile_type, int_tile_type)
|
||||
|
||||
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_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]
|
||||
TOGGLE_BIT = [3, 3, 3, 3, 3, 3, 7, 7, 3, 3, 3, 3]
|
||||
# 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()
|
||||
|
||||
|
|
@ -81,29 +80,33 @@ module top();
|
|||
bits_set.add((CHANNEL[idx], TOGGLE_BIT[idx]))
|
||||
|
||||
assigns.append(' // {}'.format(int_tile))
|
||||
assigns.append(' assign {site}_in_d{channel}[{bit}] = 0;'.format(
|
||||
site=site,
|
||||
channel=CHANNEL[idx],
|
||||
bit=HOLD_BIT_0[idx],
|
||||
assigns.append(
|
||||
' assign {site}_in_d{channel}[{bit}] = 0;'.format(
|
||||
site=site,
|
||||
channel=CHANNEL[idx],
|
||||
bit=HOLD_BIT_0[idx],
|
||||
))
|
||||
assigns.append(' assign {site}_in_d{channel}[{bit}] = {toggle_bit};'.format(
|
||||
site=site,
|
||||
channel=CHANNEL[idx],
|
||||
bit=TOGGLE_BIT[idx],
|
||||
toggle_bit=bit,
|
||||
assigns.append(
|
||||
' assign {site}_in_d{channel}[{bit}] = {toggle_bit};'
|
||||
.format(
|
||||
site=site,
|
||||
channel=CHANNEL[idx],
|
||||
bit=TOGGLE_BIT[idx],
|
||||
toggle_bit=bit,
|
||||
))
|
||||
params[int_tile] = (bit,)
|
||||
params[int_tile] = (bit, )
|
||||
|
||||
assigns.append('')
|
||||
|
||||
|
||||
for channel, width in enumerate(WIDTH):
|
||||
for bit in range(width):
|
||||
if (channel, bit) not in bits_set:
|
||||
assigns.append(' assign {site}_in_d{channel}[{bit}] = 1;'.format(
|
||||
site=site,
|
||||
channel=channel,
|
||||
bit=bit,
|
||||
assigns.append(
|
||||
' assign {site}_in_d{channel}[{bit}] = 1;'.
|
||||
format(
|
||||
site=site,
|
||||
channel=channel,
|
||||
bit=bit,
|
||||
))
|
||||
|
||||
print(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import print_function
|
||||
import sys, json
|
||||
import json
|
||||
from utils import xjson
|
||||
'''
|
||||
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
|
||||
'''
|
||||
|
||||
from generate import load_tiles
|
||||
import util as localutil
|
||||
|
||||
|
||||
|
|
@ -60,109 +59,10 @@ def make_tiles_by_grid(database):
|
|||
return tiles_by_grid
|
||||
|
||||
|
||||
def add_int_bits(database, tile, baseaddr, offset):
|
||||
"""
|
||||
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):
|
||||
def propagate_INT_lr_bits(database, tiles_by_grid, verbose=False):
|
||||
'''Populate segment base addresses: L/R along INT column'''
|
||||
'''
|
||||
Create BRAM base addresses based on nearby CLBs
|
||||
ie if we have a BRAM_L, compute as nearby CLB_R base address + offset
|
||||
'''
|
||||
|
||||
int_frames, int_words, _ = localutil.get_entry('INT', 'CLB_IO_CLK')
|
||||
|
||||
verbose and print('')
|
||||
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_y = database[tile]["grid_y"]
|
||||
framebase = int(database[tile]["bits"]["CLB_IO_CLK"]["baseaddr"], 0)
|
||||
wordbase = database[tile]["bits"]["CLB_IO_CLK"]["offset"]
|
||||
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
|
||||
framebase = framebase + 0x80
|
||||
baseaddr = baseaddr + 0x80
|
||||
elif database[tile]["type"] == "INT_R":
|
||||
grid_x -= 1
|
||||
framebase = framebase - 0x80
|
||||
baseaddr = baseaddr - 0x80
|
||||
else:
|
||||
assert 0
|
||||
assert 0, database[tile]["type"]
|
||||
|
||||
# ROI at edge?
|
||||
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:
|
||||
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):
|
||||
'''Populate segment base addresses: Up along INT/HCLK columns'''
|
||||
def propagate_INT_bits_in_column(database, tiles_by_grid):
|
||||
""" Propigate INT offsets up and down INT columns.
|
||||
|
||||
verbose and print('')
|
||||
# Copy the initial list containing only base addresses
|
||||
# and soon to have derived addresses
|
||||
src_segment_names = list()
|
||||
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 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.
|
||||
|
||||
"""
|
||||
|
||||
_, 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')
|
||||
|
||||
for tile_name in sorted(database.keys()):
|
||||
tile = database[tile_name]
|
||||
|
||||
if tile['type'] not in ['HCLK_L', 'HCLK_R']:
|
||||
if tile['type'] not in ['INT_L', 'INT_R']:
|
||||
continue
|
||||
|
||||
tile_below = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 1)]
|
||||
tile_above = tiles_by_grid[(tile['grid_x'], tile['grid_y'] - 1)]
|
||||
l_or_r = tile['type'][-1]
|
||||
|
||||
expected_tile_type = 'INT_{}'.format(tile['type'][-1])
|
||||
|
||||
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']:
|
||||
if not tile['bits']:
|
||||
continue
|
||||
|
||||
bits_below = database[tile_below]['bits']['CLB_IO_CLK']
|
||||
bits_above = database[tile_above]['bits']['CLB_IO_CLK']
|
||||
if tile_name in seen_int:
|
||||
continue
|
||||
|
||||
assert bits_below['baseaddr'] == bits_above['baseaddr'], (
|
||||
tile_name, bits_below['baseaddr'], bits_above['baseaddr'])
|
||||
# Walk down INT column
|
||||
while True:
|
||||
seen_int.add(tile_name)
|
||||
|
||||
offset_below = bits_below['offset']
|
||||
offset_above = bits_above['offset']
|
||||
next_tile = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 1)]
|
||||
next_tile_type = database[next_tile]['type']
|
||||
|
||||
assert offset_above - offset_below == (int_words + hclk_words), (
|
||||
tile_name, offset_below, offset_above, int_words + hclk_words)
|
||||
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
|
||||
|
||||
localutil.add_tile_bits(
|
||||
tile_name,
|
||||
database[tile_name],
|
||||
baseaddr=int(bits_below['baseaddr'], 0),
|
||||
offset=offset_below + int_words,
|
||||
frames=hclk_frames,
|
||||
words=hclk_words)
|
||||
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'], 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):
|
||||
|
|
@ -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"))
|
||||
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
|
||||
xjson.pprint(open(json_out_fn, "w"), database)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ proc loc_pins {} {
|
|||
set tile [get_tiles -of_objects $site]
|
||||
|
||||
set pin [dict get $io_pin_sites $site]
|
||||
|
||||
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" $port
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import random
|
|||
random.seed(int(os.getenv("SEED"), 16))
|
||||
from prjxray import util
|
||||
from prjxray.db import Database
|
||||
import re
|
||||
|
||||
|
||||
def gen_sites():
|
||||
|
|
@ -31,7 +32,9 @@ def gen_sites():
|
|||
if len(sites) == 0:
|
||||
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':
|
||||
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_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"):
|
||||
int_tile_locs.append((int_grid_x, loc.grid_y - 1))
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ def main():
|
|||
if 'INT_INTERFACE' in tile_type:
|
||||
continue
|
||||
|
||||
if 'BRKH' in tile_type:
|
||||
continue
|
||||
|
||||
have_bits = 0
|
||||
for tile_name, gridinfo in tiles:
|
||||
total_tile_count += 1
|
||||
|
|
|
|||
Loading…
Reference in New Issue