diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index 53061808b..b738d9712 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -593,14 +593,17 @@ module DSP48E1 ( endgenerate wire signed [42:0] M = A_MULT * B_MULT; + wire signed [42:0] Mx = (CARRYINSEL == 3'b010) ? 43'bx : M; reg signed [42:0] Mr = 43'b0; // Multiplier result register generate - if (MREG == 1) begin always @(posedge CLK) if (RSTM) Mr <= 43'b0; else if (CEM) Mr <= M; end - else always @* Mr <= M; + if (MREG == 1) begin always @(posedge CLK) if (RSTM) Mr <= 43'b0; else if (CEM) Mr <= Mx; end + else always @* Mr <= Mx; endgenerate + wire signed [42:0] Mrx = (CARRYINSELr == 3'b010) ? 43'bx : Mr; + // X, Y and Z ALU inputs reg signed [47:0] X, Y, Z; @@ -608,7 +611,7 @@ module DSP48E1 ( // X multiplexer case (OPMODEr[1:0]) 2'b00: X = 48'b0; - 2'b01: begin X = $signed(Mr); + 2'b01: begin X = $signed(Mrx); `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 @@ -664,7 +667,7 @@ module DSP48E1 ( if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end else always @* CARRYINr = CARRYIN; - if (MREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) A24_xnor_B17 <= 1'b0; else if (CECARRYIN) A24_xnor_B17 <= A24_xnor_B17d; end + if (MREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) A24_xnor_B17 <= 1'b0; else if (CEM) A24_xnor_B17 <= A24_xnor_B17d; end else always @* A24_xnor_B17 = A24_xnor_B17d; endgenerate @@ -755,7 +758,7 @@ module DSP48E1 ( 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]; + wire MULTSIGNOUTd = Mrx[42]; generate if (PREG == 1) begin diff --git a/techlibs/xilinx/tests/test_dsp_model.v b/techlibs/xilinx/tests/test_dsp_model.v index 6f1ca045a..7086634d2 100644 --- a/techlibs/xilinx/tests/test_dsp_model.v +++ b/techlibs/xilinx/tests/test_dsp_model.v @@ -134,7 +134,7 @@ module testbench; end {RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0; - repeat (5000) begin + repeat (10000) begin clkcycle; config_valid = 0; while (!config_valid) begin @@ -146,6 +146,13 @@ module testbench; 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; @@ -162,7 +169,7 @@ module testbench; if (CARRYINSEL == 3'b101) OPMODE = 7'b0011010; if (CARRYINSEL == 3'b110) OPMODE = 7'b0010101; if (CARRYINSEL == 3'b111) OPMODE = 7'b0100011; - + drc; end end