diff --git a/fuzzers/015-clbnffmux/.gitignore b/fuzzers/015-clbnffmux/.gitignore new file mode 100644 index 00000000..93b5bef8 --- /dev/null +++ b/fuzzers/015-clbnffmux/.gitignore @@ -0,0 +1,4 @@ +/specimen_*/ +/*.segbits +/vivado.log +/vivado.jou diff --git a/fuzzers/015-clbnffmux/Makefile b/fuzzers/015-clbnffmux/Makefile new file mode 100644 index 00000000..cdd3cf23 --- /dev/null +++ b/fuzzers/015-clbnffmux/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/015-clbnffmux/README.txt b/fuzzers/015-clbnffmux/README.txt new file mode 100644 index 00000000..820fcf39 --- /dev/null +++ b/fuzzers/015-clbnffmux/README.txt @@ -0,0 +1,42 @@ +Purpose: +Document AFFMUX family of CLB muxes + +Algorithm: + +Outcome: + + +CLB.SLICE_X0.AFF.DMUX.B0 30_00 +CLB.SLICE_X0.AFF.DMUX.B1 30_01 +CLB.SLICE_X0.AFF.DMUX.B2 30_02 +CLB.SLICE_X0.AFF.DMUX.B3 30_03 +CLB.SLICE_X0.BFF.DMUX.B0 30_27 +CLB.SLICE_X0.BFF.DMUX.B1 30_26 +CLB.SLICE_X0.BFF.DMUX.B2 30_25 +CLB.SLICE_X0.BFF.DMUX.B3 30_24 +CLB.SLICE_X0.CFF.DMUX.B0 30_35 +CLB.SLICE_X0.CFF.DMUX.B1 30_36 +CLB.SLICE_X0.CFF.DMUX.B2 30_37 +CLB.SLICE_X0.CFF.DMUX.B3 30_38 +CLB.SLICE_X0.DFF.DMUX.B0 30_62 +CLB.SLICE_X0.DFF.DMUX.B1 30_61 +CLB.SLICE_X0.DFF.DMUX.B2 30_60 +CLB.SLICE_X0.DFF.DMUX.B3 30_59 +CLB.SLICE_X1.AFF.DMUX.B0 31_00 +CLB.SLICE_X1.AFF.DMUX.B1 31_01 +CLB.SLICE_X1.AFF.DMUX.B2 31_02 +CLB.SLICE_X1.AFF.DMUX.B3 30_04 +CLB.SLICE_X1.BFF.DMUX.B0 31_25 +CLB.SLICE_X1.BFF.DMUX.B1 31_27 +CLB.SLICE_X1.BFF.DMUX.B2 31_26 +CLB.SLICE_X1.BFF.DMUX.B3 31_24 +CLB.SLICE_X1.CFF.DMUX.B0 31_35 +CLB.SLICE_X1.CFF.DMUX.B1 31_38 +CLB.SLICE_X1.CFF.DMUX.B2 31_37 +CLB.SLICE_X1.CFF.DMUX.B3 31_36 +CLB.SLICE_X1.DFF.DMUX.B0 30_58 +CLB.SLICE_X1.DFF.DMUX.B1 31_61 +CLB.SLICE_X1.DFF.DMUX.B2 31_62 +CLB.SLICE_X1.DFF.DMUX.B3 31_60 + + diff --git a/fuzzers/015-clbnffmux/generate.py b/fuzzers/015-clbnffmux/generate.py new file mode 100644 index 00000000..5b6e22ba --- /dev/null +++ b/fuzzers/015-clbnffmux/generate.py @@ -0,0 +1,46 @@ +#!/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 +clb_NFFMUX_O5,SLICE_X12Y100,3 +clb_NFFMUX_AX,SLICE_X13Y100,2 +clb_NFFMUX_O6,SLICE_X14Y100,3 +''' +f = open('params.csv', 'r') +f.readline() +for l in f: + module,loc,n = l.split(',') + n = int(n) + which = chr(ord('A') + n) + # clb_NFFMUX_AX => AX + module = module.replace('clb_NFFMUX_', '') + + ''' + AFFMUX + 30_00 30_01 30_02 30_03 + F78 1 1 + CY 1 1 + O5 1 1 + AX 1 + XOR 1 + O6 1 + ''' + # TODO: this needs to be converted to PIP type format + if 0: + # Although F78 is special, if it doesn't show up, we don't care + segmk.addtag(loc, "%cFF.DMUX.B0" % which, module in ('F78', 'CY', 'O5')) + segmk.addtag(loc, "%cFF.DMUX.B1" % which, module in ('F78', 'AX')) + segmk.addtag(loc, "%cFF.DMUX.B2" % which, module in ('CY', 'XOR')) + segmk.addtag(loc, "%cFF.DMUX.B3" % which, module in ('O5', 'O6')) + +segmk.compile() +segmk.write() + diff --git a/fuzzers/015-clbnffmux/generate.sh b/fuzzers/015-clbnffmux/generate.sh new file mode 100644 index 00000000..93c44166 --- /dev/null +++ b/fuzzers/015-clbnffmux/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/015-clbnffmux/generate.tcl b/fuzzers/015-clbnffmux/generate.tcl new file mode 100644 index 00000000..86162f92 --- /dev/null +++ b/fuzzers/015-clbnffmux/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/015-clbnffmux/top.py b/fuzzers/015-clbnffmux/top.py new file mode 100644 index 00000000..0ca2029e --- /dev/null +++ b/fuzzers/015-clbnffmux/top.py @@ -0,0 +1,327 @@ +import random + +random.seed(0) + +CLBN = 400 +# 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\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): + modules = ['clb_NFFMUX_' + x for x in ['AX', 'CY', 'F78', 'O5', 'O6', 'XOR']] + module = random.choice(modules) + + if module == 'clb_NFFMUX_F78': + n = random.randint(0, 2) + else: + n = random.randint(0, 3) + #n = 0 + loc = next(slices) + + print(' %s' % module) + print(' #(.LOC("%s"), .N(%d))' % (loc, n)) + 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, n)) +f.close() +print('''endmodule + +// --------------------------------------------------------------------- + +''') + +print(''' +module myLUT8 (input clk, input [7:0] din, + output lut8o, output lut7bo, output lut7ao, + //caro: XOR additional result (main output) + //carco: CLA result (carry module additional output) + output caro, output carco, + output bo5, output bo6, + output wire ff_q, //always connect to output + input wire ff_d); //mux output net + parameter LOC="SLICE_FIXME"; + parameter N=-1; + + wire [3:0] caro_all; + assign caro = caro_all[N]; + wire [3:0] carco_all; + assign carco = carco_all[N]; + + wire [3:0] lutno6; + wire [3:0] lutno5; + assign bo5 = lutno5[N]; + assign bo6 = lutno6[N]; + + //Outputs does not have to be used, will stay without it + (* LOC=LOC, BEL="F8MUX", KEEP, DONT_TOUCH *) + MUXF8 mux8 (.O(lut8o), .I0(lut7bo), .I1(lut7ao), .S(din[6])); + (* LOC=LOC, BEL="F7BMUX", KEEP, DONT_TOUCH *) + MUXF7 mux7b (.O(lut7bo), .I0(lutno6[3]), .I1(lutno6[2]), .S(din[6])); + (* LOC=LOC, BEL="F7AMUX", KEEP, DONT_TOUCH *) + MUXF7 mux7a (.O(lut7ao), .I0(lutno6[1]), .I1(lutno6[0]), .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(lutno5[3]), + .O6(lutno6[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(lutno5[2]), + .O6(lutno6[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(lutno5[1]), + .O6(lutno6[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(lutno5[0]), + .O6(lutno6[0])); + + //Outputs do not have to be used, will stay without them + (* LOC=LOC, KEEP, DONT_TOUCH *) + CARRY4 carry4(.O(caro_all), .CO(carco_all), .DI(lutno5), .S(lutno6), .CYINIT(1'b0), .CI()); + + generate + if (N == 3) begin + (* LOC=LOC, BEL="DFF", KEEP, DONT_TOUCH *) + FDPE bff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(ff_d)); + end + if (N == 2) begin + (* LOC=LOC, BEL="CFF", KEEP, DONT_TOUCH *) + FDPE bff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(ff_d)); + end + if (N == 1) begin + (* LOC=LOC, BEL="BFF", KEEP, DONT_TOUCH *) + FDPE bff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(ff_d)); + end + if (N == 0) begin + (* LOC=LOC, BEL="AFF", KEEP, DONT_TOUCH *) + FDPE bff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(ff_d)); + end + endgenerate +endmodule + +//****************************************************************************** +//BFFMUX tests + +module clb_NFFMUX_AX (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=-1; + + /* + D: DX + drawn a little differently + not a mux control + becomes a dedicated external signal + C: CX + B: BX + A: AX + */ + wire ax = din[6]; //used on MUX8:S, MUX7A:S, and MUX7B:S + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), + .lut8o(), + .caro(), .carco(), + .bo5(), .bo6(), + .ff_q(dout[0]), + .ff_d(ax)); + +endmodule + +module clb_NFFMUX_CY (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=-1; + wire carco; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), + .lut8o(), + .caro(), .carco(carco), + .bo5(), .bo6(), + .ff_q(dout[0]), + .ff_d(carco)); +endmodule + +module clb_NFFMUX_F78 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=-1; + wire lut8o, lut7bo, lut7ao; + + /* + D: N/A (no such mux position) + C: F7B:O + B: F8:O + A: F7A:O + */ + wire ff_d; + + generate + if (N == 3) begin + //No muxes, so this is undefined + invalid_configuration invalid_configuration3(); + end else if (N == 2) begin + assign ff_d = lut7bo; + end else if (N == 1) begin + assign ff_d = lut8o; + end else if (N == 0) begin + assign ff_d = lut7ao; + end + endgenerate + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), + .lut8o(lut8o), .lut7bo(lut7bo), .lut7ao(lut7ao), + .caro(), .carco(), + .bo5(), .bo6(), + .ff_q(dout[0]), + .ff_d(ff_d)); +endmodule + +module clb_NFFMUX_O5 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=-1; + wire bo5; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), + .lut8o(), + .caro(), .carco(), + .bo5(bo5), .bo6(), + .ff_q(dout[0]), + .ff_d(bo5)); +endmodule + +module clb_NFFMUX_O6 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=-1; + wire bo6; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), + .lut8o(), + .caro(), .carco(), + .bo5(), .bo6(bo6), + .ff_q(dout[0]), + .ff_d(bo6)); +endmodule + +module clb_NFFMUX_XOR (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=-1; + wire caro; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), + .lut8o(), + .caro(caro), .carco(), + .bo5(), .bo6(bo6), + .ff_q(dout[0]), + .ff_d(caro)); +endmodule +''') + diff --git a/minitests/clb_nffmux/README.txt b/minitests/clb_nffmux/README.txt index e69de29b..f58707de 100644 --- a/minitests/clb_nffmux/README.txt +++ b/minitests/clb_nffmux/README.txt @@ -0,0 +1,9 @@ +AFFMUX + 30_00 30_01 30_02 30_03 +F78 1 1 +CY 1 1 +O5 1 1 +AX 1 +XOR 1 +O6 1 + diff --git a/minitests/clb_nffmux/top.v b/minitests/clb_nffmux/top.v index 5601b487..259f7f1f 100644 --- a/minitests/clb_nffmux/top.v +++ b/minitests/clb_nffmux/top.v @@ -27,24 +27,24 @@ module top(input clk, stb, di, output do); endmodule module roi(input clk, input [255:0] din, output [255:0] dout); - parameter N=3; + parameter N=0; - clb_BFFMUX_AX #(.LOC("SLICE_X18Y100"), .N(N)) - clb_BFFMUX_AX (.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); - clb_BFFMUX_CY #(.LOC("SLICE_X18Y101"), .N(N)) - clb_BFFMUX_CY (.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); + clb_NFFMUX_AX #(.LOC("SLICE_X18Y100"), .N(N)) + clb_NFFMUX_AX (.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); + clb_NFFMUX_CY #(.LOC("SLICE_X18Y101"), .N(N)) + clb_NFFMUX_CY (.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); generate if (N != 3) begin - clb_BFFMUX_F78 #(.LOC("SLICE_X18Y102"), .N(N)) - clb_BFFMUX_F78 (.clk(clk), .din(din[ 24 +: 8]), .dout(dout[ 24 +: 8])); + clb_NFFMUX_F78 #(.LOC("SLICE_X18Y102"), .N(N)) + clb_NFFMUX_F78 (.clk(clk), .din(din[ 24 +: 8]), .dout(dout[ 24 +: 8])); end endgenerate - clb_BFFMUX_O5 #(.LOC("SLICE_X18Y103"), .N(N)) - clb_BFFMUX_O5 (.clk(clk), .din(din[ 32 +: 8]), .dout(dout[ 32 +: 8])); - clb_BFFMUX_O6 #(.LOC("SLICE_X18Y104"), .N(N)) - clb_BFFMUX_O6 (.clk(clk), .din(din[ 40 +: 8]), .dout(dout[ 40 +: 8])); - clb_BFFMUX_XOR #(.LOC("SLICE_X18Y105"), .N(N)) - clb_BFFMUX_XOR (.clk(clk), .din(din[ 48 +: 8]), .dout(dout[ 48 +: 8 ])); + clb_NFFMUX_O5 #(.LOC("SLICE_X18Y103"), .N(N)) + clb_NFFMUX_O5 (.clk(clk), .din(din[ 32 +: 8]), .dout(dout[ 32 +: 8])); + clb_NFFMUX_O6 #(.LOC("SLICE_X18Y104"), .N(N)) + clb_NFFMUX_O6 (.clk(clk), .din(din[ 40 +: 8]), .dout(dout[ 40 +: 8])); + clb_NFFMUX_XOR #(.LOC("SLICE_X18Y105"), .N(N)) + clb_NFFMUX_XOR (.clk(clk), .din(din[ 48 +: 8]), .dout(dout[ 48 +: 8 ])); endmodule module myLUT8 (input clk, input [7:0] din, @@ -175,7 +175,7 @@ endmodule //****************************************************************************** //BFFMUX tests -module clb_BFFMUX_AX (input clk, input [7:0] din, output [7:0] dout); +module clb_NFFMUX_AX (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=-1; @@ -200,7 +200,7 @@ module clb_BFFMUX_AX (input clk, input [7:0] din, output [7:0] dout); endmodule -module clb_BFFMUX_CY (input clk, input [7:0] din, output [7:0] dout); +module clb_NFFMUX_CY (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=-1; wire carco; @@ -214,7 +214,7 @@ module clb_BFFMUX_CY (input clk, input [7:0] din, output [7:0] dout); .ff_d(carco)); endmodule -module clb_BFFMUX_F78 (input clk, input [7:0] din, output [7:0] dout); +module clb_NFFMUX_F78 (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=-1; wire lut8o, lut7bo, lut7ao; @@ -249,7 +249,7 @@ module clb_BFFMUX_F78 (input clk, input [7:0] din, output [7:0] dout); .ff_d(ff_d)); endmodule -module clb_BFFMUX_O5 (input clk, input [7:0] din, output [7:0] dout); +module clb_NFFMUX_O5 (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=-1; wire bo5; @@ -263,7 +263,7 @@ module clb_BFFMUX_O5 (input clk, input [7:0] din, output [7:0] dout); .ff_d(bo5)); endmodule -module clb_BFFMUX_O6 (input clk, input [7:0] din, output [7:0] dout); +module clb_NFFMUX_O6 (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=-1; wire bo6; @@ -277,7 +277,7 @@ module clb_BFFMUX_O6 (input clk, input [7:0] din, output [7:0] dout); .ff_d(bo6)); endmodule -module clb_BFFMUX_XOR (input clk, input [7:0] din, output [7:0] dout); +module clb_NFFMUX_XOR (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=-1; wire caro;