Merge pull request #906 from antmicro/tilegrid_ioi

Calculate base addresses for IOI tiles
This commit is contained in:
litghost 2019-06-25 10:20:06 -07:00 committed by GitHub
commit 73a6bc5d77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 287 additions and 0 deletions

View File

@ -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

View File

@ -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),

View File

@ -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)

View File

@ -0,0 +1,3 @@
N ?= 24
GENERATE_ARGS?="--oneval 1 --design params.csv --dframe 20 --dword 3"
include ../fuzzaddr/common.mk

View File

@ -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

View File

@ -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()