diff options
| author | David Shah <dave@ds0.me> | 2019-08-07 13:09:12 +0100 | 
|---|---|---|
| committer | David Shah <dave@ds0.me> | 2019-08-07 13:09:12 +0100 | 
| commit | fe95807f162704d1f9c09ba8d665092c92574cce (patch) | |
| tree | 4919b147958835b0716c0f4d1f256bb1f44907ea /techlibs/xilinx | |
| parent | c43b0c4b49235da5aee658413a2a6f880aff09b0 (diff) | |
| download | yosys-fe95807f162704d1f9c09ba8d665092c92574cce.tar.gz yosys-fe95807f162704d1f9c09ba8d665092c92574cce.tar.bz2 yosys-fe95807f162704d1f9c09ba8d665092c92574cce.zip | |
[wip] DSP48E1 sim model improvements
Signed-off-by: David Shah <dave@ds0.me>
Diffstat (limited to 'techlibs/xilinx')
| -rw-r--r-- | techlibs/xilinx/cells_sim.v | 88 | 
1 files changed, 82 insertions, 6 deletions
| diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v index bc8a2d8f0..7e7199f0b 100644 --- a/techlibs/xilinx/cells_sim.v +++ b/techlibs/xilinx/cells_sim.v @@ -382,9 +382,9 @@ endmodule  module DSP48E1 (      output [29:0] ACOUT,      output [17:0] BCOUT, -    output CARRYCASCOUT, -    output [3:0] CARRYOUT, -    output MULTSIGNOUT, +    output reg CARRYCASCOUT, +    output reg [3:0] CARRYOUT, +    output reg MULTSIGNOUT,      output OVERFLOW,      output reg signed [47:0] P,      output PATTERNBDETECT, @@ -669,13 +669,70 @@ module DSP48E1 (          endcase      end +    // ALU core +      wire alu_cin = 1'b0; // FIXME*      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] xor_xyz_muxed = ALUMODEr[3] ? maj_xyz : xor_xyz; +    wire [47:0] maj_xyz_gated = ALUMODEr[2] ? 48'b0 :  maj_xyz; + +    wire [48:0] maj_xyz_simd_gated; +    wire [3:0] int_carry_in, int_carry_out, ext_carry_out; +    wire [47:0] alu_sum; +    assign int_carry_in[0] = 1'b0; + +    generate +        if (USE_SIMD == "FOUR12") begin +            assign maj_xyz_simd_gated = { +                    maj_xyz_gated[47:36], +                    1'b0, maj_xyz_gated[34:24], +                    1'b0, maj_xyz_gated[22:12], +                    1'b0, maj_xyz_gated[10:0], +                    alu_cin +                }; +            assign int_carry_in[3:1] = 3'b000; +            assign ext_carry_out = { +                    int_carry_out[3], +                    maj_xyz_gated[35] ^ int_carry_out[2], +                    maj_xyz_gated[23] ^ int_carry_out[1], +                    maj_xyz_gated[11] ^ int_carry_out[0] +                }; +        end else if (USE_SIMD == "TWO24") begin +            assign maj_xyz_simd_gated = { +                    maj_xyz_gated[47:24], +                    1'b0, maj_xyz_gated[22:0], +                    alu_cin +                }; +            assign int_carry_in[3:1] = {int_carry_out[2], 1'b0, int_carry_out[0]}; +            assign ext_carry_out = { +                    int_carry_out[3], +                    1'bx, +                    maj_xyz_gated[23] ^ int_carry_out[1], +                    1'bx +                }; +        end else if (USE_SIMD == "FOUR48") begin +            assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin}; +            assign int_carry_in[3:1] = int_carry_out[2:0]; +            assign ext_carry_out = { +                    int_carry_out[3], +                    3'bxxx +                }; +        end + +        genvar i; +        for (i = 0; i < 4; i++) +            assign {int_carry_out[i], alu_sum[i*12 +: 12]} = {1'b0, maj_xyz_simd_gated[i*12 +: ((i == 3) ? 13 : 12)]} +                                                              + xor_xyz_muxed[i*12 +: 12] + int_carry_in[i]; +    endgenerate + +    wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum; +    wire [3:0] CARRYOUTd = (ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out; +    wire CARRYCASCOUTd = ext_carry_out[3]; +    wire MULTSIGNOUTd = Mr[42];      always @* begin  `ifdef __ICARUS__ @@ -684,8 +741,27 @@ module DSP48E1 (      end      generate -        if (PREG == 1) begin always @(posedge CLK) if (RSTP) P <= 48'b0; else if (CEP) P <= Mr; end -        else           always @* P <= Mr; +        if (PREG == 1) begin +            always @(posedge CLK) +                if (RSTP) begin +                    P <= 48'b0; +                    CARRYOUT <= 4'b0; +                    CARRYCASCOUT <= 1'b0; +                    MULTSIGNOUT <= 1'b0; +                end else if (CEP) begin +                    P <= Pd; +                    CARRYOUT <= CARRYOUTd; +                    CARRYCASCOUT <= CARRYCASCOUTd; +                    MULTSIGNOUT <= MULTSIGNOUTd; +                end +        end else begin +            always @* begin +                P = Pd; +                CARRYOUT = CARRYOUTd; +                CARRYCASCOUT = CARRYCASCOUTd; +                MULTSIGNOUT = MULTSIGNOUTd; +            end +        end      endgenerate  endmodule | 
