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 += iob/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 += bram/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
|
||||
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
|
||||
cd mmcm && $(MAKE)
|
||||
|
||||
|
|
@ -133,6 +137,7 @@ clean:
|
|||
cd cfg && $(MAKE) clean
|
||||
cd iob && $(MAKE) clean
|
||||
cd iob_int && $(MAKE) clean
|
||||
cd ioi && $(MAKE) clean
|
||||
cd mmcm && $(MAKE) clean
|
||||
cd pll && $(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()
|
||||
tdb_fns = [
|
||||
("iob/build/segbits_tilegrid.tdb", 42, 4),
|
||||
("ioi/build/segbits_tilegrid.tdb", 42, 4),
|
||||
("mmcm/build/segbits_tilegrid.tdb", 30, 101),
|
||||
("pll/build/segbits_tilegrid.tdb", 30, 101),
|
||||
("monitor/build/segbits_tilegrid.tdb", 30, 101),
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
from utils import xjson
|
||||
'''
|
||||
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):
|
||||
# Load input files
|
||||
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_rebuf(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
|
||||
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