Add HCLK back to tilegrid.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2019-01-27 08:19:40 -08:00
parent be334a38df
commit 40e7771fa5
6 changed files with 77 additions and 57 deletions

View File

@ -81,7 +81,7 @@ build/tilegrid_tdb.json: add_tdb.py $(TILEGRID_TDB_DEPENDENCIES)
build/tilegrid.json: generate_full.py build/tilegrid_tdb.json
cd build && python3 ${FUZDIR}/generate_full.py \
--json-in tilegrid_tdb.json --json-out ${BUILD_DIR}/tilegrid.json \
--tiles $(FUZDIR)/build/tiles/tiles.txt ${GENERATE_FULL_ARGS}
${GENERATE_FULL_ARGS}
run:
$(MAKE) clean
$(MAKE) database

View File

@ -1,7 +1,6 @@
#!/usr/bin/env python3
from __future__ import print_function
from prjxray import util
import json
import util as localutil
@ -51,8 +50,7 @@ def run(fn_in, fn_out, verbose=False):
# FIXME: generate frames from part file (or equivilent)
# See https://github.com/SymbiFlow/prjxray/issues/327
# FIXME: generate words from pitch
int_frames = 28
int_words = 2
int_frames, int_words, _ = localutil.get_entry('INT', 'CLB_IO_CLK')
tdb_fns = [
("iob/build/segbits_tilegrid.tdb", 42, 4),
# FIXME: height

View File

@ -66,6 +66,8 @@ module top();
sites = list(gen_dsps())
fuzz_iter = iter(util.gen_fuzz_states(len(sites) * 5))
for tile_name, dsp_sites, int_tiles in sites:
int_tiles.reverse()
# Each DSP tile has 5 INT tiles.
# The following feature is used to toggle a one PIP in each INT tile
#
@ -104,22 +106,22 @@ module top();
wire [6:0] {dsp_site1}_opmode;
wire [2:0] {dsp_site1}_carryinsel;
// INT 0
// INT 0, {int0}
assign {dsp_site1}_c[36] = 0;
assign {dsp_site1}_carryinsel[1] = {d1_carryinsel1};
// INT 1
// INT 1, {int1}
assign {dsp_site0}_carryinsel[0] = {d0_carryinsel0};
// INT 2
// INT 2, {int2}
assign {dsp_site1}_a[29] = 0;
assign {dsp_site1}_b[8] = {d1_b8};
// INT 3
// INT 3, {int3}
assign {dsp_site1}_b[4] = 0;
assign {dsp_site1}_b[6] = {d1_b6};
// INT 4
// INT 4, {int4}
assign {dsp_site1}_c[20] = 0;
assign {dsp_site1}_b[2] = {d1_b2};
@ -150,7 +152,13 @@ module top();
d0_carryinsel0=d0_carryinsel0,
d1_b8=d1_b8,
d1_b6=d1_b6,
d1_b2=d1_b2))
d1_b2=d1_b2,
int0=int_tiles[0],
int1=int_tiles[1],
int2=int_tiles[2],
int3=int_tiles[3],
int4=int_tiles[4],
))
print("endmodule")
write_params(params)

View File

@ -49,12 +49,13 @@ def load_tdb_baseaddr(database, int_tdb, verbose=False):
return tdb_tile_baseaddrs
def make_tiles_by_grid(tiles):
def make_tiles_by_grid(database):
# lookup tile names by (X, Y)
tiles_by_grid = dict()
for tile in tiles:
tiles_by_grid[(tile["grid_x"], tile["grid_y"])] = tile["name"]
for tile_name in database:
tile = database[tile_name]
tiles_by_grid[(tile["grid_x"], tile["grid_y"])] = tile_name
return tiles_by_grid
@ -233,7 +234,7 @@ def seg_base_addr_up_INT(database, segments, tiles_by_grid, verbose=False):
for inttile in list(get_inttile(database, src_segment)) + list(
get_iobtile(database, src_segment)):
verbose and print(
' up_INT CLK_IO_CLK: %s => inttile %s' %
' up_INT CLB_IO_CLK: %s => inttile %s' %
(src_segment_name, inttile),
file=sys.stderr)
grid_x = database[inttile]["grid_x"]
@ -344,57 +345,66 @@ def db_add_bits(database, segments):
frames, words, height)
def db_add_segments(database, segments):
# 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.
# looks like only htmlgen is using this?
for tiledata in database.values():
if "segment" in tiledata:
segment = tiledata["segment"]
tiledata["segment_type"] = segments[segment]["type"]
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.
def db_int_fixup(database, tiles, tiles_by_grid):
for tile_name in tiles.keys():
tiles_to_add = dict()
"""
_, 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]
grid_x = tile["grid_x"]
grid_y = tile["grid_y"]
tile_type = tile["type"]
if tile['type'] not in ['HCLK_L', 'HCLK_R']:
continue
block_type, (baseaddr, offset) = sorted(tiles[tile_name].items())[0]
tile_below = tiles_by_grid[(tile['grid_x'], tile['grid_y'] + 1)]
tile_above = tiles_by_grid[(tile['grid_x'], tile['grid_y'] - 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']:
continue
bits_below = database[tile_below]['bits']['CLB_IO_CLK']
bits_above = database[tile_above]['bits']['CLB_IO_CLK']
assert bits_below['baseaddr'] == bits_above['baseaddr'], (
tile_name, bits_below['baseaddr'], bits_above['baseaddr'])
offset_below = bits_below['offset']
offset_above = bits_above['offset']
assert offset_above - offset_below == (int_words + hclk_words), (tile_name, offset_below, offset_above, int_words + hclk_words)
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)
tile_name, database[tile_name],
baseaddr=int(bits_below['baseaddr'], 0),
offset=offset_below+int_words,
frames=hclk_frames, words=hclk_words)
def run(json_in_fn, json_out_fn, tiles_fn, int_tdb=None, verbose=False):
def run(json_in_fn, json_out_fn, int_tdb=None, verbose=False):
# Load input files
tiles = load_tiles(tiles_fn)
#site_baseaddr = {}
database = json.load(open(json_in_fn, "r"))
tiles_by_grid = make_tiles_by_grid(database)
tiles_by_grid = make_tiles_by_grid(tiles)
add_hclk_bits(database, tiles_by_grid)
if int_tdb is not None:
tile_baseaddrs_fixup = load_tdb_baseaddr(database, int_tdb)
db_int_fixup(database, tile_baseaddrs_fixup, tiles_by_grid)
#add_adjacent_int_tiles(database, tiles_by_grid, verbose=verbose)
# Reference adjacent CLBs to locate adjacent tiles by known offsets
#seg_base_addr_lr_INT(database, tiles_by_grid, verbose=verbose)
# Save
xjson.pprint(open(json_out_fn, "w"), database)
@ -413,8 +423,6 @@ def main():
help="Input .json without addresses")
parser.add_argument(
"--json-out", default="tilegrid.json", help="Output JSON")
parser.add_argument(
'--tiles', default='tiles.txt', help='Input tiles.txt tcl output')
parser.add_argument(
"--int-tdb",
default=None,
@ -424,7 +432,6 @@ def main():
run(
args.json_in,
args.json_out,
args.tiles,
args.int_tdb,
verbose=args.verbose)

View File

@ -19,7 +19,7 @@ def gen_sites():
'''
db = Database(util.get_db_root())
grid = db.grid()
for tile_name in grid.tiles():
for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc)
@ -31,7 +31,7 @@ def gen_sites():
if len(sites) == 0:
continue
sites = sorted(sites)
sites.sort()
if gridinfo.tile_type[0] == 'L':
int_grid_x = loc.grid_x + 3
@ -97,6 +97,7 @@ module top(input wire [`N_DI-1:0] di);
print(
'''
// Solving for {3}
(* KEEP, DONT_TOUCH *)
IBUF ibuf_{0}(.I(di[{2}]), .O(di_buf[{2}]));
@ -105,7 +106,7 @@ module top(input wire [`N_DI-1:0] di);
.CNTVALUEIN(5'b0{1}111),
.IDATAIN(di_buf[{2}])
);
'''.format(site_name, isone, idx))
'''.format(site_name, isone, idx, tile_name))
print("endmodule")
write_params(params)

View File

@ -42,6 +42,7 @@ def propagate_up_INT(grid_x, grid_y, database, tiles_by_grid, wordbase):
wordbase += 1
else:
wordbase += 2
yield tile, wordbase
@ -155,3 +156,8 @@ def add_tile_bits(
if height is None:
height = words
block["height"] = height
def get_int_params():
int_frames = 28
int_words = 2
return int_frames, int_words