DSP48E1 sim model: fix seq tests and add preadder tests
authorDavid Shah <dave@ds0.me>
Thu, 8 Aug 2019 10:18:37 +0000 (11:18 +0100)
committerDavid Shah <dave@ds0.me>
Thu, 8 Aug 2019 10:18:37 +0000 (11:18 +0100)
Signed-off-by: David Shah <dave@ds0.me>
techlibs/xilinx/tests/test_dsp_model.sh
techlibs/xilinx/tests/test_dsp_model.v

index 3c7cfac30e79ca352acdaee1739a1e380702fb13..337530e87253b201e41489eb557fae8e5d8d1e1e 100644 (file)
@@ -4,7 +4,8 @@ sed 's/DSP48E1/DSP48E1_UUT/; /DSP48E1_UUT/,/endmodule/ p; d;' < ../cells_sim.v >
 if [ ! -f "test_dsp_model_ref.v" ]; then
        cat /opt/Xilinx/Vivado/2019.1/data/verilog/src/unisims/DSP48E1.v > test_dsp_model_ref.v
 fi
-for tb in mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc
+for tb in mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc  \
+       mult_allreg_preadd_nocasc mult_noreg_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 /opt/Xilinx/Vivado/2019.1/data/verilog/src/glbl.v
        vvp -N ./test_dsp_model
index b5574911bee0267123a357c9c11a41653790d6cd..6f1ca045a4def1bf609ac3dbd35e7b4cc4fe619e 100644 (file)
@@ -91,16 +91,19 @@ module testbench;
                        config_valid = 1;
                        if (AREG != 2 && INMODE[0]) config_valid = 0;
                        if (BREG != 2 && INMODE[4]) 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 ((ALUMODE[3:2] == 2'b01 || ALUMODE[3:2] == 2'b11) && OPMODE[3:2] != 2'b00 && OPMODE[3:2] != 2'b10) config_valid = 0;
                        if ((OPMODE[3:0] == 4'b0101) && CARRYINSEL == 3'b010) config_valid = 0;
-                       if (CARRYINSEL == 3'b010 && OPMODE != 7'b0001010) config_valid = 0;
-                       if (CARRYINSEL == 3'b001 && OPMODE != 7'b1010101) 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
 
@@ -131,7 +134,7 @@ module testbench;
                end
                {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0;
 
-               repeat (300) begin
+               repeat (5000) begin
                        clkcycle;
                        config_valid = 0;
                        while (!config_valid) begin
@@ -144,11 +147,22 @@ module testbench;
                                PCIN = {$urandom, $urandom};
 
                                {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom;
-                               {ALUMODE, CARRYINSEL, INMODE} = $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
@@ -395,4 +409,74 @@ module mult_allreg_nopreadd_nocasc;
                .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
\ No newline at end of file