diff --git a/fuzzers/031-mmcm/.gitignore b/fuzzers/031-mmcm/.gitignore new file mode 100644 index 00000000..378eac25 --- /dev/null +++ b/fuzzers/031-mmcm/.gitignore @@ -0,0 +1 @@ +build diff --git a/fuzzers/031-mmcm/Makefile b/fuzzers/031-mmcm/Makefile new file mode 100644 index 00000000..bfbe7b23 --- /dev/null +++ b/fuzzers/031-mmcm/Makefile @@ -0,0 +1,19 @@ +# read/write width is relatively slow to resolve +# Even slower with multi bit masks... +N := 8 +include ../fuzzer.mk + +database: build/segbits_bramx.db + +build/segbits_bramx.rdb: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -o build/segbits_bramx.rdb $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS)) + +build/segbits_bramx.db: build/segbits_bramx.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@ + +pushdb: + ${XRAY_MERGEDB} bram_l build/segbits_bramx.db + ${XRAY_MERGEDB} bram_r build/segbits_bramx.db + +.PHONY: database pushdb + diff --git a/fuzzers/031-mmcm/README.md b/fuzzers/031-mmcm/README.md new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/031-mmcm/bits.dbf b/fuzzers/031-mmcm/bits.dbf new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/031-mmcm/generate.py b/fuzzers/031-mmcm/generate.py new file mode 100644 index 00000000..38292875 --- /dev/null +++ b/fuzzers/031-mmcm/generate.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +import json + +from prjxray.segmaker import Segmaker +from prjxray import verilog + + +def bus_tags(segmk, ps, site): + for param, tagname in [('CLKOUT1_DIVIDE', 'ZCLKOUT1_DIVIDE')]: + # 1-128 => 0-127 for actual 7 bit value + paramadj = int(ps[param]) - 1 + bitstr = [int(x) for x in "{0:07b}".format(paramadj)[::-1]] + # FIXME: only bits 0 and 1 resolving + # for i in range(7): + for i in range(2): + segmk.add_site_tag(site, '%s[%u]' % (param, i), 1 ^ bitstr[i]) + + +def run(): + + segmk = Segmaker("design.bits") + + print("Loading tags") + f = open('params.jl', 'r') + f.readline() + for l in f: + j = json.loads(l) + ps = j['params'] + assert j['module'] == 'my_MMCME2_ADV' + site = verilog.unquote(ps['LOC']) + + bus_tags(segmk, ps, site) + + segmk.compile() + segmk.write() + + +run() diff --git a/fuzzers/031-mmcm/generate.sh b/fuzzers/031-mmcm/generate.sh new file mode 100644 index 00000000..f42f840c --- /dev/null +++ b/fuzzers/031-mmcm/generate.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +set -ex +source ${XRAY_DIR}/utils/top_generate.sh + diff --git a/fuzzers/031-mmcm/generate.tcl b/fuzzers/031-mmcm/generate.tcl new file mode 100644 index 00000000..b3e18603 --- /dev/null +++ b/fuzzers/031-mmcm/generate.tcl @@ -0,0 +1,33 @@ +create_project -force -part $::env(XRAY_PART) design design +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] +# 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/031-mmcm/top.py b/fuzzers/031-mmcm/top.py new file mode 100644 index 00000000..db426ffc --- /dev/null +++ b/fuzzers/031-mmcm/top.py @@ -0,0 +1,114 @@ +import os +import random +random.seed(int(os.getenv("SEED"), 16)) +from prjxray import util +from prjxray import verilog +from prjxray.verilog import vrandbit, vrandbits +import sys +import json + + +def gen_sites(): + for _tile_name, site_name, _site_type in sorted(util.get_roi().gen_sites( + ["PLLE2_ADV"])): + yield site_name + + +sites = list(gen_sites()) +DUTN = len(sites) +DIN_N = DUTN * 8 +DOUT_N = DUTN * 8 + +verilog.top_harness(DIN_N, DOUT_N) + +f = open('params.jl', 'w') +f.write('module,loc,params\n') +print( + 'module roi(input clk, input [%d:0] din, output [%d:0] dout);' % + (DIN_N - 1, DOUT_N - 1)) + +for loci, site in enumerate(sites): + + ports = { + 'clk': 'clk', + 'din': 'din[ %d +: 8]' % (8 * loci, ), + 'dout': 'dout[ %d +: 8]' % (8 * loci, ), + } + + params = { + "CLKOUT1_DIVIDE": random.randint(1, 128), + } + + modname = "my_MMCME2_ADV" + verilog.instance(modname, "inst_%u" % loci, ports, params=params) + # LOC isn't support + params["LOC"] = verilog.quote(site) + + j = {'module': modname, 'i': loci, 'params': params} + f.write('%s\n' % (json.dumps(j))) + print('') + +f.close() +print( + '''endmodule + +// --------------------------------------------------------------------- + +''') + +print( + ''' +module my_MMCME2_ADV (input clk, input [7:0] din, output [7:0] dout); + parameter CLKOUT1_DIVIDE = 1; + parameter CLKOUT2_DIVIDE = 1; + parameter CLKOUT3_DIVIDE = 1; + parameter CLKOUT4_DIVIDE = 1; + parameter CLKOUT5_DIVIDE = 1; + parameter CLKOUT6_DIVIDE = 1; + parameter DIVCLK_DIVIDE = 1; + parameter CLKFBOUT_MULT = 5; + + (* KEEP, DONT_TOUCH *) + MMCME2_ADV #( + .CLKOUT1_DIVIDE(CLKOUT1_DIVIDE), + .CLKOUT2_DIVIDE(CLKOUT2_DIVIDE), + .CLKOUT3_DIVIDE(CLKOUT3_DIVIDE), + .CLKOUT4_DIVIDE(CLKOUT4_DIVIDE), + .CLKOUT5_DIVIDE(CLKOUT5_DIVIDE), + .CLKOUT6_DIVIDE(CLKOUT6_DIVIDE) + ) dut( + .CLKFBOUT(), + .CLKFBOUTB(), + .CLKFBSTOPPED(), + .CLKINSTOPPED(), + .CLKOUT0(dout[0]), + .CLKOUT0B(), + .CLKOUT1(), + .CLKOUT1B(), + .CLKOUT2(), + .CLKOUT2B(), + .CLKOUT3(), + .CLKOUT3B(), + .CLKOUT4(), + .CLKOUT5(), + .CLKOUT6(), + .DO(), + .DRDY(), + .LOCKED(), + .PSDONE(), + .CLKFBIN(clk), + .CLKIN1(clk), + .CLKIN2(clk), + .CLKINSEL(clk), + .DADDR(), + .DCLK(clk), + .DEN(), + .DI(), + .DWE(), + .PSCLK(clk), + .PSEN(), + .PSINCDEC(), + .PWRDWN(), + .RST(din[0])); +endmodule +''')