From dd3424450a4fc336b9aafa30d363ca8779737f9e Mon Sep 17 00:00:00 2001 From: John McMaster Date: Tue, 5 Dec 2017 16:08:40 -0800 Subject: [PATCH] clbnoutmux fuzzer Signed-off-by: John McMaster Signed-off-by: Tim 'mithro' Ansell --- fuzzers/016-clbnoutmux/.gitignore | 4 + fuzzers/016-clbnoutmux/Makefile | 22 ++ fuzzers/016-clbnoutmux/README.txt | 40 ++++ fuzzers/016-clbnoutmux/generate.py | 46 +++++ fuzzers/016-clbnoutmux/generate.sh | 18 ++ fuzzers/016-clbnoutmux/generate.tcl | 26 +++ fuzzers/016-clbnoutmux/top.py | 302 ++++++++++++++++++++++++++++ minitests/clb_nffmux/top.v | 2 +- minitests/clb_noutmux/top.v | 181 ++++++++++------- 9 files changed, 566 insertions(+), 75 deletions(-) create mode 100644 fuzzers/016-clbnoutmux/.gitignore create mode 100644 fuzzers/016-clbnoutmux/Makefile create mode 100644 fuzzers/016-clbnoutmux/README.txt create mode 100644 fuzzers/016-clbnoutmux/generate.py create mode 100644 fuzzers/016-clbnoutmux/generate.sh create mode 100644 fuzzers/016-clbnoutmux/generate.tcl create mode 100644 fuzzers/016-clbnoutmux/top.py diff --git a/fuzzers/016-clbnoutmux/.gitignore b/fuzzers/016-clbnoutmux/.gitignore new file mode 100644 index 00000000..93b5bef8 --- /dev/null +++ b/fuzzers/016-clbnoutmux/.gitignore @@ -0,0 +1,4 @@ +/specimen_*/ +/*.segbits +/vivado.log +/vivado.jou diff --git a/fuzzers/016-clbnoutmux/Makefile b/fuzzers/016-clbnoutmux/Makefile new file mode 100644 index 00000000..cdd3cf23 --- /dev/null +++ b/fuzzers/016-clbnoutmux/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/016-clbnoutmux/README.txt b/fuzzers/016-clbnoutmux/README.txt new file mode 100644 index 00000000..66451f7e --- /dev/null +++ b/fuzzers/016-clbnoutmux/README.txt @@ -0,0 +1,40 @@ +Purpose: +Document AOUTMUX family of CLB muxes + +Algorithm: + +Outcome: + +CLB.SLICE_X0.AMUX.B0 30_11 +CLB.SLICE_X0.AMUX.B1 30_08 +CLB.SLICE_X0.AMUX.B2 30_06 +CLB.SLICE_X0.AMUX.B3 30_07 +CLB.SLICE_X0.BMUX.B0 30_20 +CLB.SLICE_X0.BMUX.B1 30_21 +CLB.SLICE_X0.BMUX.B2 30_22 +CLB.SLICE_X0.BMUX.B3 30_23 +CLB.SLICE_X0.CMUX.B0 30_45 +CLB.SLICE_X0.CMUX.B1 30_44 +CLB.SLICE_X0.CMUX.B2 30_40 +CLB.SLICE_X0.CMUX.B3 30_43 +CLB.SLICE_X0.DMUX.B0 30_56 +CLB.SLICE_X0.DMUX.B1 30_51 +CLB.SLICE_X0.DMUX.B2 30_52 +CLB.SLICE_X0.DMUX.B3 30_57 +CLB.SLICE_X1.AMUX.B0 31_09 +CLB.SLICE_X1.AMUX.B1 31_07 +CLB.SLICE_X1.AMUX.B2 31_10 +CLB.SLICE_X1.AMUX.B3 30_05 +CLB.SLICE_X1.BMUX.B0 31_20 +CLB.SLICE_X1.BMUX.B1 30_28 +CLB.SLICE_X1.BMUX.B2 31_21 +CLB.SLICE_X1.BMUX.B3 30_29 +CLB.SLICE_X1.CMUX.B0 31_43 +CLB.SLICE_X1.CMUX.B1 30_42 +CLB.SLICE_X1.CMUX.B2 31_40 +CLB.SLICE_X1.CMUX.B3 30_41 +CLB.SLICE_X1.DMUX.B0 31_56 +CLB.SLICE_X1.DMUX.B1 30_53 +CLB.SLICE_X1.DMUX.B2 31_57 +CLB.SLICE_X1.DMUX.B3 31_53 + diff --git a/fuzzers/016-clbnoutmux/generate.py b/fuzzers/016-clbnoutmux/generate.py new file mode 100644 index 00000000..ffd969fd --- /dev/null +++ b/fuzzers/016-clbnoutmux/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_NOUTMUX_', '') + + ''' + BOUTMUX + 30_20 30_21 30_22 30_23 + O6 1 + O5 1 1 + XOR 1 + CY 1 1 + F8 1 1 + B5Q 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, "%cMUX.B0" % which, module in ('O6', 'O5')) + segmk.addtag(loc, "%cMUX.B1" % which, module in ('XOR', 'CY')) + segmk.addtag(loc, "%cMUX.B2" % which, module in ('O5', 'CY', 'F78')) + segmk.addtag(loc, "%cMUX.B3" % which, module in ('F78', 'B5Q')) + +segmk.compile() +segmk.write() + diff --git a/fuzzers/016-clbnoutmux/generate.sh b/fuzzers/016-clbnoutmux/generate.sh new file mode 100644 index 00000000..93c44166 --- /dev/null +++ b/fuzzers/016-clbnoutmux/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/016-clbnoutmux/generate.tcl b/fuzzers/016-clbnoutmux/generate.tcl new file mode 100644 index 00000000..86162f92 --- /dev/null +++ b/fuzzers/016-clbnoutmux/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/016-clbnoutmux/top.py b/fuzzers/016-clbnoutmux/top.py new file mode 100644 index 00000000..cd13373f --- /dev/null +++ b/fuzzers/016-clbnoutmux/top.py @@ -0,0 +1,302 @@ +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): + # Don't have an O6 example + modules = ['clb_NOUTMUX_' + x for x in ['CY', 'F78', 'O5', 'XOR', 'B5Q']] + module = random.choice(modules) + + if module == 'clb_NOUTMUX_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, + //Note: b5ff_q requires the mux and will conflict with other wires + //Otherwise this FF drops out + output wire ff_q); + //output wire [3:0] n5ff_q); + parameter N=-1; + parameter LOC="SLICE_FIXME"; + + wire [3:0] caro_all; + assign caro = caro_all[N]; + wire [3:0] carco_all; + assign carco = carco_all[N]; + + wire [3:0] lutno6; + assign bo6 = lutno6[N]; + wire [3:0] lutno5; + assign bo5 = lutno5[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="D5FF", KEEP, DONT_TOUCH *) + FDPE d5ff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(lutno5[3])); + end + if (N == 2) begin + (* LOC=LOC, BEL="C5FF", KEEP, DONT_TOUCH *) + FDPE c5ff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(lutno5[2])); + end + if (N == 1) begin + (* LOC=LOC, BEL="B5FF", KEEP, DONT_TOUCH *) + FDPE b5ff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(lutno5[1])); + end + if (N == 0) begin + (* LOC=LOC, BEL="A5FF", KEEP, DONT_TOUCH *) + FDPE a5ff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(lutno5[0])); + end + endgenerate +endmodule + +//****************************************************************************** +//BOUTMUX tests + +module clb_NOUTMUX_CY (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=1; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), .lut8o(), + .caro(), .carco(dout[0]), + .bo5(), .bo6(), + .ff_q()); +endmodule + +//clb_NOUTMUX_F78: already have above as clb_LUT8 +module clb_NOUTMUX_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 + */ + generate + if (N == 3) begin + //No muxes, so this is undefined + invalid_configuration invalid_configuration3(); + end else if (N == 2) begin + assign dout[0] = lut7bo; + end else if (N == 1) begin + assign dout[0] = lut8o; + end else if (N == 0) begin + assign dout[0] = 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()); +endmodule + +module clb_NOUTMUX_O5 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=1; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), .lut8o(), + .caro(), .carco(), + .bo5(dout[0]), .bo6(), + .ff_q()); +endmodule + +/* +//FIXME: need to force it to use both X and O6 +module clb_NOUTMUX_O6 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=1; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), .lut8o(), .co(), .carco(), .bo5(), .bo6()); +endmodule +*/ + +module clb_NOUTMUX_XOR (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=1; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), .lut8o(), + .caro(dout[0]), .carco(), + .bo5(), .bo6(), + .ff_q()); +endmodule + +module clb_NOUTMUX_B5Q (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=1; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), + .lut8o(), + .caro(), .carco(), + .bo5(), .bo6(), + .ff_q(dout[0])); +endmodule +''') + diff --git a/minitests/clb_nffmux/top.v b/minitests/clb_nffmux/top.v index 259f7f1f..4025cc2d 100644 --- a/minitests/clb_nffmux/top.v +++ b/minitests/clb_nffmux/top.v @@ -64,9 +64,9 @@ module myLUT8 (input clk, input [7:0] din, assign carco = carco_all[N]; wire [3:0] lutno6; + assign bo6 = lutno6[N]; 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 *) diff --git a/minitests/clb_noutmux/top.v b/minitests/clb_noutmux/top.v index febbe982..2081709a 100644 --- a/minitests/clb_noutmux/top.v +++ b/minitests/clb_noutmux/top.v @@ -29,30 +29,42 @@ module top(input clk, stb, di, output do); endmodule module roi(input clk, input [255:0] din, output [255:0] dout); - parameter N=1; + parameter N=3; - clb_BOUTMUX_CY #(.LOC("SLICE_X18Y100"), .N(N)) - clb_BOUTMUX_CY (.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); - clb_BOUTMUX_F8 #(.LOC("SLICE_X18Y101"), .N(N)) - clb_BOUTMUX_F8 (.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); - //clb_BOUTMUX_O6 #(.LOC("SLICE_X18Y102"), .N(N)) - // clb_BOUTMUX_O6 (.clk(clk), .din(din[ 24 +: 8]), .dout(dout[ 24 +: 8])); - clb_BOUTMUX_O5 #(.LOC("SLICE_X18Y103"), .N(N)) - clb_BOUTMUX_O5 (.clk(clk), .din(din[ 32 +: 8]), .dout(dout[ 32 +: 8])); - clb_BOUTMUX_B5Q #(.LOC("SLICE_X18Y104"), .N(N)) - clb_BOUTMUX_B5Q (.clk(clk), .din(din[ 48 +: 8]), .dout(dout[ 48 +: 8 ])); - clb_BOUTMUX_XOR #(.LOC("SLICE_X18Y105"), .N(N)) - clb_BOUTMUX_XOR (.clk(clk), .din(din[ 56 +: 8]), .dout(dout[ 56 +: 8 ])); + //ok + clb_NOUTMUX_CY #(.LOC("SLICE_X18Y100"), .N(N)) + clb_NOUTMUX_CY (.clk(clk), .din(din[ 8 +: 8]), .dout(dout[ 8 +: 8])); + //ok + generate + if (N != 3) begin + clb_NOUTMUX_F78 #(.LOC("SLICE_X18Y101"), .N(N)) + clb_NOUTMUX_F78 (.clk(clk), .din(din[ 16 +: 8]), .dout(dout[ 16 +: 8])); + end + endgenerate + //ok + clb_NOUTMUX_O5 #(.LOC("SLICE_X18Y102"), .N(N)) + clb_NOUTMUX_O5 (.clk(clk), .din(din[ 32 +: 8]), .dout(dout[ 32 +: 8])); + //clb_NOUTMUX_O6 #(.LOC("SLICE_X18Y103"), .N(N)) + // clb_NOUTMUX_O6 (.clk(clk), .din(din[ 24 +: 8]), .dout(dout[ 24 +: 8])); + //FIXME + clb_NOUTMUX_XOR #(.LOC("SLICE_X18Y104"), .N(N)) + clb_NOUTMUX_XOR (.clk(clk), .din(din[ 56 +: 8]), .dout(dout[ 56 +: 8 ])); + //ok + clb_NOUTMUX_B5Q #(.LOC("SLICE_X18Y105"), .N(N)) + clb_NOUTMUX_B5Q (.clk(clk), .din(din[ 48 +: 8]), .dout(dout[ 48 +: 8 ])); endmodule module myLUT8 (input clk, input [7:0] din, - output lut8o, + 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, //Note: b5ff_q requires the mux and will conflict with other wires //Otherwise this FF drops out output wire ff_q); //output wire [3:0] n5ff_q); + parameter N=-1; parameter LOC="SLICE_FIXME"; wire [3:0] caro_all; @@ -60,14 +72,10 @@ module myLUT8 (input clk, input [7:0] din, wire [3:0] carco_all; assign carco = carco_all[N]; - wire [3:0] n5ff_q; - ff_q = n5ff_q[N]; - wire [3:0] lutno6; + assign bo6 = lutno6[N]; wire [3:0] lutno5; - wire lut7bo, lut7ao; - assign bo5 = lutno5[1]; - assign bo6 = lutno6[1]; + assign bo5 = lutno5[N]; //Outputs does not have to be used, will stay without it (* LOC=LOC, BEL="F8MUX", KEEP, DONT_TOUCH *) @@ -131,42 +139,52 @@ module myLUT8 (input clk, input [7:0] din, //Outputs do not have to be used, will stay without them (* LOC=LOC, KEEP, DONT_TOUCH *) - CARRY4 carry4(.O(co), .CO(cout), .DI(lutno5), .S(lutno6), .CYINIT(1'b0), .CI()); + CARRY4 carry4(.O(caro_all), .CO(carco_all), .DI(lutno5), .S(lutno6), .CYINIT(1'b0), .CI()); - (* LOC=LOC, BEL="D5FF", KEEP, DONT_TOUCH *) - FDPE d5ff ( - .C(clk), - .Q(n5ff_q[3]), - .CE(1'b1), - .PRE(1'b0), - .D(lutno5[3])); - (* LOC=LOC, BEL="C5FF", KEEP, DONT_TOUCH *) - FDPE c5ff ( - .C(clk), - .Q(n5ff_q[2]), - .CE(1'b1), - .PRE(1'b0), - .D(lutno5[2])); - (* LOC=LOC, BEL="B5FF", KEEP, DONT_TOUCH *) - FDPE b5ff ( - .C(clk), - .Q(n5ff_q[1]), - .CE(1'b1), - .PRE(1'b0), - .D(lutno5[1])); - (* LOC=LOC, BEL="A5FF", KEEP, DONT_TOUCH *) - FDPE a5ff ( - .C(clk), - .Q(n5ff_q[0]), - .CE(1'b1), - .PRE(1'b0), - .D(lutno5[0])); + generate + if (N == 3) begin + (* LOC=LOC, BEL="D5FF", KEEP, DONT_TOUCH *) + FDPE d5ff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(lutno5[3])); + end + if (N == 2) begin + (* LOC=LOC, BEL="C5FF", KEEP, DONT_TOUCH *) + FDPE c5ff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(lutno5[2])); + end + if (N == 1) begin + (* LOC=LOC, BEL="B5FF", KEEP, DONT_TOUCH *) + FDPE b5ff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(lutno5[1])); + end + if (N == 0) begin + (* LOC=LOC, BEL="A5FF", KEEP, DONT_TOUCH *) + FDPE a5ff ( + .C(clk), + .Q(ff_q), + .CE(1'b1), + .PRE(1'b0), + .D(lutno5[0])); + end + endgenerate endmodule //****************************************************************************** //BOUTMUX tests -module clb_BOUTMUX_CY (input clk, input [7:0] din, output [7:0] dout); +module clb_NOUTMUX_CY (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=1; @@ -177,21 +195,52 @@ module clb_BOUTMUX_CY (input clk, input [7:0] din, output [7:0] dout); .ff_q()); endmodule -//clb_BOUTMUX_F8: already have above as clb_LUT8 -module clb_BOUTMUX_F8 (input clk, input [7:0] din, output [7:0] dout); +//clb_NOUTMUX_F78: already have above as clb_LUT8 +module clb_NOUTMUX_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 + */ + generate + if (N == 3) begin + //No muxes, so this is undefined + invalid_configuration invalid_configuration3(); + end else if (N == 2) begin + assign dout[0] = lut7bo; + end else if (N == 1) begin + assign dout[0] = lut8o; + end else if (N == 0) begin + assign dout[0] = lut7ao; + end + endgenerate myLUT8 #(.LOC(LOC), .N(N)) - myLUT8(.clk(clk), .din(din), .lut8o(dout[0]), + myLUT8(.clk(clk), .din(din), + .lut8o(lut8o), .lut7bo(lut7bo), .lut7ao(lut7ao), .caro(), .carco(), .bo5(), .bo6(), .ff_q()); endmodule +module clb_NOUTMUX_O5 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC="SLICE_FIXME"; + parameter N=1; + + myLUT8 #(.LOC(LOC), .N(N)) + myLUT8(.clk(clk), .din(din), .lut8o(), + .caro(), .carco(), + .bo5(dout[0]), .bo6(), + .ff_q()); +endmodule + /* //FIXME: need to force it to use both X and O6 -module clb_BOUTMUX_O6 (input clk, input [7:0] din, output [7:0] dout); +module clb_NOUTMUX_O6 (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=1; @@ -200,18 +249,18 @@ module clb_BOUTMUX_O6 (input clk, input [7:0] din, output [7:0] dout); endmodule */ -module clb_BOUTMUX_O5 (input clk, input [7:0] din, output [7:0] dout); +module clb_NOUTMUX_XOR (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=1; myLUT8 #(.LOC(LOC), .N(N)) myLUT8(.clk(clk), .din(din), .lut8o(), - .caro(), .carco(), - .bo5(dout[1]), .bo6(), + .caro(dout[0]), .carco(), + .bo5(), .bo6(), .ff_q()); endmodule -module clb_BOUTMUX_B5Q (input clk, input [7:0] din, output [7:0] dout); +module clb_NOUTMUX_B5Q (input clk, input [7:0] din, output [7:0] dout); parameter LOC="SLICE_FIXME"; parameter N=1; @@ -223,19 +272,3 @@ module clb_BOUTMUX_B5Q (input clk, input [7:0] din, output [7:0] dout); .ff_q(dout[0])); endmodule -module clb_BOUTMUX_XOR (input clk, input [7:0] din, output [7:0] dout); - parameter LOC="SLICE_FIXME"; - parameter N=1; - - //Shady connections, just enough to keep it placed - wire [3:0] co; - assign dout = co[1]; - - myLUT8 #(.LOC(LOC), .N(N)) - myLUT8(.clk(clk), .din(din), .lut8o(), - .caro(co), .cout(), - .bo5(), .bo6(), - .ff_q()); -endmodule - -