From 7c2500eee7de4af1a59771fd540efbcb4e0b0407 Mon Sep 17 00:00:00 2001 From: John McMaster Date: Fri, 1 Dec 2017 16:20:13 -0800 Subject: [PATCH] clbn5ffmux fuzzer Signed-off-by: John McMaster Signed-off-by: Tim 'mithro' Ansell --- fuzzers/012-clbn5ffmux/Makefile | 22 +++ fuzzers/012-clbn5ffmux/README.txt | 16 +++ fuzzers/012-clbn5ffmux/generate.py | 33 +++++ fuzzers/012-clbn5ffmux/generate.sh | 17 +++ fuzzers/012-clbn5ffmux/generate.tcl | 26 ++++ fuzzers/012-clbn5ffmux/top.py | 200 ++++++++++++++++++++++++++++ 6 files changed, 314 insertions(+) create mode 100644 fuzzers/012-clbn5ffmux/Makefile create mode 100644 fuzzers/012-clbn5ffmux/README.txt create mode 100644 fuzzers/012-clbn5ffmux/generate.py create mode 100644 fuzzers/012-clbn5ffmux/generate.sh create mode 100644 fuzzers/012-clbn5ffmux/generate.tcl create mode 100644 fuzzers/012-clbn5ffmux/top.py diff --git a/fuzzers/012-clbn5ffmux/Makefile b/fuzzers/012-clbn5ffmux/Makefile new file mode 100644 index 00000000..cdd3cf23 --- /dev/null +++ b/fuzzers/012-clbn5ffmux/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/012-clbn5ffmux/README.txt b/fuzzers/012-clbn5ffmux/README.txt new file mode 100644 index 00000000..91d422a4 --- /dev/null +++ b/fuzzers/012-clbn5ffmux/README.txt @@ -0,0 +1,16 @@ +Purpose: +Document A5FFMUX family of CLB muxes + +Algorithm: +*5FFMUX +Inputs can come from either the LUT6_2 NO5 output or the CLB NX input +To perturb the CLB the smallest, want LUT6 always instantiated +However, some routing congestion that would require putting FFs in bypass +(which turns out is actually okay, but didn't realize that at the time) +Decided instead ot instantiate LUT8, but not use the output +Turns out this is okay and won't optimize things away +So then, the 5FF D input is switched between the O5 output and an external CLB input + +Outcome: +Bits are one hot encoded per mux position + diff --git a/fuzzers/012-clbn5ffmux/generate.py b/fuzzers/012-clbn5ffmux/generate.py new file mode 100644 index 00000000..a07efb0c --- /dev/null +++ b/fuzzers/012-clbn5ffmux/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/012-clbn5ffmux/generate.sh b/fuzzers/012-clbn5ffmux/generate.sh new file mode 100644 index 00000000..d272452b --- /dev/null +++ b/fuzzers/012-clbn5ffmux/generate.sh @@ -0,0 +1,17 @@ +#!/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 + +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/012-clbn5ffmux/generate.tcl b/fuzzers/012-clbn5ffmux/generate.tcl new file mode 100644 index 00000000..86162f92 --- /dev/null +++ b/fuzzers/012-clbn5ffmux/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/012-clbn5ffmux/top.py b/fuzzers/012-clbn5ffmux/top.py new file mode 100644 index 00000000..62ea8fb8 --- /dev/null +++ b/fuzzers/012-clbn5ffmux/top.py @@ -0,0 +1,200 @@ +import random + +random.seed(0) + +CLBN = 40 +# SLICE_X12Y100 +# SLICE_X27Y149 +SLICEX = (12, 28) +SLICEY = (100, 150) +# 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)) + +def gen_slices(): + for slicey in range(*SLICEY): + for slicex in range(*SLICEX): + 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_slices() +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 = '' + + module = 'clb_N5FFMUX' + n = random.randint(0, 3) + def_a = random.randint(0, 1) + loc = next(slices) + + print(' %s' % module) + print(' #(.LOC("%s"), .N(%d), .DEF_A(%d))' % (loc, n, def_a)) + print(' clb_%d (.clk(clk), .din(din[ %d +: 8]), .dout(dout[ %d +: 8]));' % (i, 8 * i, 8 * i)) + + f.write('%s,%s,%s,%s\n' % (module, loc, n, def_a)) +f.close() +print('''endmodule + +// --------------------------------------------------------------------- + +''') + +print(''' +module clb_N5FFMUX (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_X22Y100"; + parameter N=-1; + parameter DEF_A=1; + wire lutdo, lutco, lutbo, lutao; + wire lut7bo, lut7ao; + wire lut8o; + + reg [3:0] ffds; + wire lutdo5, lutco5, lutbo5, lutao5; + //wire lutno5 [3:0] = {lutao5, lutbo5, lutco5, lutdo5}; + wire lutno5 [3:0] = {lutdo5, lutco5, lutbo5, lutao5}; + always @(*) begin + if (DEF_A) begin + //Default poliarty A + ffds[3] = lutdo5; + ffds[2] = lutco5; + ffds[1] = lutbo5; + ffds[0] = lutao5; + ffds[N] = din[6]; + end else begin + //Default polarity B + ffds[3] = din[6]; + ffds[2] = din[6]; + ffds[1] = din[6]; + ffds[0] = din[6]; + ffds[N] = lutno5[N]; + end + end + + (* LOC=LOC, BEL="F8MUX", KEEP, DONT_TOUCH *) + MUXF8 mux8 (.O(), .I0(lut7bo), .I1(lut7ao), .S(din[6])); + (* LOC=LOC, BEL="F7BMUX", KEEP, DONT_TOUCH *) + MUXF7 mux7b (.O(lut7bo), .I0(lutdo), .I1(lutco), .S(din[6])); + (* LOC=LOC, BEL="F7AMUX", KEEP, DONT_TOUCH *) + MUXF7 mux7a (.O(lut7ao), .I0(lutbo), .I1(lutao), .S(din[6])); + + (* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *) + LUT6_2 #( + .INIT(64'h8000_DEAD_0000_0001) + ) lutd ( + .I0(din[0]), + .I1(din[1]), + .I2(din[2]), + .I3(din[3]), + .I4(din[4]), + .I5(din[5]), + .O5(lutdo5), + .O6(lutdo)); + (* LOC=LOC, BEL="D5FF" *) + FDPE ffd ( + .C(clk), + .Q(dout[1]), + .CE(din[0]), + .PRE(din[1]), + .D(ffds[3])); + + (* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *) + LUT6_2 #( + .INIT(64'h8000_BEEF_0000_0001) + ) lutc ( + .I0(din[0]), + .I1(din[1]), + .I2(din[2]), + .I3(din[3]), + .I4(din[4]), + .I5(din[5]), + .O5(lutco5), + .O6(lutco)); + (* LOC=LOC, BEL="C5FF" *) + FDPE ffc ( + .C(clk), + .Q(dout[2]), + .CE(din[0]), + .PRE(din[1]), + .D(ffds[2])); + + (* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *) + LUT6_2 #( + .INIT(64'h8000_CAFE_0000_0001) + ) lutb ( + .I0(din[0]), + .I1(din[1]), + .I2(din[2]), + .I3(din[3]), + .I4(din[4]), + .I5(din[5]), + .O5(lutbo5), + .O6(lutbo)); + (* LOC=LOC, BEL="B5FF" *) + FDPE ffb ( + .C(clk), + .Q(dout[3]), + .CE(din[0]), + .PRE(din[1]), + .D(ffds[1])); + + (* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *) + LUT6_2 #( + .INIT(64'h8000_1CE0_0000_0001) + ) luta ( + .I0(din[0]), + .I1(din[1]), + .I2(din[2]), + .I3(din[3]), + .I4(din[4]), + .I5(din[5]), + .O5(lutao5), + .O6(lutao)); + (* LOC=LOC, BEL="A5FF" *) + FDPE ffa ( + .C(clk), + .Q(dout[4]), + .CE(din[0]), + .PRE(din[1]), + //D can only come from O5 or AX + //AX is used by MUXF7:S + .D(ffds[0])); +endmodule +''') +