diff --git a/fuzzers/038-cfg/Makefile b/fuzzers/038-cfg/Makefile new file mode 100644 index 00000000..4b2c308c --- /dev/null +++ b/fuzzers/038-cfg/Makefile @@ -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 + diff --git a/fuzzers/038-cfg/README.md b/fuzzers/038-cfg/README.md new file mode 100644 index 00000000..04769fba --- /dev/null +++ b/fuzzers/038-cfg/README.md @@ -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. diff --git a/fuzzers/038-cfg/bits.dbf b/fuzzers/038-cfg/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/038-cfg/generate.py b/fuzzers/038-cfg/generate.py new file mode 100644 index 00000000..2f327b2d --- /dev/null +++ b/fuzzers/038-cfg/generate.py @@ -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() diff --git a/fuzzers/038-cfg/generate.sh b/fuzzers/038-cfg/generate.sh new file mode 100644 index 00000000..f42f840c --- /dev/null +++ b/fuzzers/038-cfg/generate.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -ex +source ${XRAY_DIR}/utils/top_generate.sh + diff --git a/fuzzers/038-cfg/generate.tcl b/fuzzers/038-cfg/generate.tcl new file mode 100644 index 00000000..79d768e9 --- /dev/null +++ b/fuzzers/038-cfg/generate.tcl @@ -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 diff --git a/fuzzers/038-cfg/top.py b/fuzzers/038-cfg/top.py new file mode 100644 index 00000000..86e45a48 --- /dev/null +++ b/fuzzers/038-cfg/top.py @@ -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() diff --git a/fuzzers/Makefile b/fuzzers/Makefile index 411e733d..b0662990 100644 --- a/fuzzers/Makefile +++ b/fuzzers/Makefile @@ -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)) diff --git a/utils/mergedb.sh b/utils/mergedb.sh index 8a39763c..f47548c3 100755 --- a/utils/mergedb.sh +++ b/utils/mergedb.sh @@ -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