mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +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 |         end | ||||||
| 
 | 
 | ||||||
|         // C and D registers |         // 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; |         else           always @* Cr <= C; | ||||||
| 
 | 
 | ||||||
|         if (DREG == 1) begin always @(posedge CLK) if (RSTD) Dr <= 25'b0; else if (CED) Dr <= D; end |         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 |         // X multiplexer | ||||||
|         case (OPMODEr[1:0]) |         case (OPMODEr[1:0]) | ||||||
|             2'b00: X = 48'b0; |             2'b00: X = 48'b0; | ||||||
|             2'b01: begin X = $signed(M); |             2'b01: begin X = $signed(Mr); | ||||||
| `ifdef __ICARUS__ | `ifdef __ICARUS__ | ||||||
|                 if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01"); |                 if (OPMODEr[3:2] != 2'b01) $fatal(1, "OPMODEr[3:2] must be 2'b01 when OPMODEr[1:0] is 2'b01"); | ||||||
| `endif | `endif | ||||||
|  | @ -631,7 +631,7 @@ module DSP48E1 ( | ||||||
| `endif | `endif | ||||||
|             end |             end | ||||||
|             2'b10: Y = {48{1'b1}}; |             2'b10: Y = {48{1'b1}}; | ||||||
|             2'b11: Y = C; |             2'b11: Y = Cr; | ||||||
|             default: Y = 48'bx; |             default: Y = 48'bx; | ||||||
|         endcase |         endcase | ||||||
| 
 | 
 | ||||||
|  | @ -644,7 +644,7 @@ module DSP48E1 ( | ||||||
|                 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010"); |                 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] i0s 3'b010"); | ||||||
| `endif | `endif | ||||||
|             end |             end | ||||||
|             3'b011: Z = C; |             3'b011: Z = Cr; | ||||||
|             3'b100: begin Z = P; |             3'b100: begin Z = P; | ||||||
| `ifdef __ICARUS__ | `ifdef __ICARUS__ | ||||||
|                 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100"); |                 if (PREG != 1) $fatal(1, "PREG must be 1 when OPMODEr[6:4] is 3'b100"); | ||||||
|  | @ -659,7 +659,7 @@ module DSP48E1 ( | ||||||
| 
 | 
 | ||||||
|     // Carry in |     // Carry in | ||||||
|     wire A24_xnor_B17d = A_MULT[24] ~^ B_MULT[17]; |     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 |     generate | ||||||
|         if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end |         if (CARRYINREG == 1) begin always @(posedge CLK) if (RSTALLCARRYIN) CARRYINr <= 1'b0; else if (CECARRYIN) CARRYINr <= CARRYIN; end | ||||||
|         else                 always @* CARRYINr = CARRYIN; |         else                 always @* CARRYINr = CARRYIN; | ||||||
|  | @ -698,6 +698,7 @@ module DSP48E1 ( | ||||||
|     wire [3:0] int_carry_in, int_carry_out, ext_carry_out; |     wire [3:0] int_carry_in, int_carry_out, ext_carry_out; | ||||||
|     wire [47:0] alu_sum; |     wire [47:0] alu_sum; | ||||||
|     assign int_carry_in[0] = 1'b0; |     assign int_carry_in[0] = 1'b0; | ||||||
|  |     wire [3:0] carryout_reset; | ||||||
| 
 | 
 | ||||||
|     generate |     generate | ||||||
|         if (USE_SIMD == "FOUR12") begin |         if (USE_SIMD == "FOUR12") begin | ||||||
|  | @ -715,6 +716,7 @@ module DSP48E1 ( | ||||||
|                     maj_xyz_gated[23] ^ int_carry_out[1], |                     maj_xyz_gated[23] ^ int_carry_out[1], | ||||||
|                     maj_xyz_gated[11] ^ int_carry_out[0] |                     maj_xyz_gated[11] ^ int_carry_out[0] | ||||||
|                 }; |                 }; | ||||||
|  |             assign carryout_reset = 4'b0000; | ||||||
|         end else if (USE_SIMD == "TWO24") begin |         end else if (USE_SIMD == "TWO24") begin | ||||||
|             assign maj_xyz_simd_gated = { |             assign maj_xyz_simd_gated = { | ||||||
|                     maj_xyz_gated[47:24], |                     maj_xyz_gated[47:24], | ||||||
|  | @ -728,6 +730,7 @@ module DSP48E1 ( | ||||||
|                     maj_xyz_gated[23] ^ int_carry_out[1], |                     maj_xyz_gated[23] ^ int_carry_out[1], | ||||||
|                     1'bx |                     1'bx | ||||||
|                 }; |                 }; | ||||||
|  |             assign carryout_reset = 4'b0x0x; | ||||||
|         end else begin |         end else begin | ||||||
|             assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin}; |             assign maj_xyz_simd_gated = {maj_xyz_gated, alu_cin}; | ||||||
|             assign int_carry_in[3:1] = int_carry_out[2:0]; |             assign int_carry_in[3:1] = int_carry_out[2:0]; | ||||||
|  | @ -735,6 +738,7 @@ module DSP48E1 ( | ||||||
|                     int_carry_out[3], |                     int_carry_out[3], | ||||||
|                     3'bxxx |                     3'bxxx | ||||||
|                 }; |                 }; | ||||||
|  |             assign carryout_reset = 4'b0xxx; | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         genvar i; |         genvar i; | ||||||
|  | @ -745,6 +749,9 @@ module DSP48E1 ( | ||||||
| 
 | 
 | ||||||
|     wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum; |     wire signed [47:0] Pd = ALUMODEr[1] ? ~alu_sum : alu_sum; | ||||||
|     initial P = 48'b0; |     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 : |     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); |                            ((ALUMODEr[0] & ALUMODEr[1]) ? ~ext_carry_out : ext_carry_out); | ||||||
|     wire CARRYCASCOUTd = ext_carry_out[3]; |     wire CARRYCASCOUTd = ext_carry_out[3]; | ||||||
|  | @ -755,7 +762,7 @@ module DSP48E1 ( | ||||||
|             always @(posedge CLK) |             always @(posedge CLK) | ||||||
|                 if (RSTP) begin |                 if (RSTP) begin | ||||||
|                     P <= 48'b0; |                     P <= 48'b0; | ||||||
|                     CARRYOUT <= 4'b0; |                     CARRYOUT <= carryout_reset; | ||||||
|                     CARRYCASCOUT <= 1'b0; |                     CARRYCASCOUT <= 1'b0; | ||||||
|                     MULTSIGNOUT <= 1'b0; |                     MULTSIGNOUT <= 1'b0; | ||||||
|                 end else if (CEP) begin |                 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 | 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 | 	cat /opt/Xilinx/Vivado/2019.1/data/verilog/src/unisims/DSP48E1.v > test_dsp_model_ref.v | ||||||
| fi | fi | ||||||
| for tb in mult_noreg_nopreadd_nocasc | for tb in mult_allreg_nopreadd_nocasc mult_noreg_nopreadd_nocasc | ||||||
| do | 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 | 	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 | 	vvp -N ./test_dsp_model | ||||||
|  |  | ||||||
|  | @ -94,7 +94,7 @@ module testbench; | ||||||
| 			if (OPMODE[1:0] == 2'b10 && PREG != 1) config_valid = 0; | 			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[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'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 ((CARRYINSEL == 3'b100 || CARRYINSEL == 3'b101 || CARRYINSEL == 3'b111) && (PREG != 1)) config_valid = 0; | ||||||
| 			if (OPMODE[6:4] == 3'b111) 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; | 			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; | 		{OPMODE, CARRYCASCIN, CARRYIN, MULTSIGNIN} = 0; | ||||||
| 
 | 
 | ||||||
| 		{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = ~0; | 		{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = ~0; | ||||||
| 		#5; | 		repeat (10) begin | ||||||
| 		CLK = 1'b1; | 			#10; | ||||||
| 		#10; | 			CLK = 1'b1; | ||||||
| 		CLK = 1'b0; | 			#10; | ||||||
| 		#5; | 			CLK = 1'b0; | ||||||
| 		CLK = 1'b1; | 			#10; | ||||||
| 		#10; | 			CLK = 1'b1; | ||||||
| 		CLK = 1'b0; | 			#10; | ||||||
|  | 			CLK = 1'b0; | ||||||
|  | 		end | ||||||
| 		{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0; | 		{RSTA, RSTALLCARRYIN, RSTALUMODE, RSTB, RSTC, RSTCTRL, RSTD, RSTINMODE, RSTM, RSTP} = 0; | ||||||
| 
 | 
 | ||||||
| 		repeat (300) begin | 		repeat (300) begin | ||||||
|  | @ -358,4 +360,39 @@ module mult_noreg_nopreadd_nocasc; | ||||||
| 		.IS_INMODE_INVERTED (5'b0), | 		.IS_INMODE_INVERTED (5'b0), | ||||||
| 		.IS_OPMODE_INVERTED (7'b0) | 		.IS_OPMODE_INVERTED (7'b0) | ||||||
| 	) testbench (); | 	) 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 | endmodule | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue