Merge pull request #310 from mcmasterg/iob_bits1

IOB bit test
This commit is contained in:
John McMaster 2018-12-10 17:41:52 -08:00 committed by GitHub
commit 35d7906251
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 325 additions and 0 deletions

26
fuzzers/030-iob/Makefile Normal file
View File

@ -0,0 +1,26 @@
N := 1
SPECIMENS := $(addprefix build/specimen_,$(shell seq -f '%03.0f' $(N)))
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
database: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -o build/segbits_ioblx.db $(addsuffix /segdata_ioblm_[lr].txt,$(SPECIMENS))
#pushdb:
# ${XRAY_MERGEDB} ioblm_l build/segbits_ioblx.db
# ${XRAY_MERGEDB} ioblm_r build/segbits_ioblx.db
$(SPECIMENS_OK):
bash generate.sh $(subst /OK,,$@)
touch $@
run:
$(MAKE) clean
$(MAKE) database
$(MAKE) pushdb
touch run.ok
clean:
rm -rf build
.PHONY: database pushdb run clean

View File

@ -0,0 +1,4 @@
# NDI1MUX Fuzzer
See minitest for DI notes

View File

@ -0,0 +1,28 @@
#!/usr/bin/env python3
from prjxray.segmaker import Segmaker
segmk = Segmaker("design.bits")
print("Loading tags")
'''
port,site,tile,pin,val
di[0],IOB_X0Y107,LIOB33_X0Y107,A21,PULLDOWN
di[10],IOB_X0Y147,LIOB33_X0Y147,F14,PULLUP
'''
f = open('design.csv', 'r')
f.readline()
for l in f:
l = l.strip()
port, site, tile, pin, val = l.split(',')
'''
PULLTYPE 28 29 30
NONE X
KEEPER X X
PULLDOWN
PULLUP X X
'''
segmk.add_site_tag(site, "PULL.NONE", val in ("NONE", "KEEPER", "PULLUP"))
segmk.compile()
segmk.write()

View File

@ -0,0 +1,5 @@
#!/bin/bash
set -ex
source ${XRAY_DIR}/utils/top_generate.sh

View File

@ -0,0 +1,102 @@
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]
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 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]
# Have: site
# Want: pin for site
set site [get_sites $site_str]
set pad_bel [get_bels -of_objects $site -filter {TYPE =~ PAD && NAME =~ IOB_*}]
# set port [get_ports -of_objects $site]
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 "PULLUP PULLDOWN KEEPER"
set val [randsample_list 1 $keys]
set_property PULLTYPE $val $port
# puts "IOB $port $site $tile $pin $val"
puts $fp "$port,$site,$tile,$pin,$val"
}
close $fp
}
proc run {} {
create_project -force -part $::env(XRAY_PART) design design
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)"
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
place_design
route_design
write_checkpoint -force design.dcp
write_bitstream -force design.bit
}
run

147
fuzzers/030-iob/top.py Normal file
View File

@ -0,0 +1,147 @@
'''
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 import verilog
def gen_iobs():
'''
IOB33S: main IOB of a diff pair
IOB33M: secondary IOB of a diff pair
IOB33: not a diff pair. Relatively rare (at least in ROI...2 of them?)
Focus on IOB33S to start
'''
for _tile_name, site_name, site_type in util.get_roi().gen_sites(
#['IOB33', 'IOB33S', 'IOB33M']):
['IOB33S']):
yield site_name, site_type
def write_pins(ports):
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)
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_pins(ports)
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
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
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
roi roi(.di(di_buf), .do(do_unbuf));
endmodule
//Arbitrary terminate into LUTs
module roi(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do);
genvar i;
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))
if __name__ == '__main__':
run()

View File

@ -251,6 +251,18 @@ class Segmaker:
else:
assert False, "Invalid name in %s" % site
def name_y0y1():
# RAMB18_X0Y41
m = re.match(r"^(.*)_X.*Y[0-9]*[02468]$", site)
if m:
return "%s_Y0" % m.group(1)
m = re.match(r"^(.*)_X.*Y[0-9]*[13579]$", site)
if m:
return "%s_Y1" % m.group(1)
assert 0, site
def name_default():
# most sites are unique within their tile
# TODO: maybe verify against DB?
@ -259,6 +271,7 @@ class Segmaker:
sitekey = {
'SLICE': name_slice,
'RAMB18': name_bram18,
'IOB': name_y0y1,
}.get(site_prefix, name_default)()
self.verbose and print(
'site %s w/ %s prefix => tag %s' %