mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-03 21:09:12 +00:00 
			
		
		
		
	DSP48E1 sim model: seq test working
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
		
							parent
							
								
									f6605c7dc0
								
							
						
					
					
						commit
						e7dbe7bb3d
					
				
					 3 changed files with 60 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue