mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +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()) | ||||
| 			{ | ||||
| 				const char *condition, *replacement; | ||||
| 				std::string condition, replacement; | ||||
| 				SigSpec result_sig(State::S0, GetSize(cell->getPort("\\Y"))); | ||||
| 				result_sig[0] = State::Sx; | ||||
| 				bool replace = false; | ||||
| 
 | ||||
| 				if (!is_signed) | ||||
| 				{ | ||||
| 				{ /* unsigned */ | ||||
| 					if (const_sig.is_fully_zero() && cmp_type == "$lt") { | ||||
| 						condition   = "unsigned X<0"; | ||||
| 						replacement = "constant 0"; | ||||
| 						result_sig[0] = State::S0; | ||||
| 						replace = true; | ||||
| 					} | ||||
| 					if (const_sig.is_fully_zero() && cmp_type == "$ge") { | ||||
| 						condition   = "unsigned X>=0"; | ||||
| 						replacement = "constant 1"; | ||||
| 						result_sig[0] = State::S1; | ||||
| 						replace = true; | ||||
| 					} | ||||
| 					if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$gt") { | ||||
| 						condition   = "unsigned X>~0"; | ||||
| 						replacement = "constant 0"; | ||||
| 						result_sig[0] = State::S0; | ||||
| 						replace = true; | ||||
| 					} | ||||
| 					if (const_width == var_width && const_sig.is_fully_ones() && cmp_type == "$le") { | ||||
| 						condition   = "unsigned X<=~0"; | ||||
| 						replacement = "constant 1"; | ||||
| 						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_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->remove(cell); | ||||
| 					did_something = true; | ||||
|  | @ -1453,25 +1474,6 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons | |||
| 			} else | ||||
| 				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) | ||||
| 			{ | ||||
| 				int const_bit_set = get_onehot_bit_index(sigConst); | ||||
|  |  | |||
|  | @ -1,11 +1,17 @@ | |||
| module top(...); | ||||
|   input [3:0] a; | ||||
|   output o1 = 4'b0000 >  a; | ||||
|   output o2 = 4'b0000 <= a; | ||||
|   output o3 = 4'b1111 <  a; | ||||
|   output o4 = 4'b1111 >= a; | ||||
|   output o5 = a <  4'b0000; | ||||
|   output o6 = a >= 4'b0000; | ||||
|   output o7 = a >  4'b1111; | ||||
|   output o8 = a <= 4'b1111; | ||||
| 
 | ||||
|   output o1_1 = 4'b0000 >  a; | ||||
|   output o1_2 = 4'b0000 <= a; | ||||
|   output o1_3 = 4'b1111 <  a; | ||||
|   output o1_4 = 4'b1111 >= a; | ||||
|   output o1_5 = a <  4'b0000; | ||||
|   output o1_6 = a >= 4'b0000; | ||||
|   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 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue