mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	opt_expr: Optimize multiplications with low 0 bits in operands.
Fixes #1500.
This commit is contained in:
		
							parent
							
								
									5448f9c85d
								
							
						
					
					
						commit
						840bb17089
					
				
					 2 changed files with 61 additions and 0 deletions
				
			
		|  | @ -1426,6 +1426,39 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 						goto next_cell; | 						goto next_cell; | ||||||
| 					} | 					} | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			sig_a = assign_map(cell->getPort(ID::A)); | ||||||
|  | 			sig_b = assign_map(cell->getPort(ID::B)); | ||||||
|  | 			int a_zeros, b_zeros; | ||||||
|  | 			for (a_zeros = 0; a_zeros < GetSize(sig_a); a_zeros++) | ||||||
|  | 				if (sig_a[a_zeros] != RTLIL::State::S0) | ||||||
|  | 					break; | ||||||
|  | 			for (b_zeros = 0; b_zeros < GetSize(sig_b); b_zeros++) | ||||||
|  | 				if (sig_b[b_zeros] != RTLIL::State::S0) | ||||||
|  | 					break; | ||||||
|  | 			if (a_zeros || b_zeros) { | ||||||
|  | 				int y_zeros = a_zeros + b_zeros; | ||||||
|  | 				cover("opt.opt_expr.mul_low_zeros"); | ||||||
|  | 
 | ||||||
|  | 				log_debug("Removing low %d A and %d B bits from cell `%s' in module `%s'.\n", | ||||||
|  | 						a_zeros, b_zeros, cell->name.c_str(), module->name.c_str()); | ||||||
|  | 
 | ||||||
|  | 				if (a_zeros) { | ||||||
|  | 					cell->setPort(ID::A, sig_a.extract_end(a_zeros)); | ||||||
|  | 					cell->parameters[ID::A_WIDTH] = GetSize(sig_a) - a_zeros; | ||||||
|  | 				} | ||||||
|  | 				if (b_zeros) { | ||||||
|  | 					cell->setPort(ID::B, sig_b.extract_end(b_zeros)); | ||||||
|  | 					cell->parameters[ID::B_WIDTH] = GetSize(sig_b) - b_zeros; | ||||||
|  | 				} | ||||||
|  | 				cell->setPort(ID::Y, sig_y.extract_end(y_zeros)); | ||||||
|  | 				cell->parameters[ID::Y_WIDTH] = GetSize(sig_y) - y_zeros; | ||||||
|  | 				module->connect(RTLIL::SigSig(sig_y.extract(0, y_zeros), RTLIL::SigSpec(0, y_zeros))); | ||||||
|  | 				cell->check(); | ||||||
|  | 
 | ||||||
|  | 				did_something = true; | ||||||
|  | 				goto next_cell; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (!keepdc && cell->type.in(ID($div), ID($mod))) | 		if (!keepdc && cell->type.in(ID($div), ID($mod))) | ||||||
|  |  | ||||||
|  | @ -291,3 +291,31 @@ check | ||||||
| equiv_opt -assert opt_expr -keepdc | equiv_opt -assert opt_expr -keepdc | ||||||
| design -load postopt | design -load postopt | ||||||
| select -assert-count 1 t:$shift r:A_WIDTH=13 %i | select -assert-count 1 t:$shift r:A_WIDTH=13 %i | ||||||
|  | 
 | ||||||
|  | ########### | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
|  | read_verilog -icells <<EOT | ||||||
|  | module opt_expr_mul_low_bits(input [2:0] a, input [2:0] b, output [7:0] y); | ||||||
|  |     \$mul #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(4), .Y_WIDTH(8)) mul (.A({a, 1'b0}), .B({b, 1'b0}), .Y(y)); | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | check | ||||||
|  | 
 | ||||||
|  | equiv_opt -assert opt_expr | ||||||
|  | design -load postopt | ||||||
|  | select -assert-count 1 t:$mul r:A_WIDTH=3 %i r:B_WIDTH=3 %i r:Y_WIDTH=6 %i | ||||||
|  | 
 | ||||||
|  | ########### | ||||||
|  | 
 | ||||||
|  | design -reset | ||||||
|  | read_verilog -icells <<EOT | ||||||
|  | module opt_expr_mul_low_bits(input [2:0] a, input [2:0] b, output [7:0] y); | ||||||
|  |     \$mul #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(4), .Y_WIDTH(8)) mul (.A({a, 1'b0}), .B({b, 1'b0}), .Y(y)); | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | check | ||||||
|  | 
 | ||||||
|  | equiv_opt -assert opt_expr -keepdc | ||||||
|  | design -load postopt | ||||||
|  | select -assert-count 1 t:$mul r:A_WIDTH=4 %i r:B_WIDTH=4 %i r:Y_WIDTH=8 %i | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue