mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	verilog: indirect AST_CONCAT and AST_TO_UNSIGNED port connections
- AST_CONCAT and AST_TO_UNSIGNED are always unsigned, but may generate RTLIL that exclusively reference a signed wire. - AST_CONCAT may also contain a memory write.
This commit is contained in:
		
							parent
							
								
									e8f8297e5d
								
							
						
					
					
						commit
						f55fbb5803
					
				
					 6 changed files with 72 additions and 9 deletions
				
			
		|  | @ -4,6 +4,11 @@ List of major changes and improvements between releases | |||
| 
 | ||||
| Yosys 0.57 .. Yosys 0.58-dev | ||||
| -------------------------- | ||||
|  * Verilog | ||||
|     - Fixed an issue that prevented using `{<expr>}` or `$unsigned(<expr>)` for | ||||
|       certain signed expressions in port connections | ||||
|     - Fixed an issue that prevented writing to a memory word via a concatenation | ||||
|       in an output port connection | ||||
| 
 | ||||
| Yosys 0.56 .. Yosys 0.57 | ||||
| -------------------------- | ||||
|  |  | |||
|  | @ -2121,11 +2121,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) | |||
| 						if (sig.is_wire()) { | ||||
| 							// if the resulting SigSpec is a wire, its
 | ||||
| 							// signedness should match that of the AstNode
 | ||||
| 							if (arg->type == AST_IDENTIFIER && arg->id2ast && arg->id2ast->is_signed && !arg->is_signed) | ||||
| 								// fully-sliced signed wire will be resolved
 | ||||
| 								// once the module becomes available
 | ||||
| 								log_assert(attributes.count(ID::reprocess_after)); | ||||
| 							else | ||||
| 							// unless this instantiation depends on module
 | ||||
| 							// information that isn't available yet
 | ||||
| 							if (!attributes.count(ID::reprocess_after)) | ||||
| 								log_assert(arg->is_signed == sig.as_wire()->is_signed); | ||||
| 						} else if (arg->is_signed) { | ||||
| 							// non-trivial signed nodes are indirected through
 | ||||
|  |  | |||
|  | @ -1332,6 +1332,12 @@ bool AstNode::simplify(bool const_fold, int stage, int width_hint, bool sign_hin | |||
| 				else if (contains_unbased_unsized(value.get())) | ||||
| 					// unbased unsized literals extend to width of the context
 | ||||
| 					lookup_suggested = true; | ||||
| 				else if (value->type == AST_TO_UNSIGNED) | ||||
| 					// inner expression may be signed by default
 | ||||
| 					lookup_suggested = true; | ||||
| 				else if (value->type == AST_CONCAT && value->children.size() == 1) | ||||
| 					// concat of a single expression is equivalent to $unsigned
 | ||||
| 					lookup_suggested = true; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -5,9 +5,11 @@ module producer( | |||
| endmodule | ||||
| 
 | ||||
| module top( | ||||
|     output logic [3:0] out | ||||
|     output logic [3:0] out0, out1 | ||||
| ); | ||||
|     logic [3:0] v[0:0]; | ||||
|     producer p(v[0]); | ||||
|     assign out = v[0]; | ||||
|     logic [3:0] v[1:0]; | ||||
|     producer p0(v[0]); | ||||
|     producer p1({v[1]}); | ||||
|     assign out0 = v[0]; | ||||
|     assign out1 = v[1]; | ||||
| endmodule | ||||
|  |  | |||
							
								
								
									
										45
									
								
								tests/verilog/signed_concat.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								tests/verilog/signed_concat.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| `define OUTPUTS(mode) \ | ||||
|     o``mode``0, \ | ||||
|     o``mode``1, \ | ||||
|     o``mode``2, \ | ||||
|     o``mode``3, \ | ||||
|     o``mode``4 | ||||
| 
 | ||||
| module gate( | ||||
|     input [1:0] iu, | ||||
|     input signed [1:0] is, | ||||
|     output [2:0] `OUTPUTS(u), | ||||
|     output signed [2:0] `OUTPUTS(s) | ||||
| ); | ||||
| `define INSTANCES(mode) \ | ||||
|     mod m``mode``0({i``mode}, {o``mode``0}); \ | ||||
|     mod m``mode``1($unsigned(i``mode), o``mode``1); \ | ||||
|     mod m``mode``2({i``mode[1:0]}, o``mode``2); \ | ||||
|     mod m``mode``3({$signed(i``mode)}, o``mode``3); \ | ||||
|     mod m``mode``4($unsigned({i``mode}), o``mode``4); | ||||
| `INSTANCES(u) | ||||
| `INSTANCES(s) | ||||
| `undef INSTANCES | ||||
| endmodule | ||||
| 
 | ||||
| module gold( | ||||
|     input [1:0] iu, is, | ||||
|     output [2:0] `OUTPUTS(u), `OUTPUTS(s) | ||||
| ); | ||||
| `define INSTANCES(mode) \ | ||||
|     assign o``mode``0 = i``mode; \ | ||||
|     assign o``mode``1 = i``mode; \ | ||||
|     assign o``mode``2 = i``mode; \ | ||||
|     assign o``mode``3 = i``mode; \ | ||||
|     assign o``mode``4 = i``mode; | ||||
| `INSTANCES(u) | ||||
| `INSTANCES(s) | ||||
| `undef INSTANCES | ||||
| endmodule | ||||
| 
 | ||||
| module mod( | ||||
|     input [2:0] inp, | ||||
|     output [2:0] out | ||||
| ); | ||||
|     assign out = inp; | ||||
| endmodule | ||||
							
								
								
									
										7
									
								
								tests/verilog/signed_concat.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								tests/verilog/signed_concat.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| read_verilog signed_concat.v | ||||
| hierarchy | ||||
| proc | ||||
| flatten gate | ||||
| equiv_make gold gate equiv | ||||
| equiv_simple | ||||
| equiv_status -assert | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue