diff --git a/fuzzers/101-braminit/.gitignore b/fuzzers/101-braminit/.gitignore new file mode 100644 index 00000000..932efba0 --- /dev/null +++ b/fuzzers/101-braminit/.gitignore @@ -0,0 +1,2 @@ +/specimen_[0-9][0-9][0-9]/ +/seg_clbl[lm].segbits diff --git a/fuzzers/101-braminit/Makefile b/fuzzers/101-braminit/Makefile new file mode 100644 index 00000000..94f8596a --- /dev/null +++ b/fuzzers/101-braminit/Makefile @@ -0,0 +1,20 @@ +N := 1 +SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N))) +SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) + +database: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -o seg_bramx.segbits $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS)) + +pushdb: + ${XRAY_MERGEDB} bram_l seg_bramx.segbits + ${XRAY_MERGEDB} bram_r seg_bramx.segbits + +$(SPECIMENS_OK): + bash generate.sh $(subst /OK,,$@) + touch $@ + +clean: + rm -rf specimen_[0-9][0-9][0-9]/ seg_*.segbits vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit top.v + +.PHONY: database pushdb clean + diff --git a/fuzzers/101-braminit/README.md b/fuzzers/101-braminit/README.md new file mode 100644 index 00000000..58d2dfe6 --- /dev/null +++ b/fuzzers/101-braminit/README.md @@ -0,0 +1,15 @@ +FIXME: ROI is SLICE_X12Y100:SLICE_X27Y149 +But we need something with BRAM + +export XRAY_ROI=SLICE_X6Y100:SLICE_X27Y149 +# Needed? +# export XRAY_ROI_FRAMES="0x00020500:0x000208ff" +source $XRAY_DIR/utils/environment.sh + + +Solves SLICEM specific bits: +-Shift register LUT (SRL) +-Memory size +-RAM vs LUT +-Related muxes + diff --git a/fuzzers/101-braminit/env.sh b/fuzzers/101-braminit/env.sh new file mode 100644 index 00000000..47adfb4a --- /dev/null +++ b/fuzzers/101-braminit/env.sh @@ -0,0 +1,4 @@ +#!/bin/bash +export XRAY_ROI=SLICE_X6Y100:SLICE_X27Y149 +export XRAY_ROI_FRAMES=0x00820000:0x00820080 + diff --git a/fuzzers/101-braminit/generate.py b/fuzzers/101-braminit/generate.py new file mode 100644 index 00000000..219d47f3 --- /dev/null +++ b/fuzzers/101-braminit/generate.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +import sys, re, os + +sys.path.append("../../../utils/") +from segmaker import segmaker + +c2i = {'0': 0, '1': 1} + +segmk = segmaker("design.bits") + +print("Loading tags") +''' +''' +f = open('params.csv', 'r') +f.readline() +for l in f: + l = l.strip() + module, loc, pdata, data = l.split(',') + print(loc) + + segmk.addtag(loc, "STUFF", 1) + + for i, d in enumerate(pdata): + # Keep dec convention used on LUT? + segmk.addtag(loc, "BRAM.INITP[%04d]" % i, c2i[d]) + for i, d in enumerate(data): + # Keep dec convention used on LUT? + segmk.addtag(loc, "BRAM.INIT[%04d]" % i, c2i[d]) + +segmk.compile() +segmk.write() diff --git a/fuzzers/101-braminit/generate.sh b/fuzzers/101-braminit/generate.sh new file mode 100644 index 00000000..54774bf8 --- /dev/null +++ b/fuzzers/101-braminit/generate.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -ex + +source ${XRAY_GENHEADER} + +#echo '`define SEED 32'"'h$(echo $1 | md5sum | cut -c1-8)" > setseed.vh + +python3 ../top.py >top.v +vivado -mode batch -source ../generate.tcl +test -z "$(fgrep CRITICAL vivado.log)" + +for x in design*.bit; do + ${XRAY_BITREAD} -F $XRAY_ROI_FRAMES -o ${x}s -z -y $x +done + +python3 ../generate.py + diff --git a/fuzzers/101-braminit/generate.tcl b/fuzzers/101-braminit/generate.tcl new file mode 100644 index 00000000..86162f92 --- /dev/null +++ b/fuzzers/101-braminit/generate.tcl @@ -0,0 +1,26 @@ +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 +set_property EXCLUDE_PLACEMENT 1 [get_pblocks 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] + +place_design +route_design + +write_checkpoint -force design.dcp +write_bitstream -force design.bit + diff --git a/fuzzers/101-braminit/top.py b/fuzzers/101-braminit/top.py new file mode 100644 index 00000000..981b8d92 --- /dev/null +++ b/fuzzers/101-braminit/top.py @@ -0,0 +1,273 @@ +''' +Need coverage for the following: +RAM32X1S_N +RAM32X1D +RAM32M +RAM64X1S_N +RAM64X1D_N +RAM64M +RAM128X1S_N +RAM128X1D +RAM256X1S +SRL16E_N +SRLC32E_N + +Note: LUT6 was added to try to simplify reduction, although it might not be needed +''' + +import random +random.seed(0) +import os +import re + + +def slice_xy(): + '''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for range)''' + # SLICE_X12Y100:SLICE_X27Y149 + # Note XRAY_ROI_GRID_* is something else + m = re.match(r'SLICE_X(.*)Y(.*):SLICE_X(.*)Y(.*)', os.getenv('XRAY_ROI')) + ms = [int(m.group(i + 1)) for i in range(4)] + return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1)) + + +# 18 + 36 count in ROI +DUTN = 10 +SLICEX, SLICEY = slice_xy() +# 800 +SLICEN = (SLICEY[1] - SLICEY[0]) * (SLICEX[1] - SLICEX[0]) +print('//SLICEX: %s' % str(SLICEX)) +print('//SLICEY: %s' % str(SLICEY)) +print('//SLICEN: %s' % str(SLICEN)) +print('//Requested DUTs: %s' % str(DUTN)) + + +def gen_bram18(): + # TODO: generate this from DB + assert ((6, 28) == SLICEX) + x = 0 + for y in range(40, 60): + # caller may reject position if needs more room + yield "RAMB18_X%dY%d" % (x, y) + + +def gen_bram36(): + # TODO: generate this from DB + assert ((6, 28) == SLICEX) + x = 0 + for y in range(20, 29): + # caller may reject position if needs more room + yield "RAMB36_X%dY%d" % (x, y) + + +DIN_N = DUTN * 8 +DOUT_N = DUTN * 8 + +print( + ''' +module top(input clk, stb, di, output do); + localparam integer DIN_N = %d; + localparam integer DOUT_N = %d; + + 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]; + + roi roi ( + .clk(clk), + .din(din), + .dout(dout) + ); +endmodule +''' % (DIN_N, DOUT_N)) + +f = open('params.csv', 'w') +f.write('module,loc,pdata,data\n') +print( + 'module roi(input clk, input [%d:0] din, output [%d:0] dout);' % + (DIN_N - 1, DOUT_N - 1)) + + +def randbits(n): + return ''.join([random.choice(('0', '1')) for _x in range(n)]) + + +loci = 0 + + +def make(module, gen_locs, pdatan, datan): + global loci + + for loc in gen_locs(): + pdata = randbits(pdatan * 0x100) + data = randbits(datan * 0x100) + + print(' %s #(' % module) + for i in range(pdatan): + print( + " .INITP_%02X(256'b%s)," % + (i, pdata[i * 256:(i + 1) * 256])) + for i in range(datan): + print( + " .INIT_%02X(256'b%s)," % (i, data[i * 256:(i + 1) * 256])) + print('.LOC("%s"))' % (loc, )) + print( + ' inst_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' + % (loci, 8 * loci, 8 * loci)) + + f.write('%s,%s,%s,%s\n' % (module, loc, pdata, data)) + loci += 1 + + +#make('my_RAMB18E1', gen_bram18, 0x08, 0x40) +make('my_RAMB36E1', gen_bram36, 0x10, 0x80) + +f.close() +print( + '''endmodule + +// --------------------------------------------------------------------- + +''') + +# RAMB18E1 +print( + ''' +module my_RAMB18E1 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + ''') +for i in range(8): + print( + " parameter INITP_%02X = 256'h0000000000000000000000000000000000000000000000000000000000000000;" + % i) +print() +for i in range(0x40): + print( + " parameter INIT_%02X = 256'h0000000000000000000000000000000000000000000000000000000000000000;" + % i) +print() +print('''\ + (* LOC=LOC *) + RAMB18E1 #(''') +for i in range(8): + print(' .INITP_%02X(INITP_%02X),' % (i, i)) +print() +for i in range(0x40): + print(' .INIT_%02X(INIT_%02X),' % (i, i)) +print() +print( + ''' + .IS_CLKARDCLK_INVERTED(1'b0), + .IS_CLKBWRCLK_INVERTED(1'b0), + .IS_ENARDEN_INVERTED(1'b0), + .IS_ENBWREN_INVERTED(1'b0), + .IS_RSTRAMARSTRAM_INVERTED(1'b0), + .IS_RSTRAMB_INVERTED(1'b0), + .IS_RSTREGARSTREG_INVERTED(1'b0), + .IS_RSTREGB_INVERTED(1'b0), + .RAM_MODE("TDP"), + .WRITE_MODE_A("WRITE_FIRST"), + .WRITE_MODE_B("WRITE_FIRST"), + .SIM_DEVICE("VIRTEX6") + ) ram ( + .CLKARDCLK(din[0]), + .CLKBWRCLK(din[1]), + .ENARDEN(din[2]), + .ENBWREN(din[3]), + .REGCEAREGCE(din[4]), + .REGCEB(din[5]), + .RSTRAMARSTRAM(din[6]), + .RSTRAMB(din[7]), + .RSTREGARSTREG(din[0]), + .RSTREGB(din[1]), + .ADDRARDADDR(din[2]), + .ADDRBWRADDR(din[3]), + .DIADI(din[4]), + .DIBDI(din[5]), + .DIPADIP(din[6]), + .DIPBDIP(din[7]), + .WEA(din[0]), + .WEBWE(din[1]), + .DOADO(dout[0]), + .DOBDO(dout[1]), + .DOPADOP(dout[2]), + .DOPBDOP(dout[3])); +endmodule +''') + +print( + ''' + +module my_RAMB36E1 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + ''') +for i in range(16): + print( + " parameter INITP_%02X = 256'h0000000000000000000000000000000000000000000000000000000000000000;" + % i) +print() +for i in range(0x80): + print( + " parameter INIT_%02X = 256'h0000000000000000000000000000000000000000000000000000000000000000;" + % i) +print() +print('''\ + (* LOC=LOC *) + RAMB36E1 #(''') +for i in range(16): + print(' .INITP_%02X(INITP_%02X),' % (i, i)) +print() +for i in range(0x80): + print(' .INIT_%02X(INIT_%02X),' % (i, i)) +print() +print( + ''' + .IS_CLKARDCLK_INVERTED(1'b0), + .IS_CLKBWRCLK_INVERTED(1'b0), + .IS_ENARDEN_INVERTED(1'b0), + .IS_ENBWREN_INVERTED(1'b0), + .IS_RSTRAMARSTRAM_INVERTED(1'b0), + .IS_RSTRAMB_INVERTED(1'b0), + .IS_RSTREGARSTREG_INVERTED(1'b0), + .IS_RSTREGB_INVERTED(1'b0), + .RAM_MODE("TDP"), + .WRITE_MODE_A("WRITE_FIRST"), + .WRITE_MODE_B("WRITE_FIRST"), + .SIM_DEVICE("VIRTEX6") + ) ram ( + .CLKARDCLK(din[0]), + .CLKBWRCLK(din[1]), + .ENARDEN(din[2]), + .ENBWREN(din[3]), + .REGCEAREGCE(din[4]), + .REGCEB(din[5]), + .RSTRAMARSTRAM(din[6]), + .RSTRAMB(din[7]), + .RSTREGARSTREG(din[0]), + .RSTREGB(din[1]), + .ADDRARDADDR(din[2]), + .ADDRBWRADDR(din[3]), + .DIADI(din[4]), + .DIBDI(din[5]), + .DIPADIP(din[6]), + .DIPBDIP(din[7]), + .WEA(din[0]), + .WEBWE(din[1]), + .DOADO(dout[0]), + .DOBDO(dout[1]), + .DOPADOP(dout[2]), + .DOPBDOP(dout[3])); +endmodule +''')