aboutsummaryrefslogtreecommitdiffstats
path: root/techlibs/xilinx/tests
diff options
context:
space:
mode:
Diffstat (limited to 'techlibs/xilinx/tests')
-rw-r--r--techlibs/xilinx/tests/.gitignore12
-rw-r--r--techlibs/xilinx/tests/test_dsp48_model.sh14
-rw-r--r--techlibs/xilinx/tests/test_dsp48_model.v287
-rw-r--r--techlibs/xilinx/tests/test_dsp48a1_model.sh17
-rw-r--r--techlibs/xilinx/tests/test_dsp48a1_model.v331
-rw-r--r--techlibs/xilinx/tests/test_dsp_model.sh17
-rw-r--r--techlibs/xilinx/tests/test_dsp_model.v652
7 files changed, 1330 insertions, 0 deletions
diff --git a/techlibs/xilinx/tests/.gitignore b/techlibs/xilinx/tests/.gitignore
index 496b87461..0d9c28fde 100644
--- a/techlibs/xilinx/tests/.gitignore
+++ b/techlibs/xilinx/tests/.gitignore
@@ -4,3 +4,15 @@ bram1_[0-9]*/
bram2.log
bram2_syn.v
bram2_tb
+dsp_work*/
+test_dsp_model_ref.v
+test_dsp_model_uut.v
+test_dsp_model
+test_dsp48a_model_ref.v
+test_dsp48a1_model_ref.v
+test_dsp48a1_model_uut.v
+test_dsp48a1_model
+test_dsp48_model_ref.v
+test_dsp48_model_uut.v
+test_dsp48_model
+*.vcd
diff --git a/techlibs/xilinx/tests/test_dsp48_model.sh b/techlibs/xilinx/tests/test_dsp48_model.sh
new file mode 100644
index 000000000..9a73f9b0c
--- /dev/null
+++ b/techlibs/xilinx/tests/test_dsp48_model.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+set -ex
+if [ -z $ISE_DIR ]; then
+ ISE_DIR=/opt/Xilinx/ISE/14.7
+fi
+sed 's/DSP48 /DSP48_UUT /; /DSP48_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp48_model_uut.v
+if [ ! -f "test_dsp48_model_ref.v" ]; then
+ cp $ISE_DIR/ISE_DS/ISE/verilog/src/unisims/DSP48.v test_dsp48_model_ref.v
+fi
+for tb in mult_allreg mult_noreg mult_inreg
+do
+ iverilog -s $tb -s glbl -o test_dsp48_model test_dsp48_model.v test_dsp48_model_uut.v test_dsp48_model_ref.v $ISE_DIR/ISE_DS/ISE/verilog/src/glbl.v
+ vvp -N ./test_dsp48_model
+done
diff --git a/techlibs/xilinx/tests/test_dsp48_model.v b/techlibs/xilinx/tests/test_dsp48_model.v
new file mode 100644
index 000000000..d69c00e93
--- /dev/null
+++ b/techlibs/xilinx/tests/test_dsp48_model.v
@@ -0,0 +1,287 @@
+`timescale 1ns / 1ps
+
+module testbench;
+ parameter integer AREG = 1;
+ parameter integer BREG = 1;
+ parameter integer CREG = 1;
+ parameter integer MREG = 1;
+ parameter integer PREG = 1;
+ parameter integer CARRYINREG = 1;
+ parameter integer CARRYINSELREG = 1;
+ parameter integer OPMODEREG = 1;
+ parameter integer SUBTRACTREG = 1;
+ parameter B_INPUT = "DIRECT";
+ parameter LEGACY_MODE = "NONE";
+
+ reg CLK;
+ reg CEA, CEB, CEC, CEM, CEP, CECARRYIN, CECINSUB, CECTRL;
+ reg RSTA, RSTB, RSTC, RSTM, RSTP, RSTCARRYIN, RSTCTRL;
+ reg [17:0] A;
+ reg [17:0] B;
+ reg [47:0] C;
+ reg [17:0] BCIN;
+ reg [47:0] PCIN;
+ reg CARRYIN;
+ reg [6:0] OPMODE;
+ reg SUBTRACT;
+ reg [1:0] CARRYINSEL;
+
+ output [47:0] P, REF_P;
+ output [17:0] BCOUT, REF_BCOUT;
+ output [47:0] PCOUT, REF_PCOUT;
+
+ integer errcount = 0;
+
+ reg ERROR_FLAG = 0;
+
+ task clkcycle;
+ begin
+ #5;
+ CLK = ~CLK;
+ #10;
+ CLK = ~CLK;
+ #2;
+ ERROR_FLAG = 0;
+ if (REF_BCOUT !== BCOUT) begin
+ $display("ERROR at %1t: REF_BCOUT=%b UUT_BCOUT=%b DIFF=%b", $time, REF_BCOUT, BCOUT, REF_BCOUT ^ BCOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_P !== P) begin
+ $display("ERROR at %1t: REF_P=%b UUT_P=%b DIFF=%b", $time, REF_P, P, REF_P ^ P);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_PCOUT !== PCOUT) begin
+ $display("ERROR at %1t: REF_PCOUT=%b UUT_PCOUT=%b DIFF=%b", $time, REF_PCOUT, PCOUT, REF_PCOUT ^ PCOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ #3;
+ end
+ endtask
+
+ reg config_valid = 0;
+ task drc;
+ begin
+ config_valid = 1;
+
+ if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0;
+ if (OPMODE[1:0] == 2'b00 && CARRYINSEL == 2'b10) config_valid = 0;
+ if (OPMODE[1:0] == 2'b10 && CARRYINSEL == 2'b10) config_valid = 0;
+ if (OPMODE[1:0] == 2'b00 && CARRYINSEL == 2'b11) config_valid = 0;
+ if (OPMODE[1:0] == 2'b10 && CARRYINSEL == 2'b11) config_valid = 0;
+ if (OPMODE[3:2] == 2'b10) config_valid = 0;
+ if ((OPMODE[3:2] == 2'b01) ^ (OPMODE[1:0] == 2'b01) == 1'b1) config_valid = 0;
+ if ((OPMODE[6:4] == 3'b010 || OPMODE[6:4] == 3'b110) && PREG != 1) config_valid = 0;
+ if (OPMODE[6:4] == 3'b100) config_valid = 0;
+ if (OPMODE[6:4] == 3'b111) config_valid = 0;
+ if (OPMODE[6:4] == 3'b000 && CARRYINSEL == 2'b01) config_valid = 0;
+ if (OPMODE[6:4] == 3'b011 && CARRYINSEL == 2'b01) config_valid = 0;
+
+ // Xilinx models consider these combinations invalid for an unknown reason.
+ if (CARRYINSEL == 2'b01 && OPMODE[3:2] == 2'b00) config_valid = 0;
+ if (CARRYINSEL == 2'b10 && OPMODE == 7'b0000011) config_valid = 0;
+ if (CARRYINSEL == 2'b10 && OPMODE == 7'b0000101) config_valid = 0;
+ if (CARRYINSEL == 2'b10 && OPMODE == 7'b0100011) config_valid = 0;
+ if (CARRYINSEL == 2'b10 && OPMODE == 7'b0111111) config_valid = 0;
+ if (CARRYINSEL == 2'b10 && OPMODE == 7'b1100011) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0000011) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0000101) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0011111) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0010011) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0100011) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0100101) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0101111) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0110011) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b0111111) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b1010011) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b1011111) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b1100011) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b1100101) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE == 7'b1101111) config_valid = 0;
+
+ if (CARRYINSEL == 2'b10 && OPMODE[3:0] == 4'b0101 && MREG == 1) config_valid = 0;
+ if (CARRYINSEL == 2'b11 && OPMODE[3:0] == 4'b0101 && MREG == 0) config_valid = 0;
+ end
+ endtask
+
+ initial begin
+ $dumpfile("test_dsp48_model.vcd");
+ $dumpvars(0, testbench);
+
+ #2;
+ CLK = 1'b0;
+ {CEA, CEB, CEC, CEM, CEP, CECARRYIN, CECINSUB, CECTRL} = 8'b11111111;
+ {A, B, C, PCIN, OPMODE, SUBTRACT, CARRYIN, CARRYINSEL} = 0;
+ {RSTA, RSTB, RSTC, RSTM, RSTP, RSTCARRYIN, RSTCTRL} = 7'b1111111;
+ repeat (10) begin
+ #10;
+ CLK = 1'b1;
+ #10;
+ CLK = 1'b0;
+ #10;
+ CLK = 1'b1;
+ #10;
+ CLK = 1'b0;
+ end
+ {RSTA, RSTB, RSTC, RSTM, RSTP, RSTCARRYIN, RSTCTRL} = 0;
+
+ repeat (100000) begin
+ clkcycle;
+ config_valid = 0;
+ while (!config_valid) begin
+ A = $urandom;
+ B = $urandom;
+ C = {$urandom, $urandom};
+ BCIN = $urandom;
+ PCIN = {$urandom, $urandom};
+
+ {CEA, CEB, CEC, CEM, CEP, CECARRYIN, CECINSUB, CECTRL} = $urandom | $urandom | $urandom;
+ {RSTA, RSTB, RSTC, RSTM, RSTP, RSTCARRYIN, RSTCTRL} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom;
+ {CARRYIN, CARRYINSEL, OPMODE, SUBTRACT} = $urandom;
+
+ drc;
+ end
+ end
+
+ if (errcount == 0) begin
+ $display("All tests passed.");
+ $finish;
+ end else begin
+ $display("Caught %1d errors.", errcount);
+ $stop;
+ end
+ end
+
+ DSP48 #(
+ .AREG (AREG),
+ .BREG (BREG),
+ .CREG (CREG),
+ .MREG (MREG),
+ .PREG (PREG),
+ .CARRYINREG (CARRYINREG),
+ .CARRYINSELREG (CARRYINSELREG),
+ .OPMODEREG (OPMODEREG),
+ .SUBTRACTREG (SUBTRACTREG),
+ .B_INPUT (B_INPUT),
+ .LEGACY_MODE (LEGACY_MODE)
+ ) ref (
+ .A (A),
+ .B (B),
+ .C (C),
+ .BCIN (BCIN),
+ .PCIN (PCIN),
+ .CARRYIN (CARRYIN),
+ .OPMODE (OPMODE),
+ .SUBTRACT (SUBTRACT),
+ .CARRYINSEL (CARRYINSEL),
+ .BCOUT (REF_BCOUT),
+ .P (REF_P),
+ .PCOUT (REF_PCOUT),
+ .CEA (CEA),
+ .CEB (CEB),
+ .CEC (CEC),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CECARRYIN (CECARRYIN),
+ .CECINSUB (CECINSUB),
+ .CECTRL (CECTRL),
+ .CLK (CLK),
+ .RSTA (RSTA),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTM (RSTM),
+ .RSTP (RSTP),
+ .RSTCARRYIN (RSTCARRYIN),
+ .RSTCTRL (RSTCTRL)
+ );
+
+ DSP48_UUT #(
+ .AREG (AREG),
+ .BREG (BREG),
+ .CREG (CREG),
+ .MREG (MREG),
+ .PREG (PREG),
+ .CARRYINREG (CARRYINREG),
+ .CARRYINSELREG (CARRYINSELREG),
+ .OPMODEREG (OPMODEREG),
+ .SUBTRACTREG (SUBTRACTREG),
+ .B_INPUT (B_INPUT),
+ .LEGACY_MODE (LEGACY_MODE)
+ ) uut (
+ .A (A),
+ .B (B),
+ .C (C),
+ .BCIN (BCIN),
+ .PCIN (PCIN),
+ .CARRYIN (CARRYIN),
+ .OPMODE (OPMODE),
+ .SUBTRACT (SUBTRACT),
+ .CARRYINSEL (CARRYINSEL),
+ .BCOUT (BCOUT),
+ .P (P),
+ .PCOUT (PCOUT),
+ .CEA (CEA),
+ .CEB (CEB),
+ .CEC (CEC),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CECARRYIN (CECARRYIN),
+ .CECINSUB (CECINSUB),
+ .CECTRL (CECTRL),
+ .CLK (CLK),
+ .RSTA (RSTA),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTM (RSTM),
+ .RSTP (RSTP),
+ .RSTCARRYIN (RSTCARRYIN),
+ .RSTCTRL (RSTCTRL)
+ );
+endmodule
+
+module mult_noreg;
+ testbench #(
+ .AREG (0),
+ .BREG (0),
+ .CREG (0),
+ .MREG (0),
+ .PREG (0),
+ .CARRYINREG (0),
+ .CARRYINSELREG (0),
+ .OPMODEREG (0),
+ .SUBTRACTREG (0),
+ .B_INPUT ("DIRECT")
+ ) testbench ();
+endmodule
+
+module mult_allreg;
+ testbench #(
+ .AREG (1),
+ .BREG (1),
+ .CREG (1),
+ .MREG (1),
+ .PREG (1),
+ .CARRYINREG (1),
+ .CARRYINSELREG (1),
+ .OPMODEREG (1),
+ .SUBTRACTREG (1),
+ .B_INPUT ("CASCADE")
+ ) testbench ();
+endmodule
+
+module mult_inreg;
+ testbench #(
+ .AREG (1),
+ .BREG (1),
+ .CREG (1),
+ .MREG (0),
+ .PREG (0),
+ .CARRYINREG (1),
+ .CARRYINSELREG (0),
+ .OPMODEREG (0),
+ .SUBTRACTREG (0),
+ .B_INPUT ("DIRECT")
+ ) testbench ();
+endmodule
diff --git a/techlibs/xilinx/tests/test_dsp48a1_model.sh b/techlibs/xilinx/tests/test_dsp48a1_model.sh
new file mode 100644
index 000000000..a14a78e72
--- /dev/null
+++ b/techlibs/xilinx/tests/test_dsp48a1_model.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -ex
+if [ -z $ISE_DIR ]; then
+ ISE_DIR=/opt/Xilinx/ISE/14.7
+fi
+sed 's/DSP48A1/MARKER1/; s/DSP48A/DSP48A_UUT/; s/MARKER1/DSP48A1_UUT/; /module DSP48A_UUT/,/endmodule/ p; /module DSP48A1_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp48a1_model_uut.v
+if [ ! -f "test_dsp48a1_model_ref.v" ]; then
+ cp $ISE_DIR/ISE_DS/ISE/verilog/src/unisims/DSP48A1.v test_dsp48a1_model_ref.v
+fi
+if [ ! -f "test_dsp48a_model_ref.v" ]; then
+ cp $ISE_DIR/ISE_DS/ISE/verilog/src/unisims/DSP48A.v test_dsp48a_model_ref.v
+fi
+for tb in mult_allreg mult_noreg mult_inreg
+do
+ iverilog -s $tb -s glbl -o test_dsp48a1_model test_dsp48a1_model.v test_dsp48a1_model_uut.v test_dsp48a1_model_ref.v test_dsp48a_model_ref.v $ISE_DIR/ISE_DS/ISE/verilog/src/glbl.v
+ vvp -N ./test_dsp48a1_model
+done
diff --git a/techlibs/xilinx/tests/test_dsp48a1_model.v b/techlibs/xilinx/tests/test_dsp48a1_model.v
new file mode 100644
index 000000000..66346b47b
--- /dev/null
+++ b/techlibs/xilinx/tests/test_dsp48a1_model.v
@@ -0,0 +1,331 @@
+`timescale 1ns / 1ps
+
+module testbench;
+ parameter integer A0REG = 1;
+ parameter integer A1REG = 1;
+ parameter integer B0REG = 1;
+ parameter integer B1REG = 1;
+ parameter integer CREG = 1;
+ parameter integer DREG = 1;
+ parameter integer MREG = 1;
+ parameter integer PREG = 1;
+ parameter integer CARRYINREG = 1;
+ parameter integer CARRYOUTREG = 1;
+ parameter integer OPMODEREG = 1;
+ parameter CARRYINSEL = "OPMODE5";
+ parameter RSTTYPE = "SYNC";
+
+ reg CLK;
+ reg CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE;
+ reg RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE;
+ reg [17:0] A;
+ reg [17:0] B;
+ reg [47:0] C;
+ reg [17:0] D;
+ reg [47:0] PCIN;
+ reg [7:0] OPMODE;
+ reg CARRYIN;
+
+ output CARRYOUTF, REF_CARRYOUTF;
+ output CARRYOUT, REF_CARRYOUT, REF_OLD_CARRYOUT;
+ output [35:0] M, REF_M;
+ output [47:0] P, REF_P, REF_OLD_P;
+ output [17:0] BCOUT, REF_BCOUT, REF_OLD_BCOUT;
+ output [47:0] PCOUT, REF_PCOUT, REF_OLD_PCOUT;
+
+ integer errcount = 0;
+
+ reg ERROR_FLAG = 0;
+
+ task clkcycle;
+ begin
+ #5;
+ CLK = ~CLK;
+ #10;
+ CLK = ~CLK;
+ #2;
+ ERROR_FLAG = 0;
+ if (REF_BCOUT !== BCOUT || REF_OLD_BCOUT != BCOUT) begin
+ $display("ERROR at %1t: REF_BCOUT=%b REF_OLD_BCOUT=%b UUT_BCOUT=%b DIFF=%b", $time, REF_BCOUT, REF_OLD_BCOUT, BCOUT, REF_BCOUT ^ BCOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_M !== M) begin
+ $display("ERROR at %1t: REF_M=%b UUT_M=%b DIFF=%b", $time, REF_M, M, REF_M ^ M);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_P !== P || REF_OLD_P != P) begin
+ $display("ERROR at %1t: REF_P=%b REF_OLD_P=%b UUT_P=%b DIFF=%b", $time, REF_P, REF_OLD_P, P, REF_P ^ P);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_PCOUT !== PCOUT || REF_OLD_PCOUT != PCOUT) begin
+ $display("ERROR at %1t: REF_PCOUT=%b REF_OLD_PCOUT=%b UUT_PCOUT=%b DIFF=%b", $time, REF_PCOUT, REF_OLD_PCOUT, PCOUT, REF_PCOUT ^ PCOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_CARRYOUT !== CARRYOUT || (REF_OLD_CARRYOUT != CARRYOUT && !CARRYOUTREG)) begin
+ $display("ERROR at %1t: REF_CARRYOUT=%b REF_OLD_CARRYOUT=%b UUT_CARRYOUT=%b DIFF=%b", $time, REF_CARRYOUT, REF_OLD_CARRYOUT, CARRYOUT, REF_CARRYOUT ^ CARRYOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_CARRYOUTF !== CARRYOUTF) begin
+ $display("ERROR at %1t: REF_CARRYOUTF=%b UUT_CARRYOUTF=%b", $time, REF_CARRYOUTF, CARRYOUTF);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ #3;
+ end
+ endtask
+
+ reg config_valid = 0;
+ task drc;
+ begin
+ config_valid = 1;
+
+ if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0;
+ if (OPMODE[3:2] == 2'b10 && PREG != 1) config_valid = 0;
+ end
+ endtask
+
+ initial begin
+ $dumpfile("test_dsp48a1_model.vcd");
+ $dumpvars(0, testbench);
+
+ #2;
+ CLK = 1'b0;
+ {CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE} = 8'b11111111;
+ {A, B, C, D, PCIN, OPMODE, CARRYIN} = 0;
+ {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = 8'b11111111;
+ repeat (10) begin
+ #10;
+ CLK = 1'b1;
+ #10;
+ CLK = 1'b0;
+ #10;
+ CLK = 1'b1;
+ #10;
+ CLK = 1'b0;
+ end
+ {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = 0;
+
+ repeat (10000) begin
+ clkcycle;
+ config_valid = 0;
+ while (!config_valid) begin
+ A = $urandom;
+ B = $urandom;
+ C = {$urandom, $urandom};
+ D = $urandom;
+ PCIN = {$urandom, $urandom};
+
+ {CEA, CEB, CEC, CED, CEM, CEP, CECARRYIN, CEOPMODE} = $urandom | $urandom | $urandom;
+ {RSTA, RSTB, RSTC, RSTD, RSTM, RSTP, RSTCARRYIN, RSTOPMODE} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom;
+ {CARRYIN, OPMODE} = $urandom;
+
+ drc;
+ end
+ end
+
+ if (errcount == 0) begin
+ $display("All tests passed.");
+ $finish;
+ end else begin
+ $display("Caught %1d errors.", errcount);
+ $stop;
+ end
+ end
+
+ DSP48A #(
+ .A0REG (A0REG),
+ .A1REG (A1REG),
+ .B0REG (B0REG),
+ .B1REG (B1REG),
+ .CREG (CREG),
+ .DREG (DREG),
+ .MREG (MREG),
+ .PREG (PREG),
+ .CARRYINREG (CARRYINREG),
+ .OPMODEREG (OPMODEREG),
+ .CARRYINSEL (CARRYINSEL),
+ .RSTTYPE (RSTTYPE)
+ ) ref_old (
+ .A (A),
+ .B (B),
+ .C (C),
+ .D (D),
+ .PCIN (PCIN),
+ .CARRYIN (CARRYIN),
+ .OPMODE (OPMODE),
+ .BCOUT (REF_OLD_BCOUT),
+ .CARRYOUT (REF_OLD_CARRYOUT),
+ .P (REF_OLD_P),
+ .PCOUT (REF_OLD_PCOUT),
+ .CEA (CEA),
+ .CEB (CEB),
+ .CEC (CEC),
+ .CED (CED),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CECARRYIN (CECARRYIN),
+ .CEOPMODE (CEOPMODE),
+ .CLK (CLK),
+ .RSTA (RSTA),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTD (RSTD),
+ .RSTM (RSTM),
+ .RSTP (RSTP),
+ .RSTCARRYIN (RSTCARRYIN),
+ .RSTOPMODE (RSTOPMODE)
+ );
+
+ DSP48A1 #(
+ .A0REG (A0REG),
+ .A1REG (A1REG),
+ .B0REG (B0REG),
+ .B1REG (B1REG),
+ .CREG (CREG),
+ .DREG (DREG),
+ .MREG (MREG),
+ .PREG (PREG),
+ .CARRYINREG (CARRYINREG),
+ .CARRYOUTREG (CARRYOUTREG),
+ .OPMODEREG (OPMODEREG),
+ .CARRYINSEL (CARRYINSEL),
+ .RSTTYPE (RSTTYPE)
+ ) ref (
+ .A (A),
+ .B (B),
+ .C (C),
+ .D (D),
+ .PCIN (PCIN),
+ .CARRYIN (CARRYIN),
+ .OPMODE (OPMODE),
+ .BCOUT (REF_BCOUT),
+ .CARRYOUTF (REF_CARRYOUTF),
+ .CARRYOUT (REF_CARRYOUT),
+ .P (REF_P),
+ .M (REF_M),
+ .PCOUT (REF_PCOUT),
+ .CEA (CEA),
+ .CEB (CEB),
+ .CEC (CEC),
+ .CED (CED),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CECARRYIN (CECARRYIN),
+ .CEOPMODE (CEOPMODE),
+ .CLK (CLK),
+ .RSTA (RSTA),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTD (RSTD),
+ .RSTM (RSTM),
+ .RSTP (RSTP),
+ .RSTCARRYIN (RSTCARRYIN),
+ .RSTOPMODE (RSTOPMODE)
+ );
+
+ DSP48A1_UUT #(
+ .A0REG (A0REG),
+ .A1REG (A1REG),
+ .B0REG (B0REG),
+ .B1REG (B1REG),
+ .CREG (CREG),
+ .DREG (DREG),
+ .MREG (MREG),
+ .PREG (PREG),
+ .CARRYINREG (CARRYINREG),
+ .CARRYOUTREG (CARRYOUTREG),
+ .OPMODEREG (OPMODEREG),
+ .CARRYINSEL (CARRYINSEL),
+ .RSTTYPE (RSTTYPE)
+ ) uut (
+ .A (A),
+ .B (B),
+ .C (C),
+ .D (D),
+ .PCIN (PCIN),
+ .CARRYIN (CARRYIN),
+ .OPMODE (OPMODE),
+ .BCOUT (BCOUT),
+ .CARRYOUTF (CARRYOUTF),
+ .CARRYOUT (CARRYOUT),
+ .P (P),
+ .M (M),
+ .PCOUT (PCOUT),
+ .CEA (CEA),
+ .CEB (CEB),
+ .CEC (CEC),
+ .CED (CED),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CECARRYIN (CECARRYIN),
+ .CEOPMODE (CEOPMODE),
+ .CLK (CLK),
+ .RSTA (RSTA),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTD (RSTD),
+ .RSTM (RSTM),
+ .RSTP (RSTP),
+ .RSTCARRYIN (RSTCARRYIN),
+ .RSTOPMODE (RSTOPMODE)
+ );
+endmodule
+
+module mult_noreg;
+ testbench #(
+ .A0REG (0),
+ .A1REG (0),
+ .B0REG (0),
+ .B1REG (0),
+ .CREG (0),
+ .DREG (0),
+ .MREG (0),
+ .PREG (0),
+ .CARRYINREG (0),
+ .CARRYOUTREG (0),
+ .OPMODEREG (0),
+ .CARRYINSEL ("CARRYIN"),
+ .RSTTYPE ("SYNC")
+ ) testbench ();
+endmodule
+
+module mult_allreg;
+ testbench #(
+ .A0REG (1),
+ .A1REG (1),
+ .B0REG (1),
+ .B1REG (1),
+ .CREG (1),
+ .DREG (1),
+ .MREG (1),
+ .PREG (1),
+ .CARRYINREG (1),
+ .CARRYOUTREG (1),
+ .OPMODEREG (1),
+ .CARRYINSEL ("OPMODE5"),
+ .RSTTYPE ("SYNC")
+ ) testbench ();
+endmodule
+
+module mult_inreg;
+ testbench #(
+ .A0REG (1),
+ .A1REG (1),
+ .B0REG (1),
+ .B1REG (1),
+ .CREG (1),
+ .DREG (1),
+ .MREG (0),
+ .PREG (0),
+ .CARRYINREG (1),
+ .CARRYOUTREG (0),
+ .OPMODEREG (0),
+ .CARRYINSEL ("CARRYIN"),
+ .RSTTYPE ("SYNC")
+ ) testbench ();
+endmodule
diff --git a/techlibs/xilinx/tests/test_dsp_model.sh b/techlibs/xilinx/tests/test_dsp_model.sh
new file mode 100644
index 000000000..d005cd40c
--- /dev/null
+++ b/techlibs/xilinx/tests/test_dsp_model.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+set -ex
+if [ -z $VIVADO_DIR ]; then
+ VIVADO_DIR=/opt/Xilinx/Vivado/2019.1
+fi
+sed 's/DSP48E1/DSP48E1_UUT/; /DSP48E1_UUT/,/endmodule/ p; d;' < ../cells_sim.v > test_dsp_model_uut.v
+if [ ! -f "test_dsp_model_ref.v" ]; then
+ cp $VIVADO_DIR/data/verilog/src/unisims/DSP48E1.v test_dsp_model_ref.v
+fi
+for tb in macc_overflow_underflow \
+ simd24_preadd_noreg_nocasc simd12_preadd_noreg_nocasc \
+ mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc \
+ mult_allreg_preadd_nocasc mult_noreg_preadd_nocasc mult_inreg_preadd_nocasc
+do
+ iverilog -s $tb -s glbl -o test_dsp_model test_dsp_model.v test_dsp_model_uut.v test_dsp_model_ref.v $VIVADO_DIR/data/verilog/src/glbl.v
+ vvp -N ./test_dsp_model
+done
diff --git a/techlibs/xilinx/tests/test_dsp_model.v b/techlibs/xilinx/tests/test_dsp_model.v
new file mode 100644
index 000000000..db012f169
--- /dev/null
+++ b/techlibs/xilinx/tests/test_dsp_model.v
@@ -0,0 +1,652 @@
+`timescale 1ns / 1ps
+
+module testbench;
+ parameter integer ACASCREG = 1;
+ parameter integer ADREG = 1;
+ parameter integer ALUMODEREG = 1;
+ parameter integer AREG = 1;
+ parameter AUTORESET_PATDET = "NO_RESET";
+ parameter A_INPUT = "DIRECT";
+ parameter integer BCASCREG = 1;
+ parameter integer BREG = 1;
+ parameter B_INPUT = "DIRECT";
+ parameter integer CARRYINREG = 1;
+ parameter integer CARRYINSELREG = 1;
+ parameter integer CREG = 1;
+ parameter integer DREG = 1;
+ parameter integer INMODEREG = 1;
+ parameter integer MREG = 1;
+ parameter integer OPMODEREG = 1;
+ parameter integer PREG = 1;
+ parameter SEL_MASK = "MASK";
+ parameter SEL_PATTERN = "PATTERN";
+ parameter USE_DPORT = "FALSE";
+ parameter USE_MULT = "MULTIPLY";
+ parameter USE_PATTERN_DETECT = "NO_PATDET";
+ parameter USE_SIMD = "ONE48";
+ parameter [47:0] MASK = 48'h3FFFFFFFFFFF;
+ parameter [47:0] PATTERN = 48'h000000000000;
+ parameter [3:0] IS_ALUMODE_INVERTED = 4'b0;
+ parameter [0:0] IS_CARRYIN_INVERTED = 1'b0;
+ parameter [0:0] IS_CLK_INVERTED = 1'b0;
+ parameter [4:0] IS_INMODE_INVERTED = 5'b0;
+ parameter [6:0] IS_OPMODE_INVERTED = 7'b0;
+
+ reg CLK;
+ reg CEA1, CEA2, CEAD, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL;
+ reg CED, CEINMODE, CEM, CEP;
+ reg RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP;
+ reg [29:0] A, ACIN;
+ reg [17:0] B, BCIN;
+ reg [47:0] C;
+ reg [24:0] D;
+ reg [47:0] PCIN;
+ reg [3:0] ALUMODE;
+ reg [2:0] CARRYINSEL;
+ reg [4:0] INMODE;
+ reg [6:0] OPMODE;
+ reg CARRYCASCIN, CARRYIN, MULTSIGNIN;
+
+ output [29:0] ACOUT, REF_ACOUT;
+ output [17:0] BCOUT, REF_BCOUT;
+ output CARRYCASCOUT, REF_CARRYCASCOUT;
+ output [3:0] CARRYOUT, REF_CARRYOUT;
+ output MULTSIGNOUT, REF_MULTSIGNOUT;
+ output OVERFLOW, REF_OVERFLOW;
+ output [47:0] P, REF_P;
+ output PATTERNBDETECT, REF_PATTERNBDETECT;
+ output PATTERNDETECT, REF_PATTERNDETECT;
+ output [47:0] PCOUT, REF_PCOUT;
+ output UNDERFLOW, REF_UNDERFLOW;
+
+ integer errcount = 0;
+
+ reg ERROR_FLAG = 0;
+
+ task clkcycle;
+ begin
+ #5;
+ CLK = ~CLK;
+ #10;
+ CLK = ~CLK;
+ #2;
+ ERROR_FLAG = 0;
+ if (REF_P !== P) begin
+ $display("ERROR at %1t: REF_P=%b UUT_P=%b DIFF=%b", $time, REF_P, P, REF_P ^ P);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_CARRYOUT !== CARRYOUT) begin
+ $display("ERROR at %1t: REF_CARRYOUT=%b UUT_CARRYOUT=%b", $time, REF_CARRYOUT, CARRYOUT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_PATTERNDETECT !== PATTERNDETECT) begin
+ $display("ERROR at %1t: REF_PATTERNDETECT=%b UUT_PATTERNDETECT=%b DIFF=%b REF_P=%b P=%b", $time, REF_PATTERNDETECT, PATTERNDETECT, REF_PATTERNDETECT ^ PATTERNDETECT, REF_P, P);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_PATTERNBDETECT !== PATTERNBDETECT) begin
+ $display("ERROR at %1t: REF_PATTERNBDETECT=%b UUT_PATTERNBDETECT=%b DIFF=%b", $time, REF_PATTERNBDETECT, PATTERNBDETECT, REF_PATTERNBDETECT ^ PATTERNBDETECT);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_OVERFLOW !== OVERFLOW) begin
+ $display("ERROR at %1t: REF_OVERFLOW=%b UUT_OVERFLOW=%b DIFF=%b", $time, REF_OVERFLOW, OVERFLOW, REF_OVERFLOW ^ OVERFLOW);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ if (REF_UNDERFLOW !== UNDERFLOW) begin
+ $display("ERROR at %1t: REF_UNDERFLOW=%b UUT_UNDERFLOW=%b DIFF=%b", $time, REF_UNDERFLOW, UNDERFLOW, REF_UNDERFLOW ^ UNDERFLOW);
+ errcount = errcount + 1;
+ ERROR_FLAG = 1;
+ end
+ #3;
+ end
+ endtask
+
+ reg config_valid = 0;
+ task drc;
+ begin
+ config_valid = 1;
+ if (AREG != 2 && INMODE[0]) config_valid = 0;
+ if (BREG != 2 && INMODE[4]) config_valid = 0;
+
+ if (USE_SIMD != "ONE48" && OPMODE[3:0] == 4'b0101) config_valid = 0;
+
+ if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0;
+ if ((OPMODE[3:2] == 2'b01) ^ (OPMODE[1:0] == 2'b01) == 1'b1) config_valid = 0;
+ if ((OPMODE[6:4] == 3'b010 || OPMODE[6:4] == 3'b110) && PREG != 1) config_valid = 0;
+ if ((OPMODE[6:4] == 3'b100) && (PREG != 1 || OPMODE[3:0] != 4'b1000 || ALUMODE[3:2] == 2'b01 || ALUMODE[3:2] == 2'b11)) config_valid = 0;
+ if ((CARRYINSEL == 3'b100 || CARRYINSEL == 3'b101 || CARRYINSEL == 3'b111) && (PREG != 1)) config_valid = 0;
+ if (OPMODE[6:4] == 3'b111) config_valid = 0;
+ if ((OPMODE[3:0] == 4'b0101) && CARRYINSEL == 3'b010) config_valid = 0;
+ if (CARRYINSEL == 3'b000 && OPMODE == 7'b1001000) config_valid = 0;
+
+ if ((ALUMODE[3:2] == 2'b01 || ALUMODE[3:2] == 2'b11) && OPMODE[3:2] != 2'b00 && OPMODE[3:2] != 2'b10) config_valid = 0;
+
+
+ end
+ endtask
+
+ initial begin
+ $dumpfile("test_dsp_model.vcd");
+ $dumpvars(0, testbench);
+
+ #2;
+ CLK = 1'b0;
+ {CEA1, CEA2, CEAD, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL} = 9'b111111111;
+ {CED, CEINMODE, CEM, CEP} = 4'b1111;
+
+ {A, B, C, D} = 0;
+ {ACIN, BCIN, PCIN} = 0;
+ {ALUMODE, CARRYINSEL, INMODE} = 0;
+ {OPMODE, CARRYCASCIN, CARRYIN, MULTSIGNIN} = 0;
+
+ {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = ~0;
+ repeat (10) begin
+ #10;
+ CLK = 1'b1;
+ #10;
+ CLK = 1'b0;
+ #10;
+ CLK = 1'b1;
+ #10;
+ CLK = 1'b0;
+ end
+ {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0;
+
+ repeat (10000) begin
+ clkcycle;
+ config_valid = 0;
+ while (!config_valid) begin
+ A = $urandom;
+ ACIN = $urandom;
+ B = $urandom;
+ BCIN = $urandom;
+ C = {$urandom, $urandom};
+ D = $urandom;
+ PCIN = {$urandom, $urandom};
+
+ {CEA1, CEA2, CEAD, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL} = $urandom | $urandom | $urandom;
+ {CED, CEINMODE, CEM, CEP} = $urandom | $urandom | $urandom | $urandom;
+
+ // Otherwise we can accidentally create illegal configs
+ CEINMODE = CECTRL;
+ CEALUMODE = CECTRL;
+
+ {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom;
+ {ALUMODE, INMODE} = $urandom;
+ CARRYINSEL = $urandom & $urandom & $urandom;
+ OPMODE = $urandom;
+ if ($urandom & 1'b1)
+ OPMODE[3:0] = 4'b0101; // test multiply more than other modes
+ {CARRYCASCIN, CARRYIN, MULTSIGNIN} = $urandom;
+
+ // So few valid options in these modes, just force one valid option
+ if (CARRYINSEL == 3'b001) OPMODE = 7'b1010101;
+ if (CARRYINSEL == 3'b010) OPMODE = 7'b0001010;
+ if (CARRYINSEL == 3'b011) OPMODE = 7'b0011011;
+ if (CARRYINSEL == 3'b100) OPMODE = 7'b0110011;
+ if (CARRYINSEL == 3'b101) OPMODE = 7'b0011010;
+ if (CARRYINSEL == 3'b110) OPMODE = 7'b0010101;
+ if (CARRYINSEL == 3'b111) OPMODE = 7'b0100011;
+
+ drc;
+ end
+ end
+
+ if (errcount == 0) begin
+ $display("All tests passed.");
+ $finish;
+ end else begin
+ $display("Caught %1d errors.", errcount);
+ $stop;
+ end
+ end
+
+ DSP48E1 #(
+ .ACASCREG (ACASCREG),
+ .ADREG (ADREG),
+ .ALUMODEREG (ALUMODEREG),
+ .AREG (AREG),
+ .AUTORESET_PATDET (AUTORESET_PATDET),
+ .A_INPUT (A_INPUT),
+ .BCASCREG (BCASCREG),
+ .BREG (BREG),
+ .B_INPUT (B_INPUT),
+ .CARRYINREG (CARRYINREG),
+ .CARRYINSELREG (CARRYINSELREG),
+ .CREG (CREG),
+ .DREG (DREG),
+ .INMODEREG (INMODEREG),
+ .MREG (MREG),
+ .OPMODEREG (OPMODEREG),
+ .PREG (PREG),
+ .SEL_MASK (SEL_MASK),
+ .SEL_PATTERN (SEL_PATTERN),
+ .USE_DPORT (USE_DPORT),
+ .USE_MULT (USE_MULT),
+ .USE_PATTERN_DETECT (USE_PATTERN_DETECT),
+ .USE_SIMD (USE_SIMD),
+ .MASK (MASK),
+ .PATTERN (PATTERN),
+ .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
+ .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
+ .IS_CLK_INVERTED (IS_CLK_INVERTED),
+ .IS_INMODE_INVERTED (IS_INMODE_INVERTED),
+ .IS_OPMODE_INVERTED (IS_OPMODE_INVERTED)
+ ) ref (
+ .ACOUT (REF_ACOUT),
+ .BCOUT (REF_BCOUT),
+ .CARRYCASCOUT (REF_CARRYCASCOUT),
+ .CARRYOUT (REF_CARRYOUT),
+ .MULTSIGNOUT (REF_MULTSIGNOUT),
+ .OVERFLOW (REF_OVERFLOW),
+ .P (REF_P),
+ .PATTERNBDETECT(REF_PATTERNBDETECT),
+ .PATTERNDETECT (REF_PATTERNDETECT),
+ .PCOUT (REF_PCOUT),
+ .UNDERFLOW (REF_UNDERFLOW),
+ .A (A),
+ .ACIN (ACIN),
+ .ALUMODE (ALUMODE),
+ .B (B),
+ .BCIN (BCIN),
+ .C (C),
+ .CARRYCASCIN (CARRYCASCIN),
+ .CARRYINSEL (CARRYINSEL),
+ .CEA1 (CEA1),
+ .CEA2 (CEA2),
+ .CEAD (CEAD),
+ .CEALUMODE (CEALUMODE),
+ .CEB1 (CEB1),
+ .CEB2 (CEB2),
+ .CEC (CEC),
+ .CECARRYIN (CECARRYIN),
+ .CECTRL (CECTRL),
+ .CED (CED),
+ .CEINMODE (CEINMODE),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CLK (CLK),
+ .D (D),
+ .INMODE (INMODE),
+ .MULTSIGNIN (MULTSIGNIN),
+ .OPMODE (OPMODE),
+ .PCIN (PCIN),
+ .RSTA (RSTA),
+ .RSTALLCARRYIN (RSTALLCARRYIN),
+ .RSTALUMODE (RSTALUMODE),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTCTRL (RSTCTRL),
+ .RSTD (RSTD),
+ .RSTINMODE (RSTINMODE),
+ .RSTM (RSTM),
+ .RSTP (RSTP)
+ );
+
+ DSP48E1_UUT #(
+ .ACASCREG (ACASCREG),
+ .ADREG (ADREG),
+ .ALUMODEREG (ALUMODEREG),
+ .AREG (AREG),
+ .AUTORESET_PATDET (AUTORESET_PATDET),
+ .A_INPUT (A_INPUT),
+ .BCASCREG (BCASCREG),
+ .BREG (BREG),
+ .B_INPUT (B_INPUT),
+ .CARRYINREG (CARRYINREG),
+ .CARRYINSELREG (CARRYINSELREG),
+ .CREG (CREG),
+ .DREG (DREG),
+ .INMODEREG (INMODEREG),
+ .MREG (MREG),
+ .OPMODEREG (OPMODEREG),
+ .PREG (PREG),
+ .SEL_MASK (SEL_MASK),
+ .SEL_PATTERN (SEL_PATTERN),
+ .USE_DPORT (USE_DPORT),
+ .USE_MULT (USE_MULT),
+ .USE_PATTERN_DETECT (USE_PATTERN_DETECT),
+ .USE_SIMD (USE_SIMD),
+ .MASK (MASK),
+ .PATTERN (PATTERN),
+ .IS_ALUMODE_INVERTED(IS_ALUMODE_INVERTED),
+ .IS_CARRYIN_INVERTED(IS_CARRYIN_INVERTED),
+ .IS_CLK_INVERTED (IS_CLK_INVERTED),
+ .IS_INMODE_INVERTED (IS_INMODE_INVERTED),
+ .IS_OPMODE_INVERTED (IS_OPMODE_INVERTED)
+ ) uut (
+ .ACOUT (ACOUT),
+ .BCOUT (BCOUT),
+ .CARRYCASCOUT (CARRYCASCOUT),
+ .CARRYOUT (CARRYOUT),
+ .MULTSIGNOUT (MULTSIGNOUT),
+ .OVERFLOW (OVERFLOW),
+ .P (P),
+ .PATTERNBDETECT(PATTERNBDETECT),
+ .PATTERNDETECT (PATTERNDETECT),
+ .PCOUT (PCOUT),
+ .UNDERFLOW (UNDERFLOW),
+ .A (A),
+ .ACIN (ACIN),
+ .ALUMODE (ALUMODE),
+ .B (B),
+ .BCIN (BCIN),
+ .C (C),
+ .CARRYCASCIN (CARRYCASCIN),
+ .CARRYINSEL (CARRYINSEL),
+ .CEA1 (CEA1),
+ .CEA2 (CEA2),
+ .CEAD (CEAD),
+ .CEALUMODE (CEALUMODE),
+ .CEB1 (CEB1),
+ .CEB2 (CEB2),
+ .CEC (CEC),
+ .CECARRYIN (CECARRYIN),
+ .CECTRL (CECTRL),
+ .CED (CED),
+ .CEINMODE (CEINMODE),
+ .CEM (CEM),
+ .CEP (CEP),
+ .CLK (CLK),
+ .D (D),
+ .INMODE (INMODE),
+ .MULTSIGNIN (MULTSIGNIN),
+ .OPMODE (OPMODE),
+ .PCIN (PCIN),
+ .RSTA (RSTA),
+ .RSTALLCARRYIN (RSTALLCARRYIN),
+ .RSTALUMODE (RSTALUMODE),
+ .RSTB (RSTB),
+ .RSTC (RSTC),
+ .RSTCTRL (RSTCTRL),
+ .RSTD (RSTD),
+ .RSTINMODE (RSTINMODE),
+ .RSTM (RSTM),
+ .RSTP (RSTP)
+ );
+endmodule
+
+module mult_noreg_nopreadd_nocasc;
+ testbench #(
+ .ACASCREG (0),
+ .ADREG (0),
+ .ALUMODEREG (0),
+ .AREG (0),
+ .AUTORESET_PATDET ("NO_RESET"),
+ .A_INPUT ("DIRECT"),
+ .BCASCREG (0),
+ .BREG (0),
+ .B_INPUT ("DIRECT"),
+ .CARRYINREG (0),
+ .CARRYINSELREG (0),
+ .CREG (0),
+ .DREG (0),
+ .INMODEREG (0),
+ .MREG (0),
+ .OPMODEREG (0),
+ .PREG (0),
+ .SEL_MASK ("MASK"),
+ .SEL_PATTERN ("PATTERN"),
+ .USE_DPORT ("FALSE"),
+ .USE_MULT ("DYNAMIC"),
+ .USE_PATTERN_DETECT ("NO_PATDET"),
+ .USE_SIMD ("ONE48"),
+ .MASK (48'h3FFFFFFFFFFF),
+ .PATTERN (48'h000000000000),
+ .IS_ALUMODE_INVERTED(4'b0),
+ .IS_CARRYIN_INVERTED(1'b0),
+ .IS_CLK_INVERTED (1'b0),
+ .IS_INMODE_INVERTED (5'b0),
+ .IS_OPMODE_INVERTED (7'b0)
+ ) testbench ();
+endmodule
+
+module mult_allreg_nopreadd_nocasc;
+ testbench #(
+ .ACASCREG (1),
+ .ADREG (1),
+ .ALUMODEREG (1),
+ .AREG (2),
+ .AUTORESET_PATDET ("NO_RESET"),
+ .A_INPUT ("DIRECT"),
+ .BCASCREG (1),
+ .BREG (2),
+ .B_INPUT ("DIRECT"),
+ .CARRYINREG (1),
+ .CARRYINSELREG (1),
+ .CREG (1),
+ .DREG (1),
+ .INMODEREG (1),
+ .MREG (1),
+ .OPMODEREG (1),
+ .PREG (1),
+ .SEL_MASK ("MASK"),
+ .SEL_PATTERN ("PATTERN"),
+ .USE_DPORT ("FALSE"),
+ .USE_MULT ("DYNAMIC"),
+ .USE_PATTERN_DETECT ("NO_PATDET"),
+ .USE_SIMD ("ONE48"),
+ .MASK (48'h3FFFFFFFFFFF),
+ .PATTERN (48'h000000000000),
+ .IS_ALUMODE_INVERTED(4'b0),
+ .IS_CARRYIN_INVERTED(1'b0),
+ .IS_CLK_INVERTED (1'b0),
+ .IS_INMODE_INVERTED (5'b0),
+ .IS_OPMODE_INVERTED (7'b0)
+ ) testbench ();
+endmodule
+
+module mult_noreg_preadd_nocasc;
+ testbench #(
+ .ACASCREG (0),
+ .ADREG (0),
+ .ALUMODEREG (0),
+ .AREG (0),
+ .AUTORESET_PATDET ("NO_RESET"),
+ .A_INPUT ("DIRECT"),
+ .BCASCREG (0),
+ .BREG (0),
+ .B_INPUT ("DIRECT"),
+ .CARRYINREG (0),
+ .CARRYINSELREG (0),
+ .CREG (0),
+ .DREG (0),
+ .INMODEREG (0),
+ .MREG (0),
+ .OPMODEREG (0),
+ .PREG (0),
+ .SEL_MASK ("MASK"),
+ .SEL_PATTERN ("PATTERN"),
+ .USE_DPORT ("TRUE"),
+ .USE_MULT ("DYNAMIC"),
+ .USE_PATTERN_DETECT ("NO_PATDET"),
+ .USE_SIMD ("ONE48"),
+ .MASK (48'h3FFFFFFFFFFF),
+ .PATTERN (48'h000000000000),
+ .IS_ALUMODE_INVERTED(4'b0),
+ .IS_CARRYIN_INVERTED(1'b0),
+ .IS_CLK_INVERTED (1'b0),
+ .IS_INMODE_INVERTED (5'b0),
+ .IS_OPMODE_INVERTED (7'b0)
+ ) testbench ();
+endmodule
+
+module mult_allreg_preadd_nocasc;
+ testbench #(
+ .ACASCREG (1),
+ .ADREG (1),
+ .ALUMODEREG (1),
+ .AREG (2),
+ .AUTORESET_PATDET ("NO_RESET"),
+ .A_INPUT ("DIRECT"),
+ .BCASCREG (1),
+ .BREG (2),
+ .B_INPUT ("DIRECT"),
+ .CARRYINREG (1),
+ .CARRYINSELREG (1),
+ .CREG (1),
+ .DREG (1),
+ .INMODEREG (1),
+ .MREG (1),
+ .OPMODEREG (1),
+ .PREG (1),
+ .SEL_MASK ("MASK"),
+ .SEL_PATTERN ("PATTERN"),
+ .USE_DPORT ("TRUE"),
+ .USE_MULT ("DYNAMIC"),
+ .USE_PATTERN_DETECT ("NO_PATDET"),
+ .USE_SIMD ("ONE48"),
+ .MASK (48'h3FFFFFFFFFFF),
+ .PATTERN (48'h000000000000),
+ .IS_ALUMODE_INVERTED(4'b0),
+ .IS_CARRYIN_INVERTED(1'b0),
+ .IS_CLK_INVERTED (1'b0),
+ .IS_INMODE_INVERTED (5'b0),
+ .IS_OPMODE_INVERTED (7'b0)
+ ) testbench ();
+endmodule
+
+module mult_inreg_preadd_nocasc;
+ testbench #(
+ .ACASCREG (1),
+ .ADREG (0),
+ .ALUMODEREG (0),
+ .AREG (1),
+ .AUTORESET_PATDET ("NO_RESET"),
+ .A_INPUT ("DIRECT"),
+ .BCASCREG (1),
+ .BREG (1),
+ .B_INPUT ("DIRECT"),
+ .CARRYINREG (0),
+ .CARRYINSELREG (0),
+ .CREG (1),
+ .DREG (1),
+ .INMODEREG (0),
+ .MREG (0),
+ .OPMODEREG (0),
+ .PREG (0),
+ .SEL_MASK ("MASK"),
+ .SEL_PATTERN ("PATTERN"),
+ .USE_DPORT ("TRUE"),
+ .USE_MULT ("DYNAMIC"),
+ .USE_PATTERN_DETECT ("NO_PATDET"),
+ .USE_SIMD ("ONE48"),
+ .MASK (48'h3FFFFFFFFFFF),
+ .PATTERN (48'h000000000000),
+ .IS_ALUMODE_INVERTED(4'b0),
+ .IS_CARRYIN_INVERTED(1'b0),
+ .IS_CLK_INVERTED (1'b0),
+ .IS_INMODE_INVERTED (5'b0),
+ .IS_OPMODE_INVERTED (7'b0)
+ ) testbench ();
+endmodule
+
+module simd12_preadd_noreg_nocasc;
+ testbench #(
+ .ACASCREG (0),
+ .ADREG (0),
+ .ALUMODEREG (0),
+ .AREG (0),
+ .AUTORESET_PATDET ("NO_RESET"),
+ .A_INPUT ("DIRECT"),
+ .BCASCREG (0),
+ .BREG (0),
+ .B_INPUT ("DIRECT"),
+ .CARRYINREG (0),
+ .CARRYINSELREG (0),
+ .CREG (0),
+ .DREG (0),
+ .INMODEREG (0),
+ .MREG (0),
+ .OPMODEREG (0),
+ .PREG (0),
+ .SEL_MASK ("MASK"),
+ .SEL_PATTERN ("PATTERN"),
+ .USE_DPORT ("TRUE"),
+ .USE_MULT ("DYNAMIC"),
+ .USE_PATTERN_DETECT ("NO_PATDET"),
+ .USE_SIMD ("FOUR12"),
+ .MASK (48'h3FFFFFFFFFFF),
+ .PATTERN (48'h000000000000),
+ .IS_ALUMODE_INVERTED(4'b0),
+ .IS_CARRYIN_INVERTED(1'b0),
+ .IS_CLK_INVERTED (1'b0),
+ .IS_INMODE_INVERTED (5'b0),
+ .IS_OPMODE_INVERTED (7'b0)
+ ) testbench ();
+endmodule
+
+
+module simd24_preadd_noreg_nocasc;
+ testbench #(
+ .ACASCREG (0),
+ .ADREG (0),
+ .ALUMODEREG (0),
+ .AREG (0),
+ .AUTORESET_PATDET ("NO_RESET"),
+ .A_INPUT ("DIRECT"),
+ .BCASCREG (0),
+ .BREG (0),
+ .B_INPUT ("DIRECT"),
+ .CARRYINREG (0),
+ .CARRYINSELREG (0),
+ .CREG (0),
+ .DREG (0),
+ .INMODEREG (0),
+ .MREG (0),
+ .OPMODEREG (0),
+ .PREG (0),
+ .SEL_MASK ("MASK"),
+ .SEL_PATTERN ("PATTERN"),
+ .USE_DPORT ("TRUE"),
+ .USE_MULT ("DYNAMIC"),
+ .USE_PATTERN_DETECT ("NO_PATDET"),
+ .USE_SIMD ("TWO24"),
+ .MASK (48'h3FFFFFFFFFFF),
+ .PATTERN (48'h000000000000),
+ .IS_ALUMODE_INVERTED(4'b0),
+ .IS_CARRYIN_INVERTED(1'b0),
+ .IS_CLK_INVERTED (1'b0),
+ .IS_INMODE_INVERTED (5'b0),
+ .IS_OPMODE_INVERTED (7'b0)
+ ) testbench ();
+endmodule
+
+module macc_overflow_underflow;
+ testbench #(
+ .ACASCREG (0),
+ .ADREG (0),
+ .ALUMODEREG (0),
+ .AREG (0),
+ .AUTORESET_PATDET ("NO_RESET"),
+ .A_INPUT ("DIRECT"),
+ .BCASCREG (0),
+ .BREG (0),
+ .B_INPUT ("DIRECT"),
+ .CARRYINREG (0),
+ .CARRYINSELREG (0),
+ .CREG (0),
+ .DREG (0),
+ .INMODEREG (0),
+ .MREG (0),
+ .OPMODEREG (0),
+ .PREG (1),
+ .SEL_MASK ("MASK"),
+ .SEL_PATTERN ("PATTERN"),
+ .USE_DPORT ("FALSE"),
+ .USE_MULT ("DYNAMIC"),
+ .USE_PATTERN_DETECT ("PATDET"),
+ .USE_SIMD ("ONE48"),
+ .MASK (48'h1FFFFFFFFFFF),
+ .PATTERN (48'h000000000000),
+ .IS_ALUMODE_INVERTED(4'b0),
+ .IS_CARRYIN_INVERTED(1'b0),
+ .IS_CLK_INVERTED (1'b0),
+ .IS_INMODE_INVERTED (5'b0),
+ .IS_OPMODE_INVERTED (7'b0)
+ ) testbench ();
+endmodule