Sort tiles and revamp gen_fuzz_states to be more efficient.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2019-02-13 17:59:37 -08:00
parent 19706142db
commit 7e4e4b19fc
25 changed files with 120 additions and 246 deletions

View File

@ -1,4 +1,4 @@
N ?= 30 N ?= 12
GENERATE_ARGS?="--oneval 1 --design params.csv --dword 2 --dframe 1B" GENERATE_ARGS?="--oneval 1 --design params.csv --dword 2 --dframe 1B"
include ../fuzzaddr/common.mk include ../fuzzaddr/common.mk

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
def gen_sites(): def gen_sites():
db = Database(util.get_db_root()) db = Database(util.get_db_root())
grid = db.grid() grid = db.grid()
for tile_name in grid.tiles(): for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name) loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc) gridinfo = grid.gridinfo_at_loc(loc)

View File

@ -1,4 +1,4 @@
N ?= 30 N ?= 12
GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 0" GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 0"
include ../fuzzaddr/common.mk include ../fuzzaddr/common.mk

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
def gen_sites(): def gen_sites():
db = Database(util.get_db_root()) db = Database(util.get_db_root())
grid = db.grid() grid = db.grid()
for tile_name in grid.tiles(): for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name) loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc) gridinfo = grid.gridinfo_at_loc(loc)

View File

@ -1,4 +1,4 @@
N ?= 30 N ?= 15
GENERATE_ARGS?="--oneval 0 --design params.csv --dword 1 --dframe 15" GENERATE_ARGS?="--oneval 0 --design params.csv --dword 1 --dframe 15"
include ../fuzzaddr/common.mk include ../fuzzaddr/common.mk

View File

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

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
def gen_sites(): def gen_sites():
db = Database(util.get_db_root()) db = Database(util.get_db_root())
grid = db.grid() grid = db.grid()
for tile_name in grid.tiles(): for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name) loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc) gridinfo = grid.gridinfo_at_loc(loc)
if gridinfo.tile_type in ['CLBLL_L', 'CLBLL_R', 'CLBLM_L', 'CLBLM_R']: if gridinfo.tile_type in ['CLBLL_L', 'CLBLL_R', 'CLBLM_L', 'CLBLM_R']:

View File

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

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
def gen_sites(): def gen_sites():
db = Database(util.get_db_root()) db = Database(util.get_db_root())
grid = db.grid() grid = db.grid()
for tile_name in grid.tiles(): for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name) loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc) gridinfo = grid.gridinfo_at_loc(loc)
if gridinfo.tile_type in ['CLBLL_L', 'CLBLL_R', 'CLBLM_L', 'CLBLM_R']: if gridinfo.tile_type in ['CLBLL_L', 'CLBLL_R', 'CLBLM_L', 'CLBLM_R']:

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
def gen_sites(): def gen_sites():
db = Database(util.get_db_root()) db = Database(util.get_db_root())
grid = db.grid() grid = db.grid()
for tile_name in grid.tiles(): for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name) loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc) gridinfo = grid.gridinfo_at_loc(loc)
sites = [] sites = []

View File

@ -1,4 +1,4 @@
N ?= 30 N ?= 15
GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 1B" GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 1B"
include ../fuzzaddr/common.mk include ../fuzzaddr/common.mk

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
def gen_sites(): def gen_sites():
db = Database(util.get_db_root()) db = Database(util.get_db_root())
grid = db.grid() grid = db.grid()
for tile_name in grid.tiles(): for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name) loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc) gridinfo = grid.gridinfo_at_loc(loc)
if gridinfo.tile_type in ['DSP_L', 'DSP_R']: if gridinfo.tile_type in ['DSP_L', 'DSP_R']:

View File

@ -1,4 +1,4 @@
N ?= 10 N ?= 17
GENERATE_ARGS?="--oneval 0 --design params.csv --dword 1 --dframe 15" GENERATE_ARGS?="--oneval 0 --design params.csv --dword 1 --dframe 15"
include ../fuzzaddr/common.mk include ../fuzzaddr/common.mk

View File

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

View File

@ -1,3 +1,3 @@
N ?= 35 N ?= 15
GENERATE_ARGS?="--oneval KEEPER --dframe 27 --dword 3 --dbit 3" GENERATE_ARGS?="--oneval 1 --design params.csv --dframe 26 --dword 1"
include ../fuzzaddr/common.mk include ../fuzzaddr/common.mk

View File

@ -31,18 +31,13 @@ proc loc_pins {} {
set pin_lines [load_pin_lines] set pin_lines [load_pin_lines]
set io_pin_sites [make_io_pin_sites] set io_pin_sites [make_io_pin_sites]
set fp [open "design.csv" w]
puts $fp "port,site,tile,pin,val"
puts "Looping" puts "Looping"
for {set idx 0} {$idx < [llength $pin_lines]} {incr idx} { for {set idx 0} {$idx < [llength $pin_lines]} {incr idx} {
set line [lindex $pin_lines $idx] set line [lindex $pin_lines $idx]
puts "$line" puts "$line"
set site_str [lindex $line 0] set site_str [lindex $line 2]
set pin_str [lindex $line 1] set pin_str [lindex $line 3]
set io [lindex $line 2]
set cell_str [lindex $line 3]
# Have: site # Have: site
# Want: pin for site # Want: pin for site
@ -53,29 +48,9 @@ proc loc_pins {} {
set port [get_ports $pin_str] set port [get_ports $pin_str]
set tile [get_tiles -of_objects $site] set tile [get_tiles -of_objects $site]
set pin "FIXME"
set pin [dict get $io_pin_sites $site] set pin [dict get $io_pin_sites $site]
#set pin [get_property PACKAGE_PIN $port]
#set cell [get_cells $cell_str]
# puts "LOCing cell $cell to site $site (from bel $pad_bel)"
# set_property LOC $site $cell
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" $port set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" $port
# list_property isn't working
# set keys [list_property_value PULLTYPE $port]
set keys "NONE KEEPER"
set val [randsample_list 1 $keys]
if { $val == "NONE" } {
set val ""
}
set_property PULLTYPE $val $port
# puts "IOB $port $site $tile $pin $val"
puts $fp "$tile,$val,$site,$port,$pin"
} }
close $fp
} }
proc run {} { proc run {} {
@ -83,17 +58,12 @@ proc run {} {
read_verilog top.v read_verilog top.v
synth_design -top top synth_design -top top
# Mostly doesn't matter since IOB are special, but add anyway
create_pblock roi
add_cells_to_pblock [get_pblocks roi] [get_cells roi]
resize_pblock [get_pblocks roi] -add "$::env(XRAY_ROI_TILEGRID)"
loc_pins loc_pins
set_property CFGBVS VCCO [current_design] set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design] set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
set_param tcl.collectionResultDisplayLimit 0 set_property IS_ENABLED 0 [get_drc_checks {REQP-79}]
place_design place_design
route_design route_design

View File

@ -1,17 +1,12 @@
'''
Generate a primitive to place at every I/O
Unlike CLB tests, the LFSR for this is inside the ROI, not driving it
'''
import os import os
import random import random
random.seed(int(os.getenv("SEED"), 16)) random.seed(int(os.getenv("SEED"), 16))
from prjxray import util from prjxray import util
from prjxray.db import Database
from prjxray import verilog from prjxray import verilog
from prjxray.db import Database
def gen_iobs(): def gen_sites():
''' '''
IOB33S: main IOB of a diff pair IOB33S: main IOB of a diff pair
IOB33M: secondary IOB of a diff pair IOB33M: secondary IOB of a diff pair
@ -20,133 +15,62 @@ def gen_iobs():
''' '''
db = Database(util.get_db_root()) db = Database(util.get_db_root())
grid = db.grid() grid = db.grid()
for tile_name in grid.tiles(): for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name) loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc) gridinfo = grid.gridinfo_at_loc(loc)
for site_name, site_type in gridinfo.sites.items(): for site_name, site_type in gridinfo.sites.items():
if site_type in ['IOB33S']: if site_type == 'IOB33S':
yield site_name, site_type yield tile_name, site_name
def write_params(ports): def write_params(params):
pinstr = '' pinstr = ''
for site, (name, dir_, cell) in sorted(ports.items(), key=lambda x: x[1]): for tile, (site, val, pin) in sorted(params.items()):
# pinstr += 'set_property -dict "PACKAGE_PIN %s IOSTANDARD LVCMOS33" [get_ports %s]' % (packpin, port) pinstr += '%s,%s,%s,%s\n' % (tile, val, site, pin)
pinstr += '%s,%s,%s,%s\n' % (site, name, dir_, cell)
open('params.csv', 'w').write(pinstr) open('params.csv', 'w').write(pinstr)
def run(): def run():
# All possible values sites = list(gen_sites())
iosites = {}
for site_name, site_type in gen_iobs():
iosites[site_name] = site_type
# Assigned in this design
ports = {}
DIN_N = 0
DOUT_N = 0
def remain_sites():
return set(iosites.keys()) - set(ports.keys())
def rand_site():
'''Get a random, unused site'''
return random.choice(list(remain_sites()))
def assign_i(site, name):
nonlocal DIN_N
assert site not in ports
cell = "di_bufs[%u].ibuf" % DIN_N
DIN_N += 1
ports[site] = (name, 'input', cell)
def assign_o(site, name):
nonlocal DOUT_N
assert site not in ports
cell = "do_bufs[%u].obuf" % DOUT_N
DOUT_N += 1
ports[site] = (name, 'output', cell)
# Assign at least one di and one do
assign_i(rand_site(), 'di[0]')
assign_o(rand_site(), 'do[0]')
# Now assign the rest randomly
while len(remain_sites()):
if random.randint(0, 1):
assign_i(rand_site(), 'di[%u]' % DIN_N)
else:
assign_o(rand_site(), 'do[%u]' % DOUT_N)
write_params(ports)
print( print(
''' '''
`define N_DI %u `define N_DI {}
`define N_DO %u
module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do);
genvar i;
//Instantiate BUFs so we can LOC them
module top(input wire [`N_DI-1:0] di);
wire [`N_DI-1:0] di_buf; wire [`N_DI-1:0] di_buf;
generate '''.format(len(sites)))
for (i = 0; i < `N_DI; i = i+1) begin:di_bufs
IBUF ibuf(.I(di[i]), .O(di_buf[i]));
end
endgenerate
wire [`N_DO-1:0] do_unbuf; params = {}
generate print('''
for (i = 0; i < `N_DO; i = i+1) begin:do_bufs (* KEEP, DONT_TOUCH *)
OBUF obuf(.I(do_unbuf[i]), .O(do[i])); LUT6 dummy_lut();''')
end
endgenerate
roi roi(.di(di_buf), .do(do_unbuf)); for idx, ((tile_name, site_name), isone) in enumerate(zip(
endmodule sites, util.gen_fuzz_states(len(sites)))):
params[tile_name] = (site_name, isone, "di[%u]" % idx)
print('''
(* KEEP, DONT_TOUCH *)
IBUF #(
) ibuf_{site_name} (
.I(di[{idx}]),
.O(di_buf[{idx}])
);'''.format(
site_name=site_name,
idx=idx))
//Arbitrary terminate into LUTs if isone:
module roi(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do); print('''
genvar i; (* KEEP, DONT_TOUCH *)
PULLUP #(
) pullup_{site_name} (
.O(di[{idx}])
);'''.format(
site_name=site_name,
idx=idx))
generate print("endmodule")
for (i = 0; i < `N_DI; i = i+1) begin:dis write_params(params)
(* KEEP, DONT_TOUCH *)
LUT6 #(
.INIT(64'h8000_0000_0000_0001)
) lut (
.I0(di[i]),
.I1(di[i]),
.I2(di[i]),
.I3(di[i]),
.I4(di[i]),
.I5(di[i]),
.O());
end
endgenerate
generate
for (i = 0; i < `N_DO; i = i+1) begin:dos
(* KEEP, DONT_TOUCH *)
LUT6 #(
.INIT(64'h8000_0000_0000_0001)
) lut (
.I0(),
.I1(),
.I2(),
.I3(),
.I4(),
.I5(),
.O(do[i]));
end
endgenerate
endmodule
''' % (DIN_N, DOUT_N))
if __name__ == '__main__': if __name__ == '__main__':

View File

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

View File

@ -1,4 +1,4 @@
N ?= 2 N ?= 5
# Was expecting oneval 3, but bits might be inverted # Was expecting oneval 3, but bits might be inverted
# FIXME: dword # FIXME: dword
# Ex: 0002009D_029_15 # Ex: 0002009D_029_15

View File

@ -2,13 +2,17 @@ import os
import random import random
random.seed(int(os.getenv("SEED"), 16)) random.seed(int(os.getenv("SEED"), 16))
from prjxray import util from prjxray import util
from prjxray import verilog from prjxray.db import Database
def gen_sites(): def gen_sites():
for tile_name, site_name, _site_type in util.get_roi().gen_sites( db = Database(util.get_db_root())
['MMCME2_ADV']): grid = db.grid()
yield tile_name, site_name for tile_name in sorted(grid.tiles()):
gridinfo = grid.gridinfo_at_tilename(tile_name)
for site_name, site_type in gridinfo.sites.items():
if site_type in ['MMCME2_ADV']:
yield tile_name, site_name
def write_params(params): def write_params(params):
@ -47,7 +51,6 @@ module top(input clk, stb, di, output do);
# FIXME: can't LOC? # FIXME: can't LOC?
# only one for now, worry about later # only one for now, worry about later
sites = list(gen_sites()) sites = list(gen_sites())
assert len(sites) == 1, len(sites)
for (tile_name, site_name), isone in zip(sites, for (tile_name, site_name), isone in zip(sites,
util.gen_fuzz_states(len(sites))): util.gen_fuzz_states(len(sites))):
# 0 is invalid # 0 is invalid

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
def gen_sites(): def gen_sites():
db = Database(util.get_db_root()) db = Database(util.get_db_root())
grid = db.grid() grid = db.grid()
for tile_name in grid.tiles(): for tile_name in sorted(grid.tiles()):
loc = grid.loc_of_tilename(tile_name) loc = grid.loc_of_tilename(tile_name)
gridinfo = grid.gridinfo_at_loc(loc) gridinfo = grid.gridinfo_at_loc(loc)

View File

@ -1,6 +1,3 @@
N ?= 2 N ?= 5
# Was expecting oneval 3, but bits might be inverted GENERATE_ARGS?="--oneval 1 --design params.csv --dframe 1C --dword 98"
# FIXME: dword
# Ex: 0002009C_077_16
GENERATE_ARGS?="--oneval 2 --design params.csv --dframe 1C --dword 77 --dbit 16"
include ../fuzzaddr/common.mk include ../fuzzaddr/common.mk

View File

@ -5,16 +5,10 @@ proc run {} {
read_verilog top.v read_verilog top.v
synth_design -top top synth_design -top top
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk]
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_01) IOSTANDARD LVCMOS33" [get_ports stb]
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_02) IOSTANDARD LVCMOS33" [get_ports di]
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_03) IOSTANDARD LVCMOS33" [get_ports do]
set_property CFGBVS VCCO [current_design] set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design] set_property CONFIG_VOLTAGE 3.3 [current_design]
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
# Disable MMCM frequency etc sanity checks # Disable MMCM frequency etc sanity checks
set_property IS_ENABLED 0 [get_drc_checks {PDRC-29}] set_property IS_ENABLED 0 [get_drc_checks {PDRC-29}]
set_property IS_ENABLED 0 [get_drc_checks {PDRC-30}] set_property IS_ENABLED 0 [get_drc_checks {PDRC-30}]

View File

@ -3,12 +3,17 @@ import random
random.seed(int(os.getenv("SEED"), 16)) random.seed(int(os.getenv("SEED"), 16))
from prjxray import util from prjxray import util
from prjxray import verilog from prjxray import verilog
from prjxray.db import Database
def gen_sites(): def gen_sites():
for tile_name, site_name, _site_type in util.get_roi().gen_sites( db = Database(util.get_db_root())
['PLLE2_ADV']): grid = db.grid()
yield tile_name, site_name for tile_name in sorted(grid.tiles()):
gridinfo = grid.gridinfo_at_tilename(tile_name)
for site_name, site_type in gridinfo.sites.items():
if site_type in ['PLLE2_ADV']:
yield tile_name, site_name
def write_params(params): def write_params(params):
@ -21,66 +26,25 @@ def write_params(params):
def run(): def run():
print( print(
''' '''
module top(input clk, stb, di, output do); module top();
localparam integer DIN_N = 8;
localparam integer DOUT_N = 8;
reg [DIN_N-1:0] din;
wire [DOUT_N-1:0] dout;
reg [DIN_N-1:0] din_shr;
reg [DOUT_N-1:0] dout_shr;
always @(posedge clk) begin
din_shr <= {din_shr, di};
dout_shr <= {dout_shr, din_shr[DIN_N-1]};
if (stb) begin
din <= din_shr;
dout_shr <= dout;
end
end
assign do = dout_shr[DOUT_N-1];
''') ''')
params = {} params = {}
# FIXME: can't LOC? # FIXME: can't LOC?
# only one for now, worry about later # only one for now, worry about later
sites = list(gen_sites()) sites = list(gen_sites())
assert len(sites) == 1
for (tile_name, site_name), isone in zip(sites, for (tile_name, site_name), isone in zip(sites,
util.gen_fuzz_states(len(sites))): util.gen_fuzz_states(len(sites))):
# 0 is invalid params[tile_name] = (site_name, isone)
# shift one bit, keeping LSB constant
CLKOUT1_DIVIDE = {0: 2, 1: 3}[isone]
params[tile_name] = (site_name, CLKOUT1_DIVIDE)
print( print(
''' '''
(* KEEP, DONT_TOUCH *) (* KEEP, DONT_TOUCH, LOC = "{site_name}" *)
PLLE2_ADV #(/*.LOC("%s"),*/ .CLKOUT1_DIVIDE(%u)) dut_%s( PLLE2_ADV #( .STARTUP_WAIT({isone}) ) dut_{site_name} ();
.CLKFBOUT(), '''.format(
.CLKOUT0(), site_name=site_name,
.CLKOUT1(), isone=verilog.quote('TRUE' if isone else 'FALSE'),
.CLKOUT2(), ))
.CLKOUT3(),
.CLKOUT4(),
.CLKOUT5(),
.DRDY(),
.LOCKED(),
.DO(),
.CLKFBIN(),
.CLKIN1(),
.CLKIN2(),
.CLKINSEL(),
.DCLK(),
.DEN(),
.DWE(),
.PWRDWN(),
.RST(),
.DI(),
.DADDR());
''' % (site_name, CLKOUT1_DIVIDE, site_name))
print("endmodule") print("endmodule")
write_params(params) write_params(params)

View File

@ -1,4 +1,6 @@
import math
import os import os
import random
import re import re
from .roi import Roi from .roi import Roi
@ -233,17 +235,37 @@ def gen_fuzz_states(nvals):
0101 0101
1010 1010
''' '''
bits = 0 next_p2_states = 2**math.ceil(math.log(nvals, 2))
# First pass all 0's n = next_p2_states
for speci in range(2, specn() + 1):
# First pass do nothing full_mask = 2**next_p2_states-1
# Second pass invert every other bit (mod 2)
# Third pass invert blocks of two (mod 4) choices = []
block_size = 2**(speci - 1) invert_choices = []
for maski in range(nvals):
mask = (1 << maski) num_or = 1
if maski % block_size < block_size / 2: while n > 0:
bits ^= mask mask = 2**n-1
val = 0
for offset in range(0, num_or, 2):
shift = offset*next_p2_states//num_or
val |= mask << shift
choices.append(full_mask ^ val)
invert_choices.append(val)
n //= 2
num_or *= 2
choices.extend(invert_choices)
spec_idx = specn() - 1
if spec_idx < len(choices):
bits = choices[spec_idx]
else:
bits = random.randint(0, 2**next_p2_states)
for i in range(nvals): for i in range(nvals):
mask = (1 << i) mask = (1 << i)