DSP48E1 sim model: Comb, no pre-adder, mode working
authorDavid Shah <dave@ds0.me>
Thu, 8 Aug 2019 09:26:40 +0000 (10:26 +0100)
committerDavid Shah <dave@ds0.me>
Thu, 8 Aug 2019 09:26:44 +0000 (10:26 +0100)
Signed-off-by: David Shah <dave@ds0.me>
techlibs/xilinx/cells_sim.v
techlibs/xilinx/tests/test_dsp_model.v

index 4e26ea5c97acffb918dd70a1259f991c009f9c55..3817c6a1d5880ed0f7204f86055ef1693801e1f7 100644 (file)
@@ -689,7 +689,7 @@ module DSP48E1 (
     // ALU core
     wire [47:0] Z_muxinv = ALUMODEr[0] ? ~Z : Z;
     wire [47:0] xor_xyz = X ^ Y ^ Z_muxinv;
-    wire [47:0] maj_xyz = (X & Y) | (X & Z) | (X & Y);
+    wire [47:0] maj_xyz = (X & Y) | (X & Z_muxinv) | (Y & Z_muxinv);
 
     wire [47:0] xor_xyz_muxed = ALUMODEr[3] ? maj_xyz : xor_xyz;
     wire [47:0] maj_xyz_gated = ALUMODEr[2] ? 48'b0 :  maj_xyz;
@@ -745,7 +745,8 @@ module DSP48E1 (
 
     wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum;
     initial P = 48'b0;
-    wire [3:0] CARRYOUTd = (ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out;
+    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];
     wire MULTSIGNOUTd = Mr[42];
 
index f8039aa155a6c1cf18d2d805d6fd8ba36876986c..86ff7ab40388bad27cb116a4e8d4828d1097b78b 100644 (file)
@@ -35,7 +35,7 @@ module testbench;
        reg CLK;
        reg CEA1, CEA2, CEAD, CEALUMODE, CEB1, CEB2, CEC, CECARRYIN, CECTRL;
        reg CED, CEINMODE, CEM, CEP;
-       reg RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTD, RSTINMODE, RSTM, RSTP;
+       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;
@@ -61,6 +61,8 @@ module testbench;
 
        integer errcount = 0;
 
+       reg ERROR_FLAG = 0;
+
        task clkcycle;
                begin
                        #5;
@@ -68,14 +70,16 @@ module testbench;
                        #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
                        #3;
                end
@@ -114,7 +118,7 @@ module testbench;
                {ALUMODE, CARRYINSEL, INMODE} = 0;
                {OPMODE, CARRYCASCIN, CARRYIN, MULTSIGNIN} = 0;
 
-               {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTD, RSTINMODE, RSTM, RSTP} = ~0;
+               {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = ~0;
                #5;
                CLK = 1'b1;
                #10;
@@ -123,7 +127,7 @@ module testbench;
                CLK = 1'b1;
                #10;
                CLK = 1'b0;
-               {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTD, RSTINMODE, RSTM, RSTP} = 0;
+               {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0;
 
                repeat (300) begin
                        clkcycle;
@@ -137,8 +141,8 @@ module testbench;
                                D = $urandom;
                                PCIN = {$urandom, $urandom};
 
-                               {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTD, RSTINMODE, RSTM, RSTP} = $urandom & $urandom & $urandom;
-                               {ALUMODE, CARRYINSEL, INMODE} = $urandom & $urandom & $urandom;
+                               {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = $urandom & $urandom & $urandom & $urandom & $urandom & $urandom;
+                               {ALUMODE, CARRYINSEL, INMODE} = $urandom;
                                OPMODE = $urandom; 
                                if ($urandom & 1'b1)
                                        OPMODE[3:0] = 4'b0101; // test multiply more than other modes