mirror of https://github.com/openXC7/prjxray.git
Merge pull request #906 from antmicro/tilegrid_ioi
Calculate base addresses for IOI tiles
This commit is contained in:
commit
73a6bc5d77
|
|
@ -3,6 +3,7 @@ BUILD_DIR=$(FUZDIR)/build
|
||||||
TILEGRID_TDB_DEPENDENCIES=
|
TILEGRID_TDB_DEPENDENCIES=
|
||||||
TILEGRID_TDB_DEPENDENCIES += iob/build/segbits_tilegrid.tdb
|
TILEGRID_TDB_DEPENDENCIES += iob/build/segbits_tilegrid.tdb
|
||||||
TILEGRID_TDB_DEPENDENCIES += iob_int/build/segbits_tilegrid.tdb
|
TILEGRID_TDB_DEPENDENCIES += iob_int/build/segbits_tilegrid.tdb
|
||||||
|
TILEGRID_TDB_DEPENDENCIES += ioi/build/segbits_tilegrid.tdb
|
||||||
TILEGRID_TDB_DEPENDENCIES += monitor/build/segbits_tilegrid.tdb
|
TILEGRID_TDB_DEPENDENCIES += monitor/build/segbits_tilegrid.tdb
|
||||||
TILEGRID_TDB_DEPENDENCIES += bram/build/segbits_tilegrid.tdb
|
TILEGRID_TDB_DEPENDENCIES += bram/build/segbits_tilegrid.tdb
|
||||||
TILEGRID_TDB_DEPENDENCIES += bram_block/build/segbits_tilegrid.tdb
|
TILEGRID_TDB_DEPENDENCIES += bram_block/build/segbits_tilegrid.tdb
|
||||||
|
|
@ -64,6 +65,9 @@ iob/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||||
iob_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
iob_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||||
cd iob_int && $(MAKE)
|
cd iob_int && $(MAKE)
|
||||||
|
|
||||||
|
ioi/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||||
|
cd ioi && $(MAKE)
|
||||||
|
|
||||||
mmcm/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
mmcm/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||||
cd mmcm && $(MAKE)
|
cd mmcm && $(MAKE)
|
||||||
|
|
||||||
|
|
@ -133,6 +137,7 @@ clean:
|
||||||
cd cfg && $(MAKE) clean
|
cd cfg && $(MAKE) clean
|
||||||
cd iob && $(MAKE) clean
|
cd iob && $(MAKE) clean
|
||||||
cd iob_int && $(MAKE) clean
|
cd iob_int && $(MAKE) clean
|
||||||
|
cd ioi && $(MAKE) clean
|
||||||
cd mmcm && $(MAKE) clean
|
cd mmcm && $(MAKE) clean
|
||||||
cd pll && $(MAKE) clean
|
cd pll && $(MAKE) clean
|
||||||
cd ps7_int && $(MAKE) clean
|
cd ps7_int && $(MAKE) clean
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ def run(fn_in, fn_out, verbose=False):
|
||||||
int_frames, int_words = localutil.get_int_params()
|
int_frames, int_words = localutil.get_int_params()
|
||||||
tdb_fns = [
|
tdb_fns = [
|
||||||
("iob/build/segbits_tilegrid.tdb", 42, 4),
|
("iob/build/segbits_tilegrid.tdb", 42, 4),
|
||||||
|
("ioi/build/segbits_tilegrid.tdb", 42, 4),
|
||||||
("mmcm/build/segbits_tilegrid.tdb", 30, 101),
|
("mmcm/build/segbits_tilegrid.tdb", 30, 101),
|
||||||
("pll/build/segbits_tilegrid.tdb", 30, 101),
|
("pll/build/segbits_tilegrid.tdb", 30, 101),
|
||||||
("monitor/build/segbits_tilegrid.tdb", 30, 101),
|
("monitor/build/segbits_tilegrid.tdb", 30, 101),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
from utils import xjson
|
from utils import xjson
|
||||||
'''
|
'''
|
||||||
Historically we grouped data into "segments"
|
Historically we grouped data into "segments"
|
||||||
|
|
@ -317,6 +318,91 @@ def propagate_IOB_SING(database, tiles_by_grid):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def propagate_IOI_SING(database, tiles_by_grid):
|
||||||
|
"""
|
||||||
|
The IOI_SING, similarly to IOB_SING, are half tiles at top and bottom of every
|
||||||
|
IO column.
|
||||||
|
|
||||||
|
The tile contains half of the sites that are present in the full IOI,
|
||||||
|
namely one ILOGIC, OLOGIC and IDELAY.
|
||||||
|
"""
|
||||||
|
|
||||||
|
seen_iois = set()
|
||||||
|
for tile in database:
|
||||||
|
if tile in seen_iois:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if database[tile]["type"] not in ["LIOI3", "RIOI3"]:
|
||||||
|
continue
|
||||||
|
|
||||||
|
while True:
|
||||||
|
prev_tile = tile
|
||||||
|
tile = tiles_by_grid[(
|
||||||
|
database[tile]['grid_x'], database[tile]['grid_y'] + 1)]
|
||||||
|
if '_SING' in database[tile]['type']:
|
||||||
|
break
|
||||||
|
|
||||||
|
bottom_tile = tile
|
||||||
|
seen_iois.add(bottom_tile)
|
||||||
|
|
||||||
|
bits = database[prev_tile]['bits']['CLB_IO_CLK']
|
||||||
|
|
||||||
|
while True:
|
||||||
|
tile = tiles_by_grid[(
|
||||||
|
database[tile]['grid_x'], database[tile]['grid_y'] - 1)]
|
||||||
|
seen_iois.add(tile)
|
||||||
|
|
||||||
|
if '_SING' in database[tile]['type']:
|
||||||
|
break
|
||||||
|
|
||||||
|
if 'CLB_IO_CLK' in database[tile]['bits']:
|
||||||
|
assert bits['baseaddr'] == database[tile]['bits'][
|
||||||
|
'CLB_IO_CLK']['baseaddr']
|
||||||
|
assert bits['frames'] == database[tile]['bits']['CLB_IO_CLK'][
|
||||||
|
'frames']
|
||||||
|
assert bits['words'] == database[tile]['bits']['CLB_IO_CLK'][
|
||||||
|
'words']
|
||||||
|
|
||||||
|
top_tile = tile
|
||||||
|
|
||||||
|
database[top_tile]['bits']['CLB_IO_CLK'] = copy.deepcopy(bits)
|
||||||
|
database[top_tile]['bits']['CLB_IO_CLK']['words'] = 2
|
||||||
|
database[top_tile]['bits']['CLB_IO_CLK']['offset'] = 99
|
||||||
|
|
||||||
|
database[bottom_tile]['bits']['CLB_IO_CLK'] = copy.deepcopy(bits)
|
||||||
|
database[bottom_tile]['bits']['CLB_IO_CLK']['words'] = 2
|
||||||
|
database[bottom_tile]['bits']['CLB_IO_CLK']['offset'] = 0
|
||||||
|
|
||||||
|
|
||||||
|
def propagate_IOI_Y9(database, tiles_by_grid):
|
||||||
|
"""
|
||||||
|
There are IOI tiles (X0Y9 and X43Y9) that have the frame address 1 frame
|
||||||
|
higher than the rest, just like for some of the SING tiles.
|
||||||
|
|
||||||
|
"""
|
||||||
|
arch = os.getenv('XRAY_DATABASE')
|
||||||
|
if arch in 'artix7':
|
||||||
|
tiles = ['RIOI3_X43Y9', 'LIOI3_X0Y9']
|
||||||
|
elif arch in 'kintex7':
|
||||||
|
tiles = ['LIOI3_X0Y9']
|
||||||
|
elif arch in 'zynq7':
|
||||||
|
tiles = ['RIOI3_X31Y9']
|
||||||
|
else:
|
||||||
|
assert False, "Unsupported architecture"
|
||||||
|
|
||||||
|
for tile in tiles:
|
||||||
|
prev_tile = tiles_by_grid[(
|
||||||
|
database[tile]['grid_x'], database[tile]['grid_y'] - 1)]
|
||||||
|
while database[prev_tile]["type"] != database[tile]["type"]:
|
||||||
|
prev_tile = tiles_by_grid[(
|
||||||
|
database[prev_tile]['grid_x'],
|
||||||
|
database[prev_tile]['grid_y'] - 1)]
|
||||||
|
bits = database[prev_tile]['bits']['CLB_IO_CLK']
|
||||||
|
database[tile]['bits']['CLB_IO_CLK'] = copy.deepcopy(bits)
|
||||||
|
database[tile]['bits']['CLB_IO_CLK']['words'] = 4
|
||||||
|
database[tile]['bits']['CLB_IO_CLK']['offset'] = 18
|
||||||
|
|
||||||
|
|
||||||
def run(json_in_fn, json_out_fn, verbose=False):
|
def run(json_in_fn, json_out_fn, verbose=False):
|
||||||
# Load input files
|
# Load input files
|
||||||
database = json.load(open(json_in_fn, "r"))
|
database = json.load(open(json_in_fn, "r"))
|
||||||
|
|
@ -326,6 +412,8 @@ def run(json_in_fn, json_out_fn, verbose=False):
|
||||||
propagate_INT_bits_in_column(database, tiles_by_grid)
|
propagate_INT_bits_in_column(database, tiles_by_grid)
|
||||||
propagate_rebuf(database, tiles_by_grid)
|
propagate_rebuf(database, tiles_by_grid)
|
||||||
propagate_IOB_SING(database, tiles_by_grid)
|
propagate_IOB_SING(database, tiles_by_grid)
|
||||||
|
propagate_IOI_SING(database, tiles_by_grid)
|
||||||
|
propagate_IOI_Y9(database, tiles_by_grid)
|
||||||
|
|
||||||
# Save
|
# Save
|
||||||
xjson.pprint(open(json_out_fn, "w"), database)
|
xjson.pprint(open(json_out_fn, "w"), database)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
N ?= 24
|
||||||
|
GENERATE_ARGS?="--oneval 1 --design params.csv --dframe 20 --dword 3"
|
||||||
|
include ../fuzzaddr/common.mk
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
source "$::env(XRAY_DIR)/utils/utils.tcl"
|
||||||
|
|
||||||
|
proc make_io_pin_sites {} {
|
||||||
|
# get all possible IOB pins
|
||||||
|
foreach pad [get_package_pins -filter "IS_GENERAL_PURPOSE == 1"] {
|
||||||
|
set site [get_sites -of_objects $pad]
|
||||||
|
if {[llength $site] == 0} {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if [string match IOB33* [get_property SITE_TYPE $site]] {
|
||||||
|
dict append io_pin_sites $site $pad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $io_pin_sites
|
||||||
|
}
|
||||||
|
|
||||||
|
proc load_pin_lines {} {
|
||||||
|
# IOB_X0Y103 clk input
|
||||||
|
# IOB_X0Y129 do[0] output
|
||||||
|
|
||||||
|
set fp [open "params.csv" r]
|
||||||
|
gets $fp line
|
||||||
|
|
||||||
|
set pin_lines {}
|
||||||
|
for {gets $fp line} {$line != ""} {gets $fp line} {
|
||||||
|
lappend pin_lines [split $line ","]
|
||||||
|
}
|
||||||
|
close $fp
|
||||||
|
return $pin_lines
|
||||||
|
}
|
||||||
|
|
||||||
|
proc loc_pins {} {
|
||||||
|
set pin_lines [load_pin_lines]
|
||||||
|
set io_pin_sites [make_io_pin_sites]
|
||||||
|
set package_pin_keys [dict keys $io_pin_sites]
|
||||||
|
|
||||||
|
puts "Looping"
|
||||||
|
for {set idx 0} {$idx < [llength $pin_lines]} {incr idx} {
|
||||||
|
set line [lindex $pin_lines $idx]
|
||||||
|
puts "$line"
|
||||||
|
|
||||||
|
set site_str [lindex $line 2]
|
||||||
|
set pin_str [lindex $line 3]
|
||||||
|
set pad_str [lindex $line 4]
|
||||||
|
|
||||||
|
# Have: site
|
||||||
|
# Want: pin for site
|
||||||
|
|
||||||
|
set site [get_sites $site_str]
|
||||||
|
set port [get_ports $pin_str]
|
||||||
|
set tile [get_tiles -of_objects $site]
|
||||||
|
|
||||||
|
|
||||||
|
set pin [dict get $io_pin_sites $pad_str]
|
||||||
|
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" $port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
proc run {} {
|
||||||
|
create_project -force -part $::env(XRAY_PART) design design
|
||||||
|
read_verilog top.v
|
||||||
|
synth_design -top top
|
||||||
|
|
||||||
|
#loc_pins
|
||||||
|
|
||||||
|
set_property CFGBVS VCCO [current_design]
|
||||||
|
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||||
|
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||||
|
set_property IS_ENABLED 0 [get_drc_checks {REQP-79}]
|
||||||
|
set_property SEVERITY {Warning} [get_drc_checks NSTD-1]
|
||||||
|
set_property SEVERITY {Warning} [get_drc_checks UCIO-1]
|
||||||
|
#set_property IS_ENABLED 0 [get_drc_checks {REQP-83}]
|
||||||
|
|
||||||
|
place_design
|
||||||
|
route_design
|
||||||
|
|
||||||
|
write_checkpoint -force design.dcp
|
||||||
|
write_bitstream -force design.bit
|
||||||
|
}
|
||||||
|
|
||||||
|
run
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
import json
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
random.seed(int(os.getenv("SEED"), 16))
|
||||||
|
from prjxray import util
|
||||||
|
from prjxray import lut_maker
|
||||||
|
from prjxray import verilog
|
||||||
|
from prjxray.db import Database
|
||||||
|
|
||||||
|
|
||||||
|
def gen_sites():
|
||||||
|
db = Database(util.get_db_root())
|
||||||
|
grid = db.grid()
|
||||||
|
for tile_name in sorted(grid.tiles()):
|
||||||
|
loc = grid.loc_of_tilename(tile_name)
|
||||||
|
gridinfo = grid.gridinfo_at_loc(loc)
|
||||||
|
if gridinfo.tile_type.endswith("_SING"):
|
||||||
|
continue
|
||||||
|
# Y9 tiles have frame address 1 frame higher than the rest
|
||||||
|
# Need to investigate what is so special about them
|
||||||
|
if tile_name.endswith("Y9"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
sites = []
|
||||||
|
for site_name, site_type in gridinfo.sites.items():
|
||||||
|
if site_type == 'IDELAYE2':
|
||||||
|
yield tile_name, site_name
|
||||||
|
|
||||||
|
|
||||||
|
def write_params(params):
|
||||||
|
pinstr = 'tile,isone,site\n'
|
||||||
|
for vals in params:
|
||||||
|
pinstr += ','.join(map(str, vals)) + '\n'
|
||||||
|
|
||||||
|
open('params.csv', 'w').write(pinstr)
|
||||||
|
|
||||||
|
|
||||||
|
def use_idelay(p, luts, connects):
|
||||||
|
print(
|
||||||
|
'''
|
||||||
|
wire idelay_{site};
|
||||||
|
|
||||||
|
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
|
||||||
|
IDELAYE2 #(
|
||||||
|
.HIGH_PERFORMANCE_MODE("{param}"),
|
||||||
|
.DELAY_SRC("DATAIN")
|
||||||
|
) idelay_site_{site} (
|
||||||
|
.DATAIN({onet}),
|
||||||
|
.DATAOUT(idelay_{site})
|
||||||
|
);
|
||||||
|
assign {net} = idelay_{site};
|
||||||
|
'''.format(
|
||||||
|
onet=luts.get_next_output_net(),
|
||||||
|
net=luts.get_next_input_net(),
|
||||||
|
param="TRUE" if p['isone'] else "FALSE",
|
||||||
|
**p),
|
||||||
|
file=connects)
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
luts = lut_maker.LutMaker()
|
||||||
|
connects = io.StringIO()
|
||||||
|
|
||||||
|
tile_params = []
|
||||||
|
params = []
|
||||||
|
sites = sorted(list(gen_sites()))
|
||||||
|
for idx, ((tile, site), isone) in enumerate(zip(
|
||||||
|
sites, util.gen_fuzz_states(len(sites)))):
|
||||||
|
|
||||||
|
p = {}
|
||||||
|
p['tile'] = tile
|
||||||
|
p['site'] = site
|
||||||
|
p['isone'] = isone
|
||||||
|
params.append(p)
|
||||||
|
tile_params.append((tile, p['isone'], site))
|
||||||
|
|
||||||
|
write_params(tile_params)
|
||||||
|
|
||||||
|
print('''
|
||||||
|
module top();
|
||||||
|
''')
|
||||||
|
|
||||||
|
# Always output a LUT6 to make placer happy.
|
||||||
|
print('''
|
||||||
|
(* KEEP, DONT_TOUCH *)
|
||||||
|
LUT6 dummy_lut();
|
||||||
|
''')
|
||||||
|
|
||||||
|
# Need IDELAYCTRL for IDEALAYs
|
||||||
|
print('''
|
||||||
|
(* KEEP, DONT_TOUCH *)
|
||||||
|
IDELAYCTRL();
|
||||||
|
''')
|
||||||
|
|
||||||
|
for p in params:
|
||||||
|
use_idelay(p, luts, connects)
|
||||||
|
|
||||||
|
for l in luts.create_wires_and_luts():
|
||||||
|
print(l)
|
||||||
|
|
||||||
|
print(connects.getvalue())
|
||||||
|
|
||||||
|
print("endmodule")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
run()
|
||||||
Loading…
Reference in New Issue