mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	More fixes in ast expression sign/width handling
This commit is contained in:
		
							parent
							
								
									618b2ac994
								
							
						
					
					
						commit
						5dab327b30
					
				
					 2 changed files with 22 additions and 21 deletions
				
			
		| 
						 | 
					@ -530,7 +530,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint)
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case AST_TO_UNSIGNED:
 | 
						case AST_TO_UNSIGNED:
 | 
				
			||||||
		children.at(0)->detectSignWidthWorker(width_hint, sign_hint);
 | 
							children.at(0)->detectSignWidthWorker(width_hint, dummy_sign_hint);
 | 
				
			||||||
		sign_hint = false;
 | 
							sign_hint = false;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -593,8 +593,8 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint)
 | 
				
			||||||
	case AST_LOGIC_AND:
 | 
						case AST_LOGIC_AND:
 | 
				
			||||||
	case AST_LOGIC_OR:
 | 
						case AST_LOGIC_OR:
 | 
				
			||||||
	case AST_LOGIC_NOT:
 | 
						case AST_LOGIC_NOT:
 | 
				
			||||||
		for (auto child : children)
 | 
							width_hint = std::max(width_hint, 1);
 | 
				
			||||||
			child->detectSignWidthWorker(width_hint, sign_hint);
 | 
							sign_hint = false;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	case AST_TERNARY:
 | 
						case AST_TERNARY:
 | 
				
			||||||
| 
						 | 
					@ -835,7 +835,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
				
			||||||
	// just pass thru the signal. the parent will evaluated the is_signed property and inperpret the SigSpec accordingly
 | 
						// just pass thru the signal. the parent will evaluated the is_signed property and inperpret the SigSpec accordingly
 | 
				
			||||||
	case AST_TO_SIGNED:
 | 
						case AST_TO_SIGNED:
 | 
				
			||||||
	case AST_TO_UNSIGNED: {
 | 
						case AST_TO_UNSIGNED: {
 | 
				
			||||||
			RTLIL::SigSpec sig = children[0]->genRTLIL(width_hint, sign_hint);
 | 
								RTLIL::SigSpec sig = children[0]->genRTLIL();
 | 
				
			||||||
			is_signed = type == AST_TO_SIGNED;
 | 
								is_signed = type == AST_TO_SIGNED;
 | 
				
			||||||
			return sig;
 | 
								return sig;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -889,6 +889,8 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
				
			||||||
	if (0) { case AST_BIT_XOR:  type_name = "$xor"; }
 | 
						if (0) { case AST_BIT_XOR:  type_name = "$xor"; }
 | 
				
			||||||
	if (0) { case AST_BIT_XNOR: type_name = "$xnor"; }
 | 
						if (0) { case AST_BIT_XNOR: type_name = "$xnor"; }
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								if (width_hint < 0)
 | 
				
			||||||
 | 
									detectSignWidth(width_hint, sign_hint);
 | 
				
			||||||
			RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint);
 | 
								RTLIL::SigSpec left = children[0]->genRTLIL(width_hint, sign_hint);
 | 
				
			||||||
			RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint);
 | 
								RTLIL::SigSpec right = children[1]->genRTLIL(width_hint, sign_hint);
 | 
				
			||||||
			int width = std::max(left.width, right.width);
 | 
								int width = std::max(left.width, right.width);
 | 
				
			||||||
| 
						 | 
					@ -965,12 +967,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
 | 
				
			||||||
			if (width > width_hint && width_hint > 0)
 | 
								if (width > width_hint && width_hint > 0)
 | 
				
			||||||
				width = width_hint;
 | 
									width = width_hint;
 | 
				
			||||||
			if (width < width_hint) {
 | 
								if (width < width_hint) {
 | 
				
			||||||
				if (type == AST_ADD || type == AST_SUB) {
 | 
									if (type == AST_ADD || type == AST_SUB)
 | 
				
			||||||
					width++;
 | 
										width++;
 | 
				
			||||||
					if (width < width_hint && children[0]->is_signed != children[1]->is_signed)
 | 
									if (type == AST_SUB && (!children[0]->is_signed || !children[1]->is_signed))
 | 
				
			||||||
						width++;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (type == AST_SUB && !children[0]->is_signed && !children[1]->is_signed)
 | 
					 | 
				
			||||||
					width = width_hint;
 | 
										width = width_hint;
 | 
				
			||||||
				if (type == AST_MUL)
 | 
									if (type == AST_MUL)
 | 
				
			||||||
					width = std::min(left.width + right.width, width_hint);
 | 
										width = std::min(left.width + right.width, width_hint);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,19 +27,21 @@ module test04(a, y);
 | 
				
			||||||
  assign y = ~(a - 1'b0);
 | 
					  assign y = ~(a - 1'b0);
 | 
				
			||||||
endmodule
 | 
					endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module test05(a, y);
 | 
					// .. this test triggers a bug in xilinx isim.
 | 
				
			||||||
  input a;
 | 
					// module test05(a, y);
 | 
				
			||||||
  output y;
 | 
					//   input a;
 | 
				
			||||||
  assign y = 12345 >> {a, 32'd0};
 | 
					//   output y;
 | 
				
			||||||
endmodule
 | 
					//   assign y = 12345 >> {a, 32'd0};
 | 
				
			||||||
 | 
					// endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module test06(a, b, c, y);
 | 
					// .. this test triggers a bug in icarus verilog.
 | 
				
			||||||
  input signed [3:0] a;
 | 
					// module test06(a, b, c, y);
 | 
				
			||||||
  input signed [1:0] b;
 | 
					//   input signed [3:0] a;
 | 
				
			||||||
  input signed [1:0] c;
 | 
					//   input signed [1:0] b;
 | 
				
			||||||
  output [5:0] y;
 | 
					//   input signed [1:0] c;
 | 
				
			||||||
  assign y = (a >> b) >>> c;
 | 
					//   output [5:0] y;
 | 
				
			||||||
endmodule
 | 
					//   assign y = (a >> b) >>> c;
 | 
				
			||||||
 | 
					// endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module test07(a, b, y);
 | 
					module test07(a, b, y);
 | 
				
			||||||
  input signed [1:0] a;
 | 
					  input signed [1:0] a;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue