mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	sv: fix some edge cases for unbased unsized literals
- Fix explicit size cast of unbased unsized literals - Fix unbased unsized literal bound directly to port - Output `is_unsized` flag in `dumpAst`
This commit is contained in:
		
							parent
							
								
									d245e2bae5
								
							
						
					
					
						commit
						b1a8e73a60
					
				
					 4 changed files with 70 additions and 1 deletions
				
			
		|  | @ -317,6 +317,8 @@ void AstNode::dumpAst(FILE *f, std::string indent) const | ||||||
| 		fprintf(f, " reg"); | 		fprintf(f, " reg"); | ||||||
| 	if (is_signed) | 	if (is_signed) | ||||||
| 		fprintf(f, " signed"); | 		fprintf(f, " signed"); | ||||||
|  | 	if (is_unsized) | ||||||
|  | 		fprintf(f, " unsized"); | ||||||
| 	if (basic_prep) | 	if (basic_prep) | ||||||
| 		fprintf(f, " basic_prep"); | 		fprintf(f, " basic_prep"); | ||||||
| 	if (lookahead) | 	if (lookahead) | ||||||
|  |  | ||||||
|  | @ -915,6 +915,22 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | ||||||
| 			} | 			} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if (type == AST_ARGUMENT) | ||||||
|  | 	{ | ||||||
|  | 		if (children.size() == 1 && children[0]->type == AST_CONSTANT) | ||||||
|  | 		{ | ||||||
|  | 			// HACK: For port bindings using unbased unsized literals, mark them
 | ||||||
|  | 			// signed so they sign-extend. The hierarchy will still incorrectly
 | ||||||
|  | 			// generate a warning complaining about resizing the expression.
 | ||||||
|  | 			// This also doesn't handle the complex of something like a ternary
 | ||||||
|  | 			// expression bound to a port, where the actual size of the port is
 | ||||||
|  | 			// needed to resolve the expression correctly.
 | ||||||
|  | 			AstNode *arg = children[0]; | ||||||
|  | 			if (arg->is_unsized) | ||||||
|  | 				arg->is_signed = true; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	int backup_width_hint = width_hint; | 	int backup_width_hint = width_hint; | ||||||
| 	bool backup_sign_hint = sign_hint; | 	bool backup_sign_hint = sign_hint; | ||||||
| 
 | 
 | ||||||
|  | @ -3773,7 +3789,11 @@ replace_fcall_later:; | ||||||
| 		case AST_CAST_SIZE: | 		case AST_CAST_SIZE: | ||||||
| 			if (children.at(0)->type == AST_CONSTANT && children.at(1)->type == AST_CONSTANT) { | 			if (children.at(0)->type == AST_CONSTANT && children.at(1)->type == AST_CONSTANT) { | ||||||
| 				int width = children[0]->bitsAsConst().as_int(); | 				int width = children[0]->bitsAsConst().as_int(); | ||||||
| 				RTLIL::Const val = children[1]->bitsAsConst(width); | 				RTLIL::Const val; | ||||||
|  | 				if (children[1]->is_unsized) | ||||||
|  | 					val = children[1]->bitsAsUnsizedConst(width); | ||||||
|  | 				else | ||||||
|  | 					val = children[1]->bitsAsConst(width); | ||||||
| 				newNode = mkconst_bits(val.bits, children[1]->is_signed); | 				newNode = mkconst_bits(val.bits, children[1]->is_signed); | ||||||
| 			} | 			} | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
							
								
								
									
										40
									
								
								tests/verilog/unbased_unsized.sv
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								tests/verilog/unbased_unsized.sv
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | ||||||
|  | module pass_through( | ||||||
|  |     input [63:0] inp, | ||||||
|  |     output [63:0] out | ||||||
|  | ); | ||||||
|  |     assign out = inp; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module top; | ||||||
|  |     logic [63:0] | ||||||
|  |         o01, o02, o03, o04, | ||||||
|  |         o05, o06, o07, o08, | ||||||
|  |         o09, o10, o11, o12, | ||||||
|  |         o13, o14, o15, o16; | ||||||
|  |     assign o01 = '0; | ||||||
|  |     assign o02 = '1; | ||||||
|  |     assign o03 = 'x; | ||||||
|  |     assign o04 = 'z; | ||||||
|  |     assign o05 = 3'('0); | ||||||
|  |     assign o06 = 3'('1); | ||||||
|  |     assign o07 = 3'('x); | ||||||
|  |     assign o08 = 3'('z); | ||||||
|  |     pass_through pt09('0, o09); | ||||||
|  |     pass_through pt10('1, o10); | ||||||
|  |     pass_through pt11('x, o11); | ||||||
|  |     pass_through pt12('z, o12); | ||||||
|  |     always @* begin | ||||||
|  |         assert (o01 === {64 {1'b0}}); | ||||||
|  |         assert (o02 === {64 {1'b1}}); | ||||||
|  |         assert (o03 === {64 {1'bx}}); | ||||||
|  |         assert (o04 === {64 {1'bz}}); | ||||||
|  |         assert (o05 === {61'b0, 3'b000}); | ||||||
|  |         assert (o06 === {61'b0, 3'b111}); | ||||||
|  |         assert (o07 === {61'b0, 3'bxxx}); | ||||||
|  |         assert (o08 === {61'b0, 3'bzzz}); | ||||||
|  |         assert (o09 === {64 {1'b0}}); | ||||||
|  |         assert (o10 === {64 {1'b1}}); | ||||||
|  |         assert (o11 === {64 {1'bx}}); | ||||||
|  |         assert (o12 === {64 {1'bz}}); | ||||||
|  |     end | ||||||
|  | endmodule | ||||||
							
								
								
									
										7
									
								
								tests/verilog/unbased_unsized.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/verilog/unbased_unsized.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | ||||||
|  | read_verilog -sv unbased_unsized.sv | ||||||
|  | hierarchy | ||||||
|  | proc | ||||||
|  | flatten | ||||||
|  | opt -full | ||||||
|  | select -module top | ||||||
|  | sat -verify -seq 1 -tempinduct -prove-asserts -show-all | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue