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"
include ../fuzzaddr/common.mk

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
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)

View File

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

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
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)

View File

@ -1,4 +1,4 @@
N ?= 30
N ?= 15
GENERATE_ARGS?="--oneval 0 --design params.csv --dword 1 --dframe 15"
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"
include ../fuzzaddr/common.mk

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
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)
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"
include ../fuzzaddr/common.mk

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
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)
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():
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)
sites = []

View File

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

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
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)
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"
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"
include ../fuzzaddr/common.mk

View File

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

View File

@ -31,18 +31,13 @@ proc loc_pins {} {
set pin_lines [load_pin_lines]
set io_pin_sites [make_io_pin_sites]
set fp [open "design.csv" w]
puts $fp "port,site,tile,pin,val"
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 0]
set pin_str [lindex $line 1]
set io [lindex $line 2]
set cell_str [lindex $line 3]
set site_str [lindex $line 2]
set pin_str [lindex $line 3]
# Have: site
# Want: pin for site
@ -53,29 +48,9 @@ proc loc_pins {} {
set port [get_ports $pin_str]
set tile [get_tiles -of_objects $site]
set pin "FIXME"
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
# 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 {} {
@ -83,17 +58,12 @@ proc run {} {
read_verilog top.v
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
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [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
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 random
random.seed(int(os.getenv("SEED"), 16))
from prjxray import util
from prjxray.db import Database
from prjxray import verilog
from prjxray.db import Database
def gen_iobs():
def gen_sites():
'''
IOB33S: main 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())
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)
for site_name, site_type in gridinfo.sites.items():
if site_type in ['IOB33S']:
yield site_name, site_type
if site_type == 'IOB33S':
yield tile_name, site_name
def write_params(ports):
def write_params(params):
pinstr = ''
for site, (name, dir_, cell) in sorted(ports.items(), key=lambda x: x[1]):
# pinstr += 'set_property -dict "PACKAGE_PIN %s IOSTANDARD LVCMOS33" [get_ports %s]' % (packpin, port)
pinstr += '%s,%s,%s,%s\n' % (site, name, dir_, cell)
for tile, (site, val, pin) in sorted(params.items()):
pinstr += '%s,%s,%s,%s\n' % (tile, val, site, pin)
open('params.csv', 'w').write(pinstr)
def run():
# All possible values
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)
sites = list(gen_sites())
print(
'''
`define N_DI %u
`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
`define N_DI {}
module top(input wire [`N_DI-1:0] di);
wire [`N_DI-1:0] di_buf;
generate
for (i = 0; i < `N_DI; i = i+1) begin:di_bufs
IBUF ibuf(.I(di[i]), .O(di_buf[i]));
end
endgenerate
'''.format(len(sites)))
wire [`N_DO-1:0] do_unbuf;
generate
for (i = 0; i < `N_DO; i = i+1) begin:do_bufs
OBUF obuf(.I(do_unbuf[i]), .O(do[i]));
end
endgenerate
params = {}
print('''
(* KEEP, DONT_TOUCH *)
LUT6 dummy_lut();''')
roi roi(.di(di_buf), .do(do_unbuf));
endmodule
for idx, ((tile_name, site_name), isone) in enumerate(zip(
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
module roi(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do);
genvar i;
if isone:
print('''
(* KEEP, DONT_TOUCH *)
PULLUP #(
) pullup_{site_name} (
.O(di[{idx}])
);'''.format(
site_name=site_name,
idx=idx))
generate
for (i = 0; i < `N_DI; i = i+1) begin:dis
(* 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))
print("endmodule")
write_params(params)
if __name__ == '__main__':

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@ from prjxray.db import Database
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)

View File

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

View File

@ -5,16 +5,10 @@ proc run {} {
read_verilog top.v
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 CONFIG_VOLTAGE 3.3 [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
set_property IS_ENABLED 0 [get_drc_checks {PDRC-29}]
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))
from prjxray import util
from prjxray import verilog
from prjxray.db import Database
def gen_sites():
for tile_name, site_name, _site_type in util.get_roi().gen_sites(
['PLLE2_ADV']):
yield tile_name, site_name
db = Database(util.get_db_root())
grid = db.grid()
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):
@ -21,66 +26,25 @@ def write_params(params):
def run():
print(
'''
module top(input clk, stb, di, output do);
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];
module top();
''')
params = {}
# FIXME: can't LOC?
# only one for now, worry about later
sites = list(gen_sites())
assert len(sites) == 1
for (tile_name, site_name), isone in zip(sites,
util.gen_fuzz_states(len(sites))):
# 0 is invalid
# shift one bit, keeping LSB constant
CLKOUT1_DIVIDE = {0: 2, 1: 3}[isone]
params[tile_name] = (site_name, CLKOUT1_DIVIDE)
params[tile_name] = (site_name, isone)
print(
'''
(* KEEP, DONT_TOUCH *)
PLLE2_ADV #(/*.LOC("%s"),*/ .CLKOUT1_DIVIDE(%u)) dut_%s(
.CLKFBOUT(),
.CLKOUT0(),
.CLKOUT1(),
.CLKOUT2(),
.CLKOUT3(),
.CLKOUT4(),
.CLKOUT5(),
.DRDY(),
.LOCKED(),
.DO(),
.CLKFBIN(),
.CLKIN1(),
.CLKIN2(),
.CLKINSEL(),
.DCLK(),
.DEN(),
.DWE(),
.PWRDWN(),
.RST(),
.DI(),
.DADDR());
''' % (site_name, CLKOUT1_DIVIDE, site_name))
(* KEEP, DONT_TOUCH, LOC = "{site_name}" *)
PLLE2_ADV #( .STARTUP_WAIT({isone}) ) dut_{site_name} ();
'''.format(
site_name=site_name,
isone=verilog.quote('TRUE' if isone else 'FALSE'),
))
print("endmodule")
write_params(params)

View File

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