mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	read_verilog: simplify ternary condition early, ignore unreach children
This commit is contained in:
		
							parent
							
								
									5791c52e1b
								
							
						
					
					
						commit
						dd3c3c0bdc
					
				
					 2 changed files with 32 additions and 14 deletions
				
			
		|  | @ -769,8 +769,10 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun | |||
| 		break; | ||||
| 
 | ||||
| 	case AST_TERNARY: | ||||
| 		children.at(1)->detectSignWidthWorker(width_hint, sign_hint, found_real); | ||||
| 		children.at(2)->detectSignWidthWorker(width_hint, sign_hint, found_real); | ||||
| 		if (children.at(0)->type != AST_CONSTANT || children.at(0)->asBool()) | ||||
| 			children.at(1)->detectSignWidthWorker(width_hint, sign_hint, found_real); | ||||
| 		if (children.at(0)->type != AST_CONSTANT || !children.at(0)->asBool()) | ||||
| 			children.at(2)->detectSignWidthWorker(width_hint, sign_hint, found_real); | ||||
| 		break; | ||||
| 
 | ||||
| 	case AST_MEMRD: | ||||
|  | @ -1334,18 +1336,31 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | |||
| 				detectSignWidth(width_hint, sign_hint); | ||||
| 
 | ||||
| 			RTLIL::SigSpec cond = children[0]->genRTLIL(); | ||||
| 			RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); | ||||
| 			RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); | ||||
| 			RTLIL::SigSpec sig; | ||||
| 			if (cond.is_fully_const()) { | ||||
| 				if (cond.as_bool()) { | ||||
| 					sig = children[1]->genRTLIL(width_hint, sign_hint); | ||||
| 					widthExtend(this, sig, sig.size(), children[1]->is_signed); | ||||
| 				} | ||||
| 				else { | ||||
| 					sig = children[2]->genRTLIL(width_hint, sign_hint); | ||||
| 					widthExtend(this, sig, sig.size(), children[2]->is_signed); | ||||
| 				} | ||||
| 			} | ||||
| 			else { | ||||
| 				RTLIL::SigSpec val1 = children[1]->genRTLIL(width_hint, sign_hint); | ||||
| 				RTLIL::SigSpec val2 = children[2]->genRTLIL(width_hint, sign_hint); | ||||
| 
 | ||||
| 			if (cond.size() > 1) | ||||
| 				cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); | ||||
| 				if (cond.size() > 1) | ||||
| 					cond = uniop2rtlil(this, "$reduce_bool", 1, cond, false); | ||||
| 
 | ||||
| 			int width = max(val1.size(), val2.size()); | ||||
| 			is_signed = children[1]->is_signed && children[2]->is_signed; | ||||
| 			widthExtend(this, val1, width, is_signed); | ||||
| 			widthExtend(this, val2, width, is_signed); | ||||
| 				int width = max(val1.size(), val2.size()); | ||||
| 				is_signed = children[1]->is_signed && children[2]->is_signed; | ||||
| 				widthExtend(this, val1, width, is_signed); | ||||
| 				widthExtend(this, val2, width, is_signed); | ||||
| 
 | ||||
| 			RTLIL::SigSpec sig = mux2rtlil(this, cond, val1, val2); | ||||
| 				sig = mux2rtlil(this, cond, val1, val2); | ||||
| 			} | ||||
| 
 | ||||
| 			if (sig.size() < width_hint) | ||||
| 				sig.extend_u0(width_hint, sign_hint); | ||||
|  |  | |||
|  | @ -572,6 +572,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	case AST_TERNARY: | ||||
| 		detect_width_simple = true; | ||||
| 		child_0_is_self_determined = true; | ||||
| 		while (children[0]->simplify(true, false, false, 1, -1, false, false)) { } | ||||
| 		break; | ||||
| 
 | ||||
| 	case AST_MEMRD: | ||||
|  | @ -605,9 +606,11 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 	if (type == AST_TERNARY) { | ||||
| 		int width_hint_left, width_hint_right; | ||||
| 		bool sign_hint_left, sign_hint_right; | ||||
| 		bool found_real_left, found_real_right; | ||||
| 		children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left); | ||||
| 		children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right); | ||||
| 		bool found_real_left = false, found_real_right = false; | ||||
| 		if (children[0]->type != AST_CONSTANT || children[0]->asBool()) | ||||
| 			children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left); | ||||
| 		if (children[0]->type != AST_CONSTANT || !children[0]->asBool()) | ||||
| 			children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right); | ||||
| 		if (found_real_left || found_real_right) { | ||||
| 			child_1_is_self_determined = true; | ||||
| 			child_2_is_self_determined = true; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue