mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	cmp2lut: new techmap pass.
This commit is contained in:
		
							parent
							
								
									4b9f619349
								
							
						
					
					
						commit
						a91892bba4
					
				
					 5 changed files with 139 additions and 3 deletions
				
			
		|  | @ -26,5 +26,5 @@ $(eval $(call add_share_file,share,techlibs/common/pmux2mux.v)) | ||||||
| $(eval $(call add_share_file,share,techlibs/common/adff2dff.v)) | $(eval $(call add_share_file,share,techlibs/common/adff2dff.v)) | ||||||
| $(eval $(call add_share_file,share,techlibs/common/dff2ff.v)) | $(eval $(call add_share_file,share,techlibs/common/dff2ff.v)) | ||||||
| $(eval $(call add_share_file,share,techlibs/common/gate2lut.v)) | $(eval $(call add_share_file,share,techlibs/common/gate2lut.v)) | ||||||
|  | $(eval $(call add_share_file,share,techlibs/common/cmp2lut.v)) | ||||||
| $(eval $(call add_share_file,share,techlibs/common/cells.lib)) | $(eval $(call add_share_file,share,techlibs/common/cells.lib)) | ||||||
| 
 |  | ||||||
|  |  | ||||||
							
								
								
									
										105
									
								
								techlibs/common/cmp2lut.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								techlibs/common/cmp2lut.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,105 @@ | ||||||
|  | // Certain arithmetic operations between a signal of width n and a constant can be directly mapped | ||||||
|  | // to a single k-LUT (where n <= k). This is preferable to normal alumacc techmapping process | ||||||
|  | // because for many targets, arithmetic techmapping creates hard logic (such as carry cells) which often | ||||||
|  | // cannot be optimized further. | ||||||
|  | // | ||||||
|  | // TODO: Currently, only comparisons with 1-bit output are mapped. Potentially, all arithmetic cells | ||||||
|  | // with n <= k inputs should be techmapped in this way, because this shortens the critical path | ||||||
|  | // from n to 1 by avoiding carry chains. | ||||||
|  | 
 | ||||||
|  | (* techmap_celltype = "$eq $ne $lt $le $gt $ge" *) | ||||||
|  | module _90_lut_cmp_ (A, B, Y); | ||||||
|  | 
 | ||||||
|  | parameter A_SIGNED = 0; | ||||||
|  | parameter B_SIGNED = 0; | ||||||
|  | parameter A_WIDTH = 0; | ||||||
|  | parameter B_WIDTH = 0; | ||||||
|  | parameter Y_WIDTH = 0; | ||||||
|  | 
 | ||||||
|  | input [A_WIDTH-1:0] A; | ||||||
|  | input [B_WIDTH-1:0] B; | ||||||
|  | output [Y_WIDTH-1:0] Y; | ||||||
|  | 
 | ||||||
|  | parameter _TECHMAP_CELLTYPE_ = ""; | ||||||
|  | 
 | ||||||
|  | parameter _TECHMAP_CONSTMSK_A_ = 0; | ||||||
|  | parameter _TECHMAP_CONSTVAL_A_ = 0; | ||||||
|  | parameter _TECHMAP_CONSTMSK_B_ = 0; | ||||||
|  | parameter _TECHMAP_CONSTVAL_B_ = 0; | ||||||
|  | 
 | ||||||
|  | function automatic integer gen_lut; | ||||||
|  | 	input integer width; | ||||||
|  | 	input integer operation; | ||||||
|  | 	input integer swap; | ||||||
|  | 	input integer sign; | ||||||
|  | 	input integer operand; | ||||||
|  | 	integer n, i_var, i_cst, lhs, rhs, o_bit; | ||||||
|  | 	begin | ||||||
|  | 		gen_lut = width'b0; | ||||||
|  | 		for (n = 0; n < (1 << width); n++) begin | ||||||
|  | 			if (sign) | ||||||
|  | 				i_var = n[width-1:0]; | ||||||
|  | 			else | ||||||
|  | 				i_var = n; | ||||||
|  | 			i_cst = operand; | ||||||
|  | 			if (swap) begin | ||||||
|  | 				lhs = i_cst; | ||||||
|  | 				rhs = i_var; | ||||||
|  | 			end else begin | ||||||
|  | 				lhs = i_var; | ||||||
|  | 				rhs = i_cst; | ||||||
|  | 			end | ||||||
|  | 			if (operation == 0) | ||||||
|  | 				o_bit = (lhs <  rhs); | ||||||
|  | 			if (operation == 1) | ||||||
|  | 				o_bit = (lhs <= rhs); | ||||||
|  | 			if (operation == 2) | ||||||
|  | 				o_bit = (lhs >  rhs); | ||||||
|  | 			if (operation == 3) | ||||||
|  | 				o_bit = (lhs >= rhs); | ||||||
|  | 			if (operation == 4) | ||||||
|  | 				o_bit = (lhs == rhs); | ||||||
|  | 			if (operation == 5) | ||||||
|  | 				o_bit = (lhs != rhs); | ||||||
|  | 			gen_lut = gen_lut | (o_bit << n); | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | endfunction | ||||||
|  | 
 | ||||||
|  | generate | ||||||
|  | 	if (_TECHMAP_CELLTYPE_ == "$lt") | ||||||
|  | 		localparam operation = 0; | ||||||
|  | 	if (_TECHMAP_CELLTYPE_ == "$le") | ||||||
|  | 		localparam operation = 1; | ||||||
|  | 	if (_TECHMAP_CELLTYPE_ == "$gt") | ||||||
|  | 		localparam operation = 2; | ||||||
|  | 	if (_TECHMAP_CELLTYPE_ == "$ge") | ||||||
|  | 		localparam operation = 3; | ||||||
|  | 	if (_TECHMAP_CELLTYPE_ == "$eq") | ||||||
|  | 		localparam operation = 4; | ||||||
|  | 	if (_TECHMAP_CELLTYPE_ == "$ne") | ||||||
|  | 		localparam operation = 5; | ||||||
|  | 
 | ||||||
|  | 	if (A_WIDTH > `LUT_WIDTH || B_WIDTH > `LUT_WIDTH || Y_WIDTH != 1) | ||||||
|  | 		wire _TECHMAP_FAIL_ = 1; | ||||||
|  | 	else if (&_TECHMAP_CONSTMSK_B_) | ||||||
|  | 		\$lut #( | ||||||
|  | 			.WIDTH(A_WIDTH), | ||||||
|  | 			.LUT({ gen_lut(A_WIDTH, operation, 0, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_B_) }) | ||||||
|  | 		) _TECHMAP_REPLACE_ ( | ||||||
|  | 			.A(A), | ||||||
|  | 			.Y(Y) | ||||||
|  | 		); | ||||||
|  | 	else if (&_TECHMAP_CONSTMSK_A_) | ||||||
|  | 		\$lut #( | ||||||
|  | 			.WIDTH(B_WIDTH), | ||||||
|  | 			.LUT({ gen_lut(B_WIDTH, operation, 1, A_SIGNED && B_SIGNED, _TECHMAP_CONSTVAL_A_) }) | ||||||
|  | 		) _TECHMAP_REPLACE_ ( | ||||||
|  | 			.A(B), | ||||||
|  | 			.Y(Y) | ||||||
|  | 		); | ||||||
|  | 	else | ||||||
|  | 		wire _TECHMAP_FAIL_ = 1; | ||||||
|  | endgenerate | ||||||
|  | 
 | ||||||
|  | endmodule | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| simplemap | simplemap | ||||||
| equiv_opt -assert techmap -map +/gate2lut.v -D LUT_WIDTH=4 | equiv_opt -assert techmap -D LUT_WIDTH=4 -map +/cmp2lut.v | ||||||
| design -load postopt | design -load postopt | ||||||
| select -assert-count 1 t:$lut | equiv_opt -assert techmap -D LUT_WIDTH=4 -map +/gate2lut.v | ||||||
|  | design -load postopt | ||||||
|  | select -assert-count 0 t:* t:$lut %d | ||||||
|  |  | ||||||
							
								
								
									
										29
									
								
								tests/lut/map_cmp.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								tests/lut/map_cmp.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | module top(...); | ||||||
|  | 	input [3:0] a; | ||||||
|  | 
 | ||||||
|  | 	output o1_1 = 4'b1010 <= a; | ||||||
|  | 	output o1_2 = 4'b1010 <  a; | ||||||
|  | 	output o1_3 = 4'b1010 >= a; | ||||||
|  | 	output o1_4 = 4'b1010 >  a; | ||||||
|  | 	output o1_5 = 4'b1010 == a; | ||||||
|  | 	output o1_6 = 4'b1010 != a; | ||||||
|  | 
 | ||||||
|  | 	output o2_1 = a <= 4'b1010; | ||||||
|  | 	output o2_2 = a <  4'b1010; | ||||||
|  | 	output o2_3 = a >= 4'b1010; | ||||||
|  | 	output o2_4 = a >  4'b1010; | ||||||
|  | 	output o2_5 = a == 4'b1010; | ||||||
|  | 	output o2_6 = a != 4'b1010; | ||||||
|  | 
 | ||||||
|  | 	output o3_1 = 4'sb0101 <= $signed(a); | ||||||
|  | 	output o3_2 = 4'sb0101 <  $signed(a); | ||||||
|  | 	output o3_3 = 4'sb0101 >= $signed(a); | ||||||
|  | 	output o3_4 = 4'sb0101 >  $signed(a); | ||||||
|  | 	output o3_5 = 4'sb0101 == $signed(a); | ||||||
|  | 	output o3_6 = 4'sb0101 != $signed(a); | ||||||
|  | 
 | ||||||
|  | 	output o4_1 = $signed(a) <= 4'sb0000; | ||||||
|  | 	output o4_2 = $signed(a) <  4'sb0000; | ||||||
|  | 	output o4_3 = $signed(a) >= 4'sb0000; | ||||||
|  | 	output o4_4 = $signed(a) >  4'sb0000; | ||||||
|  | endmodule | ||||||
							
								
								
									
										0
									
								
								tests/lut/run-test.sh
									
										
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										0
									
								
								tests/lut/run-test.sh
									
										
									
									
									
										
										
										Normal file → Executable file
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue