038-cfg: Add fuzzer for the CFG tile

Signed-off-by: Tomasz Michalak <tmichalak@antmicro.com>
This commit is contained in:
Tomasz Michalak 2019-06-25 15:32:14 +02:00
parent e8fdac9f70
commit f5ba30a81c
9 changed files with 428 additions and 0 deletions

17
fuzzers/038-cfg/Makefile Normal file
View File

@ -0,0 +1,17 @@
N = 24
include ../fuzzer.mk
database: build/segbits_cfg.rdb
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf \
--seg-fn-in build/segbits_cfg.rdb \
--seg-fn-out build/segbits_cfg.db
build/segbits_cfg.rdb: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -c 15 -o build/segbits_cfg.rdb $$(find -name segdata_cfg_center_mid.txt)
pushdb:
${XRAY_MERGEDB} cfg_center_mid build/segbits_cfg.db
.PHONY: database pushdb

View File

@ -0,0 +1,4 @@
This fuzzer solves some of the bits in the CFG_CENTER_MID tile
The tile contains sites of the following types: BSCAN, USR_ACCESS, CAPTURE, STARTUP, FRAME_ECC, DCIRESET and ICAP.
DCIRESET and USR_ACCESS don't really have any parameters.
The parameters on CAPTURE and FRAME_ECC don't toggle any bits in the bitstream.

0
fuzzers/038-cfg/bits.dbf Normal file
View File

View File

@ -0,0 +1,56 @@
#!/usr/bin/env python3
import json
from prjxray.segmaker import Segmaker
from prjxray import verilog
from prjxray import segmaker
def bitfilter(frame, word):
if frame < 26:
return False
return True
def run():
segmk = Segmaker("design.bits")
print("Loading tags")
f = open('params.jl', 'r')
design = json.load(f)
for p in design:
ps = p["params"]
if p["site_type"] in "ICAP":
param = verilog.unquote(ps["ICAP_WIDTH"])
segmaker.add_site_group_zero(
segmk, p["site"], "ICAP_WIDTH_", ["X32", "X8", "X16"], "X32",
param)
elif p["site_type"] in "BSCAN":
param = str(ps["JTAG_CHAIN"])
segmaker.add_site_group_zero(
segmk, p["site"], "JTAG_CHAIN_", ["1", "2", "3", "4"], param,
param)
elif p["site_type"] in "CAPTURE":
param = verilog.unquote(ps["ONESHOT"])
segmk.add_site_tag(
p["site"], "ONESHOT", True if param in "TRUE" else False)
elif p["site_type"] in "STARTUP":
param = verilog.unquote(ps["PROG_USR"])
segmk.add_site_tag(
p["site"], "PROG_USR", True if param in "TRUE" else False)
elif p["site_type"] in "FRAME_ECC":
param = verilog.unquote(ps["FARSRC"])
segmaker.add_site_group_zero(
segmk, p["site"], "FARSRC_", ["FAR", "EFAR"], param, param)
elif p["site_type"] in ["USR_ACCESS", "DCIRESET"]:
feature = "ENABLED"
segmk.add_site_tag(
p["site"], feature, True if ps["ENABLED"] else False)
segmk.compile(bitfilter=bitfilter)
segmk.write()
run()

View File

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

View File

@ -0,0 +1,35 @@
create_project -force -part $::env(XRAY_PART) design design
#read_verilog $::env(FUZDIR)/top.v
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]
create_pblock roi
add_cells_to_pblock [get_pblocks roi] [get_cells roi]
resize_pblock [get_pblocks roi] -add "$::env(XRAY_ROI)"
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]
set_property IS_ENABLED 0 [get_drc_checks {DRC NDRV-1}]
# 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}]
#set_property IS_ENABLED 0 [get_drc_checks {AVAL-50}]
#set_property IS_ENABLED 0 [get_drc_checks {AVAL-53}]
#set_property IS_ENABLED 0 [get_drc_checks {REQP-126}]
# PLL
#set_property IS_ENABLED 0 [get_drc_checks {REQP-161}]
place_design
route_design
write_checkpoint -force design.dcp
write_bitstream -force design.bit

307
fuzzers/038-cfg/top.py Normal file
View File

@ -0,0 +1,307 @@
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)
for site_name, site_type in gridinfo.sites.items():
if site_type in ['BSCAN', 'CAPTURE', 'ICAP', 'USR_ACCESS',
'STARTUP', 'FRAME_ECC', 'DCIRESET']:
if site_name not in 'ICAP_X0Y0':
yield site_name, site_type
def write_csv_params(params):
pinstr = 'tile,site,\n'
for vals in params:
pinstr += ','.join(map(str, vals)) + '\n'
open('params.csv', 'w').write(pinstr)
def generate_params():
bscan_already_on = False
icap_already_on = False
tile_params = []
for loci, (site, site_type) in enumerate(sorted(gen_sites())):
p = {}
if site_type in "ICAP" and not icap_already_on:
p["ICAP_WIDTH"] = verilog.quote(
random.choice(["X32", "X8", "X16"]))
elif site_type in "BSCAN" and not bscan_already_on:
p["JTAG_CHAIN"] = random.randint(1, 4)
bscan_already_on = True
elif site_type in "CAPTURE":
p["ONESHOT"] = verilog.quote(random.choice(["TRUE", "FALSE"]))
elif site_type in "STARTUP":
p["PROG_USR"] = verilog.quote(random.choice(["TRUE", "FALSE"]))
elif site_type in "FRAME_ECC":
p["FARSRC"] = verilog.quote(random.choice(["FAR", "EFAR"]))
elif site_type in [
"DCIRESET", "USR_ACCESS"
]: #The primitives from these sites have no parameters
p["ENABLED"] = random.randint(0, 1)
else:
continue
p["LOC"] = verilog.quote(site)
tile_params.append(
{
"site": site,
"site_type": site_type,
"module": "mod_{}".format(site_type),
"params": p
})
return tile_params
def generate_netlist(params):
DUTN = len(params)
DIN_N = DUTN * 32
DOUT_N = DUTN * 32
string_output = io.StringIO()
any_bscan = False
any_icap = False
usr_access_on = False
capture_on = False
startup_on = False
frame_ecc_on = False
dcireset_on = False
luts = lut_maker.LutMaker()
verilog.top_harness(DIN_N, DOUT_N)
print(
'''
module roi(input clk, input [%d:0] din, output [%d:0] dout);''' %
(DIN_N - 1, DOUT_N - 1))
for loci, param in enumerate(params):
ports = {
'din': 'din[{} +: 8]'.format(8 * loci),
'dout': 'dout[{} +: 8]'.format(8 * loci),
'clk': 'clk'
}
if param["site_type"] in "BSCAN":
ports = {
'din':
'{{din[{} +: 7],{}}}'.format(
8 * loci + 1, luts.get_next_output_net()),
'dout':
'{{dout[{} +: 7],{}}}'.format(
8 * loci + 1, luts.get_next_input_net()),
'clk':
'clk'
}
any_bscan = True
elif param["site_type"] in ["ICAP"]:
any_icap = True
elif param["site_type"] in ["CAPTURE"]:
capture_on = True
elif param["site_type"] in ["STARTUP"]:
startup_on = True
elif param["site_type"] in ["FRAME_ECC"]:
frame_ecc_on = True
elif param["site_type"] in ["USR_ACCESS", "DCIRESET"]:
if not param["params"]["ENABLED"]:
continue
if param["site_type"] in ["DCIRESET"]:
dcireset_on = True
else:
usr_access_on = True
else:
continue
verilog.instance(
param["module"],
"inst_{}".format(param["site"]),
ports,
param["params"],
string_buffer=string_output)
#Generate LUTs
for l in luts.create_wires_and_luts():
print(l)
print(string_output.getvalue())
print(
'''
endmodule
// ---------------------------------------------------------------------''')
if any_icap:
print(
'''
module mod_ICAP (input [7:0] din, output [7:0] dout, input clk);
parameter ICAP_WIDTH = "X32";
parameter LOC = "ICAP_X0Y0";
wire [23:0] icap_out;
(* KEEP, DONT_TOUCH, LOC=LOC *)
ICAPE2 #(
.ICAP_WIDTH(ICAP_WIDTH),
.SIM_CFG_FILE_NAME("NONE")
)
ICAPE2_inst (
.O({icap_out, dout}),
.CLK(clk),
.CSIB(),
.I({24'd0, din}),
.RDWRB()
);
endmodule
''')
if capture_on:
print(
'''
module mod_CAPTURE (input [7:0] din, output [7:0] dout, input clk);
parameter ONESHOT ="TRUE";
parameter LOC = "ICAP_X0Y0";
(* KEEP, DONT_TOUCH, LOC=LOC *)
CAPTUREE2 #(
.ONESHOT(ONESHOT) // Specifies the procedure for performing single readback per CAP trigger.
)
CAPTUREE2_inst (
.CAP(1'b0),
.CLK(clk)
);
endmodule
''')
if usr_access_on:
print(
'''
module mod_USR_ACCESS (input [7:0] din, output [7:0] dout, input clk);
parameter ENABLED = 1;
parameter LOC = "USR_ACCESS_X0Y0";
wire [23:0] usr_access_wire;
(* KEEP, DONT_TOUCH, LOC=LOC *)
USR_ACCESSE2 USR_ACCESSE2_inst (
.CFGCLK(),
.DATA({usr_access_wire, dout}),
.DATAVALID()
);
endmodule
''')
if any_bscan:
print(
'''
module mod_BSCAN (input [7:0] din, output [7:0] dout, input clk);
parameter JTAG_CHAIN = 1;
parameter LOC = "BSCAN_X0Y0";
(* KEEP, DONT_TOUCH, LOC=LOC *)
BSCANE2 #(
.JTAG_CHAIN(JTAG_CHAIN)
)
dut (
.CAPTURE(),
.DRCK(),
.RESET(),
.RUNTEST(),
.SEL(),
.SHIFT(),
.TCK(),
.TDI(dout[0]),
.TMS(),
.UPDATE(),
.TDO(din[0])
);
endmodule
''')
if startup_on:
print(
'''
module mod_STARTUP (input [7:0] din, output [7:0] dout, input clk);
parameter LOC = "STARTUP_X0Y0";
parameter PROG_USR = "FALSE";
(* KEEP, DONT_TOUCH, LOC=LOC *)
STARTUPE2 #(
.PROG_USR(PROG_USR), // Activate program event security feature. Requires encrypted bitstreams.
.SIM_CCLK_FREQ(0.0) // Set the Configuration Clock Frequency(ns) for simulation.
)
STARTUPE2_inst (
.CFGCLK(),
.CFGMCLK(),
.EOS(),
.PREQ(dout[0]),
.CLK(clk),
.GSR(),
.GTS(),
.KEYCLEARB(),
.PACK(),
.USRCCLKO(),
.USRCCLKTS(),
.USRDONEO(),
.USRDONETS()
);
endmodule
''')
if frame_ecc_on:
print(
'''
module mod_FRAME_ECC (input [7:0] din, output [7:0] dout, input clk);
parameter LOC = "FRAME_ECC_X0Y0";
parameter FARSRC = "EFAR";
wire [25:0] far_wire;
assign dout[7:0] = far_wire[7:0];
(* KEEP, DONT_TOUCH, LOC=LOC *)
FRAME_ECCE2 #(
.FARSRC(FARSRC),
.FRAME_RBT_IN_FILENAME("NONE")
)
FRAME_ECCE2_inst (
.CRCERROR(),
.ECCERROR(),
.ECCERRORSINGLE(),
.FAR(far_wire),
.SYNBIT(),
.SYNDROME(),
.SYNDROMEVALID(),
.SYNWORD()
);
endmodule
''')
if dcireset_on:
print(
'''
module mod_DCIRESET (input [7:0] din, output [7:0] dout, input clk);
parameter LOC = "FRAME_ECC_X0Y0";
parameter ENABLED = 1;
(* KEEP, DONT_TOUCH, LOC=LOC *)
DCIRESET DCIRESET_inst (
.LOCKED(dout[0]),
.RST(dout[1])
);
endmodule
''')
def run():
params = generate_params()
generate_netlist(params)
with open('params.jl', 'w') as f:
json.dump(params, f, indent=2)
if __name__ == '__main__':
run()

View File

@ -87,6 +87,7 @@ $(eval $(call fuzzer,032-cmt-pll,005-tilegrid))
$(eval $(call fuzzer,034-cmt-pll-pips,005-tilegrid))
$(eval $(call fuzzer,035-iob-ilogic,005-tilegrid))
$(eval $(call fuzzer,036-iob-ologic,005-tilegrid))
$(eval $(call fuzzer,038-cfg,005-tilegrid))
$(eval $(call fuzzer,040-clk-hrow-config,005-tilegrid))
$(eval $(call fuzzer,041-clk-hrow-pips,005-tilegrid))
$(eval $(call fuzzer,042-clk-bufg-config,005-tilegrid))

View File

@ -120,6 +120,9 @@ case "$1" in
cmt_top_l_upper_t)
sed < "$2" > "$tmp1" -e 's/^CMT_UPPER_T\./CMT_TOP_L_UPPER_T./' ;;
cfg_center_mid)
cp "$2" "$tmp1" ;;
mask_*)
db=$XRAY_DATABASE_DIR/$XRAY_DATABASE/$1.db
ismask=true