DSP48E1 sim model: seq test working
authorDavid Shah <dave@ds0.me>
Thu, 8 Aug 2019 09:52:04 +0000 (10:52 +0100)
committerDavid Shah <dave@ds0.me>
Thu, 8 Aug 2019 09:52:04 +0000 (10:52 +0100)
Signed-off-by: David Shah <dave@ds0.me>
techlibs/xilinx/cells_sim.v
techlibs/xilinx/tests/test_dsp_model.sh
techlibs/xilinx/tests/test_dsp_model.v

index 3817c6a1d5880ed0f7204f86055ef1693801e1f7..53061808b011347cb915d0a2e72c6ba6e193c049 100644 (file)
@@ -547,7 +547,7 @@ module DSP48E1 (
         end
 
         // C and D registers
-        if (CREG == 1) begin always @(posedge CLK) if (RSTC) Cr <= 48'b0; else if (CEC) Cr <= D; end
+        if (CREG == 1) begin always @(posedge CLK) if (RSTC) Cr <= 48'b0; else if (CEC) Cr <= C; end
         else           always @* Cr <= C;
 
         if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end
@@ -608,7 +608,7 @@ module DSP48E1 (
         // X multiplexer
         case (OPMODEr[1:0])
             2'b00: X = 48'b0;
-            2'b01: begin X = $signed(M);
+            2'b01: begin X = $signed(Mr);
 `ifdef __ICARUS__
                 if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01");
 `endif
@@ -631,7 +631,7 @@ module DSP48E1 (
 `endif
             end
             2'b10: Y = {48{1'b1}};
-            2'b11: Y = C;
+            2'b11: Y = Cr;
             default: Y = 48'bx;
         endcase
 
@@ -644,7 +644,7 @@ module DSP48E1 (
                 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010");
 `endif
             end
-            3'b011: Z = C;
+            3'b011: Z = Cr;
             3'b100: begin Z = P;
 `ifdef __ICARUS__
                 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100");
@@ -659,7 +659,7 @@ module DSP48E1 (
 
     // Carry in
     wire A24_xnor_B17d = A_MULT[24] ~^ B_MULT[17];
-    reg CARRYINr, A24_xnor_B17;
+    reg CARRYINr = 1'b0, A24_xnor_B17 = 1'b0;
     generate
         if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end
         else                 always @* CARRYINr = CARRYIN;
@@ -698,6 +698,7 @@ module DSP48E1 (
     wire [3:0] int_carry_in, int_carry_out, ext_carry_out;
     wire [47:0] alu_sum;
     assign int_carry_in[0] = 1'b0;
+    wire [3:0] carryout_reset;
 
     generate
         if (USE_SIMD == "FOUR12") begin
@@ -715,6 +716,7 @@ module DSP48E1 (
                     maj_xyz_gated[23] ^ int_carry_out[1],
                     maj_xyz_gated[11] ^ int_carry_out[0]
                 };
+            assign carryout_reset = 4'b0000;
         end else if (USE_SIMD == "TWO24") begin
             assign maj_xyz_simd_gated = {
                     maj_xyz_gated[47:24],
@@ -728,6 +730,7 @@ module DSP48E1 (
                     maj_xyz_gated[23] ^ int_carry_out[1],
                     1'bx
                 };
+            assign carryout_reset = 4'b0x0x;
         end else begin
             assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin};
             assign int_carry_in[3:1] = int_carry_out[2:0];
@@ -735,6 +738,7 @@ module DSP48E1 (
                     int_carry_out[3],
                     3'bxxx
                 };
+            assign carryout_reset = 4'b0xxx;
         end
 
         genvar i;
@@ -745,6 +749,9 @@ module DSP48E1 (
 
     wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum;
     initial P = 48'b0;
+    initial CARRYOUT = carryout_reset;
+    initial CARRYCASCOUT = 1'b0;
+    initial MULTSIGNOUT = 1'b0;
     wire [3:0] CARRYOUTd = (OPMODEr[3:0] == 4'b0101 || ALUMODEr[3:2] != 2'b00) ? 4'bxxxx :
                            ((ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out);
     wire CARRYCASCOUTd = ext_carry_out[3];
@@ -755,7 +762,7 @@ module DSP48E1 (
             always @(posedge CLK)
                 if (RSTP) begin
                     P <= 48'b0;
-                    CARRYOUT <= 4'b0;
+                    CARRYOUT <= carryout_reset;
                     CARRYCASCOUT <= 1'b0;
                     MULTSIGNOUT <= 1'b0;
                 end else if (CEP) begin
index 5455294da9605e9f4829207433a6b05fc1f33e7f..3c7cfac30e79ca352acdaee1739a1e380702fb13 100644 (file)
@@ -4,7 +4,7 @@ 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_noreg_nopreadd_nocasc
+for tb in mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_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 86ff7ab40388bad27cb116a4e8d4828d1097b78b..b5574911bee0267123a357c9c11a41653790d6cd 100644 (file)
@@ -94,7 +94,7 @@ module testbench;
                        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)) 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;
@@ -119,14 +119,16 @@ module testbench;
                {OPMODE, CARRYCASCIN, CARRYIN, MULTSIGNIN} = 0;
 
                {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = ~0;
-               #5;
-               CLK = 1'b1;
-               #10;
-               CLK = 1'b0;
-               #5;
-               CLK = 1'b1;
-               #10;
-               CLK = 1'b0;
+               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 (300) begin
@@ -358,4 +360,39 @@ module mult_noreg_nopreadd_nocasc;
                .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
\ No newline at end of file