mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	sv: Add support for memory typedefs
Signed-off-by: David Shah <dave@ds0.me>
This commit is contained in:
		
							parent
							
								
									e70e4afb60
								
							
						
					
					
						commit
						30d2326030
					
				
					 3 changed files with 44 additions and 3 deletions
				
			
		|  | @ -785,8 +785,10 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | ||||||
| 	// resolve typedefs
 | 	// resolve typedefs
 | ||||||
| 	if (type == AST_TYPEDEF) { | 	if (type == AST_TYPEDEF) { | ||||||
| 		log_assert(children.size() == 1); | 		log_assert(children.size() == 1); | ||||||
| 		log_assert(children[0]->type == AST_WIRE); | 		log_assert(children[0]->type == AST_WIRE || children[0]->type == AST_MEMORY); | ||||||
| 		while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; | 		while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { | ||||||
|  | 			did_something = true; | ||||||
|  | 		}; | ||||||
| 		log_assert(!children[0]->is_custom_type); | 		log_assert(!children[0]->is_custom_type); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -807,6 +809,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | ||||||
| 			// Ensure typedef itself is fully simplified
 | 			// Ensure typedef itself is fully simplified
 | ||||||
| 			while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; | 			while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; | ||||||
| 
 | 
 | ||||||
|  | 			type = templ->type; | ||||||
| 			is_reg = templ->is_reg; | 			is_reg = templ->is_reg; | ||||||
| 			is_logic = templ->is_logic; | 			is_logic = templ->is_logic; | ||||||
| 			is_signed = templ->is_signed; | 			is_signed = templ->is_signed; | ||||||
|  | @ -819,6 +822,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | ||||||
| 			range_right = templ->range_right; | 			range_right = templ->range_right; | ||||||
| 			for (auto template_child : templ->children) | 			for (auto template_child : templ->children) | ||||||
| 				children.push_back(template_child->clone()); | 				children.push_back(template_child->clone()); | ||||||
|  | 			did_something = true; | ||||||
| 		} | 		} | ||||||
| 		log_assert(!is_custom_type); | 		log_assert(!is_custom_type); | ||||||
| 	} | 	} | ||||||
|  | @ -841,6 +845,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | ||||||
| 			// Ensure typedef itself is fully simplified
 | 			// Ensure typedef itself is fully simplified
 | ||||||
| 			while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; | 			while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {}; | ||||||
| 
 | 
 | ||||||
|  | 			if (templ->type == AST_MEMORY) | ||||||
|  | 				log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str()); | ||||||
| 			is_signed = templ->is_signed; | 			is_signed = templ->is_signed; | ||||||
| 			is_string = templ->is_string; | 			is_string = templ->is_string; | ||||||
| 			is_custom_type = templ->is_custom_type; | 			is_custom_type = templ->is_custom_type; | ||||||
|  | @ -851,6 +857,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | ||||||
| 			range_right = templ->range_right; | 			range_right = templ->range_right; | ||||||
| 			for (auto template_child : templ->children) | 			for (auto template_child : templ->children) | ||||||
| 				children.push_back(template_child->clone()); | 				children.push_back(template_child->clone()); | ||||||
|  | 			did_something = true; | ||||||
| 		} | 		} | ||||||
| 		log_assert(!is_custom_type); | 		log_assert(!is_custom_type); | ||||||
| 	}	 | 	}	 | ||||||
|  | @ -3074,6 +3081,9 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg | ||||||
| 	uint32_t children_flags = 0; | 	uint32_t children_flags = 0; | ||||||
| 	int lhs_children_counter = 0; | 	int lhs_children_counter = 0; | ||||||
| 
 | 
 | ||||||
|  | 	if (type == AST_TYPEDEF) | ||||||
|  | 		return; // don't touch content of typedefs
 | ||||||
|  | 
 | ||||||
| 	if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) | 	if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) | ||||||
| 	{ | 	{ | ||||||
| 		// mark all memories that are used in a complex expression on the left side of an assignment
 | 		// mark all memories that are used in a complex expression on the left side of an assignment
 | ||||||
|  | @ -3231,6 +3241,9 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, | ||||||
| 	if (type == AST_FUNCTION || type == AST_TASK) | 	if (type == AST_FUNCTION || type == AST_TASK) | ||||||
| 		return false; | 		return false; | ||||||
| 
 | 
 | ||||||
|  | 	if (type == AST_TYPEDEF) | ||||||
|  | 		return false; | ||||||
|  | 
 | ||||||
| 	if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast)) | 	if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast)) | ||||||
| 	{ | 	{ | ||||||
| 		log_assert(children[0]->type == AST_CONSTANT); | 		log_assert(children[0]->type == AST_CONSTANT); | ||||||
|  |  | ||||||
|  | @ -1400,7 +1400,7 @@ assign_expr: | ||||||
| 	}; | 	}; | ||||||
| 
 | 
 | ||||||
| typedef_decl: | typedef_decl: | ||||||
| 	TOK_TYPEDEF wire_type range TOK_ID ';' { | 	TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' { | ||||||
| 		astbuf1 = $2; | 		astbuf1 = $2; | ||||||
| 		astbuf2 = $3; | 		astbuf2 = $3; | ||||||
| 		if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) { | 		if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) { | ||||||
|  | @ -1416,6 +1416,24 @@ typedef_decl: | ||||||
| 			frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]"); | 			frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]"); | ||||||
| 		if (astbuf2) | 		if (astbuf2) | ||||||
| 			astbuf1->children.push_back(astbuf2); | 			astbuf1->children.push_back(astbuf2); | ||||||
|  | 
 | ||||||
|  | 		if ($5 != NULL) { | ||||||
|  | 			if (!astbuf2) { | ||||||
|  | 				AstNode *rng = new AstNode(AST_RANGE); | ||||||
|  | 				rng->children.push_back(AstNode::mkconst_int(0, true)); | ||||||
|  | 				rng->children.push_back(AstNode::mkconst_int(0, true)); | ||||||
|  | 				astbuf1->children.push_back(rng); | ||||||
|  | 			} | ||||||
|  | 			astbuf1->type = AST_MEMORY; | ||||||
|  | 			auto *rangeNode = $5; | ||||||
|  | 			if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) { | ||||||
|  | 				// SV array size [n], rewrite as [n-1:0] | ||||||
|  | 				rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true)); | ||||||
|  | 				rangeNode->children.push_back(AstNode::mkconst_int(0, false)); | ||||||
|  | 			} | ||||||
|  | 			astbuf1->children.push_back(rangeNode); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1)); | 		ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1)); | ||||||
| 		ast_stack.back()->children.back()->str = *$4; | 		ast_stack.back()->children.back()->str = *$4; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								tests/svtypes/typedef_memory.sv
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								tests/svtypes/typedef_memory.sv
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,10 @@ | ||||||
|  | module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata); | ||||||
|  | 	typedef logic [3:0] ram16x4_t[0:15]; | ||||||
|  | 
 | ||||||
|  | 	ram16x4_t mem; | ||||||
|  | 
 | ||||||
|  | 	always @(posedge clk) begin | ||||||
|  | 		if (wen) mem[addr] <= wdata; | ||||||
|  | 		rdata <= mem[addr]; | ||||||
|  | 	end | ||||||
|  | endmodule | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue