mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	opt_expr: refactor simplification of signed X>=0 and X<0. NFCI.
This commit is contained in:
		
							parent
							
								
									8e53d2e0bf
								
							
						
					
					
						commit
						9e9846a6ea
					
				
					 2 changed files with 40 additions and 32 deletions
				
			
		|  | @ -1373,38 +1373,59 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 
 | 
 | ||||||
| 			if (const_sig.is_fully_def() && const_sig.is_fully_const()) | 			if (const_sig.is_fully_def() && const_sig.is_fully_const()) | ||||||
| 			{ | 			{ | ||||||
| 				const char *condition, *replacement; | 				std::string condition, replacement; | ||||||
| 				SigSpec result_sig(State::S0, GetSize(cell->getPort("\\Y"))); | 				SigSpec result_sig(State::S0, GetSize(cell->getPort("\\Y"))); | ||||||
| 				result_sig[0] = State::Sx; | 				bool replace = false; | ||||||
| 
 | 
 | ||||||
| 				if (!is_signed) | 				if (!is_signed) | ||||||
| 				{ | 				{ /* unsigned */ | ||||||
| 					if (const_sig.is_fully_zero() && cmp_type == "$lt") { | 					if (const_sig.is_fully_zero() && cmp_type == "$lt") { | ||||||
| 						condition   = "unsigned X<0"; | 						condition   = "unsigned X<0"; | ||||||
| 						replacement = "constant 0"; | 						replacement = "constant 0"; | ||||||
| 						result_sig[0] = State::S0; | 						result_sig[0] = State::S0; | ||||||
|  | 						replace = true; | ||||||
| 					} | 					} | ||||||
| 					if (const_sig.is_fully_zero() && cmp_type == "$ge") { | 					if (const_sig.is_fully_zero() && cmp_type == "$ge") { | ||||||
| 						condition   = "unsigned X>=0"; | 						condition   = "unsigned X>=0"; | ||||||
| 						replacement = "constant 1"; | 						replacement = "constant 1"; | ||||||
| 						result_sig[0] = State::S1; | 						result_sig[0] = State::S1; | ||||||
|  | 						replace = true; | ||||||
| 					} | 					} | ||||||
| 					if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$gt") { | 					if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$gt") { | ||||||
| 						condition   = "unsigned X>~0"; | 						condition   = "unsigned X>~0"; | ||||||
| 						replacement = "constant 0"; | 						replacement = "constant 0"; | ||||||
| 						result_sig[0] = State::S0; | 						result_sig[0] = State::S0; | ||||||
|  | 						replace = true; | ||||||
| 					} | 					} | ||||||
| 					if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$le") { | 					if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$le") { | ||||||
| 						condition   = "unsigned X<=~0"; | 						condition   = "unsigned X<=~0"; | ||||||
| 						replacement = "constant 1"; | 						replacement = "constant 1"; | ||||||
| 						result_sig[0] = State::S1; | 						result_sig[0] = State::S1; | ||||||
|  | 						replace = true; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ /* signed */ | ||||||
|  | 					if (const_sig.is_fully_zero() && cmp_type == "$lt") | ||||||
|  | 					{ | ||||||
|  | 						condition   = "signed X<0"; | ||||||
|  | 						replacement = stringf("X[%d]", var_width - 1); | ||||||
|  | 						result_sig[0] = var_sig[var_width - 1]; | ||||||
|  | 						replace = true; | ||||||
|  | 					} | ||||||
|  | 					if (const_sig.is_fully_zero() && cmp_type == "$ge") | ||||||
|  | 					{ | ||||||
|  | 						condition   = "signed X>=0"; | ||||||
|  | 						replacement = stringf("X[%d]", var_width - 1); | ||||||
|  | 						module->addNot(NEW_ID, var_sig[var_width - 1], result_sig); | ||||||
|  | 						replace = true; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (result_sig.is_fully_def()) | 				if (replace) | ||||||
| 				{ | 				{ | ||||||
| 					log("Replacing %s cell `%s' (implementing %s) with %s.\n", | 					log("Replacing %s cell `%s' (implementing %s) with %s.\n", | ||||||
| 							log_id(cell->type), log_id(cell), condition, replacement); | 							log_id(cell->type), log_id(cell), condition.c_str(), replacement.c_str()); | ||||||
| 					module->connect(cell->getPort("\\Y"), result_sig); | 					module->connect(cell->getPort("\\Y"), result_sig); | ||||||
| 					module->remove(cell); | 					module->remove(cell); | ||||||
| 					did_something = true; | 					did_something = true; | ||||||
|  | @ -1453,25 +1474,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | ||||||
| 			} else | 			} else | ||||||
| 				log_abort(); | 				log_abort(); | ||||||
| 
 | 
 | ||||||
| 			// replace a(signed) < 0 with the high bit of a
 |  | ||||||
| 			if (sigConst.is_fully_const() && sigConst.is_fully_zero() && var_signed == true) |  | ||||||
| 			{ |  | ||||||
| 				RTLIL::SigSpec a_prime(RTLIL::State::S0, cell->parameters["\\Y_WIDTH"].as_int()); |  | ||||||
| 				a_prime[0] = sigVar[width - 1]; |  | ||||||
| 				if (is_lt) { |  | ||||||
| 					log("Replacing %s cell `%s' (implementing X<0) with X[%d]: %s\n", |  | ||||||
| 							log_id(cell->type), log_id(cell), width-1, log_signal(a_prime)); |  | ||||||
| 					module->connect(cell->getPort("\\Y"), a_prime); |  | ||||||
| 					module->remove(cell); |  | ||||||
| 				} else { |  | ||||||
| 					log("Replacing %s cell `%s' (implementing X>=0) with ~X[%d]: %s\n", |  | ||||||
| 							log_id(cell->type), log_id(cell), width-1, log_signal(a_prime)); |  | ||||||
| 					module->addNot(NEW_ID, a_prime, cell->getPort("\\Y")); |  | ||||||
| 					module->remove(cell); |  | ||||||
| 				} |  | ||||||
| 				did_something = true; |  | ||||||
| 				goto next_cell; |  | ||||||
| 			} else |  | ||||||
| 			if (sigConst.is_fully_const() && sigConst.is_fully_def() && var_signed == false) | 			if (sigConst.is_fully_const() && sigConst.is_fully_def() && var_signed == false) | ||||||
| 			{ | 			{ | ||||||
| 				int const_bit_set = get_onehot_bit_index(sigConst); | 				int const_bit_set = get_onehot_bit_index(sigConst); | ||||||
|  |  | ||||||
|  | @ -1,11 +1,17 @@ | ||||||
| module top(...); | module top(...); | ||||||
|   input [3:0] a; |   input [3:0] a; | ||||||
|   output o1 = 4'b0000 >  a; | 
 | ||||||
|   output o2 = 4'b0000 <= a; |   output o1_1 = 4'b0000 >  a; | ||||||
|   output o3 = 4'b1111 <  a; |   output o1_2 = 4'b0000 <= a; | ||||||
|   output o4 = 4'b1111 >= a; |   output o1_3 = 4'b1111 <  a; | ||||||
|   output o5 = a <  4'b0000; |   output o1_4 = 4'b1111 >= a; | ||||||
|   output o6 = a >= 4'b0000; |   output o1_5 = a <  4'b0000; | ||||||
|   output o7 = a >  4'b1111; |   output o1_6 = a >= 4'b0000; | ||||||
|   output o8 = a <= 4'b1111; |   output o1_7 = a >  4'b1111; | ||||||
|  |   output o1_8 = a <= 4'b1111; | ||||||
|  | 
 | ||||||
|  |   output o2_1 = 4'sb0000 >  $signed(a); | ||||||
|  |   output o2_2 = 4'sb0000 <= $signed(a); | ||||||
|  |   output o2_3 = $signed(a) <  4'sb0000; | ||||||
|  |   output o2_4 = $signed(a) >= 4'sb0000; | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue