From ffd77f321d699c58505a0cfbac6f2d1981c64c90 Mon Sep 17 00:00:00 2001 From: John McMaster Date: Wed, 13 Dec 2017 16:42:49 -0800 Subject: [PATCH] clbram fuzzer WIP Signed-off-by: John McMaster Signed-off-by: Tim 'mithro' Ansell --- fuzzers/018-clbram/Makefile | 22 ++ fuzzers/018-clbram/README.txt | 0 fuzzers/018-clbram/generate.py | 33 +++ fuzzers/018-clbram/generate.sh | 18 ++ fuzzers/018-clbram/generate.tcl | 26 ++ fuzzers/018-clbram/top.py | 440 ++++++++++++++++++++++++++++++++ 6 files changed, 539 insertions(+) create mode 100644 fuzzers/018-clbram/Makefile create mode 100644 fuzzers/018-clbram/README.txt create mode 100644 fuzzers/018-clbram/generate.py create mode 100644 fuzzers/018-clbram/generate.sh create mode 100644 fuzzers/018-clbram/generate.tcl create mode 100644 fuzzers/018-clbram/top.py diff --git a/fuzzers/018-clbram/Makefile b/fuzzers/018-clbram/Makefile new file mode 100644 index 00000000..cdd3cf23 --- /dev/null +++ b/fuzzers/018-clbram/Makefile @@ -0,0 +1,22 @@ +N := 1 +SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N))) +SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) + +database: $(SPECIMENS_OK) + ${XRAY_SEGMATCH} -o seg_clblx.segbits $(addsuffix /segdata_clbl[lm]_[lr].txt,$(SPECIMENS)) + +pushdb: + ${XRAY_MERGEDB} clbll_l seg_clblx.segbits + ${XRAY_MERGEDB} clbll_r seg_clblx.segbits + ${XRAY_MERGEDB} clblm_l seg_clblx.segbits + ${XRAY_MERGEDB} clblm_r seg_clblx.segbits + +$(SPECIMENS_OK): + bash generate.sh $(subst /OK,,$@) + touch $@ + +clean: + rm -rf specimen_[0-9][0-9][0-9]/ seg_clblx.segbits vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit top.v + +.PHONY: database pushdb clean + diff --git a/fuzzers/018-clbram/README.txt b/fuzzers/018-clbram/README.txt new file mode 100644 index 00000000..e69de29b diff --git a/fuzzers/018-clbram/generate.py b/fuzzers/018-clbram/generate.py new file mode 100644 index 00000000..a07efb0c --- /dev/null +++ b/fuzzers/018-clbram/generate.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 + +import sys, re + +sys.path.append("../../../utils/") +from segmaker import segmaker + +segmk = segmaker("design.bits") + +print("Loading tags") +''' +module,loc,n,def_a +clb_N5FFMUX,SLICE_X12Y100,3,1 +clb_N5FFMUX,SLICE_X13Y100,0,1 +clb_N5FFMUX,SLICE_X14Y100,3,1 +''' +f = open('params.csv', 'r') +f.readline() +for l in f: + module,loc,n,def_a = l.split(',') + def_a = int(def_a) + n = int(n) + #which = chr(ord('A') + n) + + for i, which in enumerate('ABCD'): + # Theory: there is one bit for each mux positon + # In each config 3 muxes are in one position, other 3 are in another + inv = int(i == n) + segmk.addtag(loc, "%c5FF.MUX.A" % which, def_a ^ inv) + segmk.addtag(loc, "%c5FF.MUX.B" % which, 1 ^ def_a ^ inv) +segmk.compile() +segmk.write() + diff --git a/fuzzers/018-clbram/generate.sh b/fuzzers/018-clbram/generate.sh new file mode 100644 index 00000000..35c20d37 --- /dev/null +++ b/fuzzers/018-clbram/generate.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +set -ex + +. ../../utils/genheader.sh + +#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 + ../../../build/tools/bitread -F $XRAY_ROI_FRAMES -o ${x}s -z -y $x +done + +python3 ../generate.py + diff --git a/fuzzers/018-clbram/generate.tcl b/fuzzers/018-clbram/generate.tcl new file mode 100644 index 00000000..86162f92 --- /dev/null +++ b/fuzzers/018-clbram/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/018-clbram/top.py b/fuzzers/018-clbram/top.py new file mode 100644 index 00000000..8bb652ad --- /dev/null +++ b/fuzzers/018-clbram/top.py @@ -0,0 +1,440 @@ +import random +random.seed(0) +import os +import re + +def slice_xy(): + '''Return (X1, X2), (Y1, Y2) from XRAY_ROI, exclusive end (for xrange)''' + # 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)) + +CLBN = 4 +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 CLBs: %s' % str(CLBN)) + +# Rearranged to sweep Y so that carry logic is easy to allocate +# XXX: careful...if odd number of Y in ROI will break carry +def gen_slicems(): + ''' + SLICEM at the following: + SLICE_XxY* + Where Y any value + x + Always even (ie 100, 102, 104, etc) + In our ROI + x = 6, 8, 10, 12, 14 + ''' + # TODO: generate this from DB + assert((12, 28) == SLICEX) + for slicex in (12, 14): + for slicey in range(*SLICEY): + # caller may reject position if needs more room + #yield ("SLICE_X%dY%d" % (slicex, slicey), (slicex, slicey)) + yield "SLICE_X%dY%d" % (slicex, slicey) + + +DIN_N = CLBN * 8 +DOUT_N = CLBN * 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,n,def_a\n') +slices = gen_slicems() +print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1)) +for i in range(CLBN): + bel = '' + + # Can fit 4 per CLB + # BELable + multi_bels_by = [ + 'SRL16E', + 'SRLC32E', + ] + # Not BELable + multi_bels_bn = [ + 'RAM32X1S', + 'RAM64X1S', + ] + + # Those requiring special resources + # Just make one per module + greedy_modules = [ + 'my_RAM128X1D', + 'my_RAM128X1S', + 'my_RAM256X1S', + ] + + loc = next(slices) + + cparams = '' + # Multi module + if random.randint(0, 3) > 0: + params = '' + module = 'my_ram_N' + + # Pick one un-LOCable and then fill in with LOCable + unbel_beli = random.randint(0, 3) + bels = [] + for beli in range(4): + belc = chr(ord('A') + beli) + if beli == unbel_beli: + # Chose a BEL instance that will get implicitly placed + bel = random.choice(multi_bels_bn) + params += ', .N_%s(1)' % bel + else: + bel = random.choice(multi_bels_by) + params += ', .%c_%s(1)' % (belc, bel) + + bels.append(bel) + # Record the BELs we chose in the module (A, B, C, D) + cparams = ',' + (', '.join(bels)) + # Greedy module + # Don't place anything else in it + # For solving muxes vs previous results + else: + module = random.choice(greedy_modules) + params = '' + + print(' %s' % module) + print(' #(.LOC("%s")%s)' % (loc, params)) + print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i)) + + f.write('%s,%s%s\n' % (module, loc, cparams)) +f.close() +print('''endmodule + +// --------------------------------------------------------------------- + +''') + +print(''' + +//*************************************************************** +//Supermodule + +//BEL: yes +module my_ram_N (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter D_SRL16E=0; + parameter D_SRLC32E=0; + parameter C_SRL16E=0; + parameter C_SRLC32E=0; + parameter B_SRL16E=0; + parameter B_SRLC32E=0; + parameter A_SRL16E=0; + parameter A_SRLC32E=0; + + parameter N_RAM32X1S=0; + parameter N_RAM64X1S=0; + + generate + if (D_SRL16E) begin + (* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *) + SRL16E #( + ) lutd ( + .Q(dout[3]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .CE(din[4]), + .CLK(din[5]), + .D(din[6])); + end + if (D_SRLC32E) begin + (* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) lutd ( + .Q(dout[3]), + .Q31(), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(din[7])); + end + + if (C_SRL16E) begin + (* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *) + SRL16E #( + ) lutc ( + .Q(dout[2]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .CE(din[4]), + .CLK(din[5]), + .D(din[6])); + end + if (C_SRLC32E) begin + (* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) lutc ( + .Q(dout[2]), + .Q31(), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(din[7])); + end + + if (B_SRL16E) begin + (* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *) + SRL16E #( + ) lutb ( + .Q(dout[1]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .CE(din[4]), + .CLK(din[5]), + .D(din[6])); + end + if (B_SRLC32E) begin + (* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) lutb ( + .Q(dout[1]), + .Q31(), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(din[7])); + end + + if (A_SRL16E) begin + (* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *) + SRL16E #( + ) luta ( + .Q(dout[0]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .CE(din[4]), + .CLK(din[5]), + .D(din[6])); + end + if (A_SRLC32E) begin + (* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) luta ( + .Q(dout[0]), + .Q31(), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(din[7])); + end + + if (N_RAM32X1S) begin + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM32X1S #( + ) RAM32X1S ( + .O(dout[4]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .D(din[5]), + .WCLK(din[6]), + .WE(din[7])); + end + if (N_RAM64X1S) begin + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM64X1S #( + ) RAM64X1S ( + .O(dout[4]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .A5(din[5]), + .D(din[6]), + .WCLK(clk), + .WE(din[0])); + end + endgenerate +endmodule + + +//*************************************************************** +//Basic + +//BEL: yes +module my_SRL16E (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BEL="A6LUT"; + + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + SRL16E #( + ) SRL16E ( + .Q(dout[0]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .CE(din[4]), + .CLK(din[5]), + .D(din[6])); +endmodule + +//BEL: yes +module my_SRLC32E (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BEL="A6LUT"; + + wire mc31c; + + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + SRLC32E #( + .INIT(32'h00000000), + .IS_CLK_INVERTED(1'b0) + ) lut ( + .Q(dout[0]), + .Q31(mc31c), + .A(din[4:0]), + .CE(din[5]), + .CLK(din[6]), + .D(din[7])); +endmodule + +//BEL: can't +module my_RAM32X1S (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM32X1S #( + ) RAM32X1S ( + .O(dout[0]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .D(din[5]), + .WCLK(din[6]), + .WE(din[7])); +endmodule + +//BEL: can't +module my_RAM64X1S (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM64X1S #( + ) RAM64X1S ( + .O(dout[0]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .A5(din[5]), + .D(din[6]), + .WCLK(clk), + .WE(din[0])); +endmodule + +//*************************************************************** +//WA*USED + +//Dedicated LOC +module my_RAM128X1D (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM128X1D #( + .INIT(128'h0), + .IS_WCLK_INVERTED(1'b0) + ) RAM128X1D ( + .DPO(dout[0]), + .SPO(dout[1]), + .D(din[0]), + .WCLK(clk), + .WE(din[2])); +endmodule + +//Dedicated LOC +module my_RAM128X1S (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM128X1S #( + ) RAM128X1S ( + .O(dout[0]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .A5(din[5]), + .A6(din[6]), + .D(din[7]), + .WCLK(din[0]), + .WE(din[1])); +endmodule + +//Dedicated LOC +module my_RAM256X1S (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM256X1S #( + ) RAM256X1S ( + .O(dout[0]), + .A({din[0], din[7:0]}), + .D(din[0]), + .WCLK(din[1]), + .WE(din[2])); +endmodule +''') +