mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Fix access to whole sub-structs (#3086)
* Add support for accessing whole struct * Update tests Signed-off-by: Kamil Rakoczy <krakoczy@antmicro.com>
This commit is contained in:
		
							parent
							
								
									59738c09be
								
							
						
					
					
						commit
						68c67c40ec
					
				
					 7 changed files with 72 additions and 11 deletions
				
			
		|  | @ -877,7 +877,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun | |||
| 			this_width = id_ast->children[0]->range_left - id_ast->children[0]->range_right + 1; | ||||
| 			if (children.size() > 1) | ||||
| 				range = children[1]; | ||||
| 		} else if (id_ast->type == AST_STRUCT_ITEM) { | ||||
| 		} else if (id_ast->type == AST_STRUCT_ITEM || id_ast->type == AST_STRUCT) { | ||||
| 			AstNode *tmp_range = make_struct_member_range(this, id_ast); | ||||
| 			this_width = tmp_range->range_left - tmp_range->range_right + 1; | ||||
| 			delete tmp_range; | ||||
|  |  | |||
|  | @ -307,6 +307,10 @@ static int size_packed_struct(AstNode *snode, int base_offset) | |||
| 		if (node->type == AST_STRUCT || node->type == AST_UNION) { | ||||
| 			// embedded struct or union
 | ||||
| 			width = size_packed_struct(node, base_offset + offset); | ||||
| 			// set range of struct
 | ||||
| 			node->range_right = base_offset + offset; | ||||
| 			node->range_left = base_offset + offset + width - 1; | ||||
| 			node->range_valid = true; | ||||
| 		} | ||||
| 		else { | ||||
| 			log_assert(node->type == AST_STRUCT_ITEM); | ||||
|  | @ -493,14 +497,12 @@ static void add_members_to_scope(AstNode *snode, std::string name) | |||
| 	// in case later referenced in assignments
 | ||||
| 	log_assert(snode->type==AST_STRUCT || snode->type==AST_UNION); | ||||
| 	for (auto *node : snode->children) { | ||||
| 		auto member_name = name + "." + node->str; | ||||
| 		current_scope[member_name] = node; | ||||
| 		if (node->type != AST_STRUCT_ITEM) { | ||||
| 			// embedded struct or union
 | ||||
| 			add_members_to_scope(node, name + "." + node->str); | ||||
| 		} | ||||
| 		else { | ||||
| 			auto member_name = name + "." + node->str; | ||||
| 			current_scope[member_name] = node; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -1341,6 +1343,16 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 
 | ||||
| 	case AST_PARAMETER: | ||||
| 	case AST_LOCALPARAM: | ||||
| 		// if parameter is implicit type which is the typename of a struct or union,
 | ||||
| 		// save information about struct in wiretype attribute
 | ||||
| 		if (children[0]->type == AST_IDENTIFIER && current_scope.count(children[0]->str) > 0) { | ||||
| 			auto item_node = current_scope[children[0]->str]; | ||||
| 			if (item_node->type == AST_STRUCT || item_node->type == AST_UNION) { | ||||
| 				attributes[ID::wiretype] = item_node->clone(); | ||||
| 				size_packed_struct(attributes[ID::wiretype], 0); | ||||
| 				add_members_to_scope(attributes[ID::wiretype], str); | ||||
| 			} | ||||
| 		} | ||||
| 		while (!children[0]->basic_prep && children[0]->simplify(false, false, false, stage, -1, false, true) == true) | ||||
| 			did_something = true; | ||||
| 		children[0]->detectSignWidth(width_hint, sign_hint); | ||||
|  | @ -2018,7 +2030,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		if (name_has_dot(str, sname)) { | ||||
| 			if (current_scope.count(str) > 0) { | ||||
| 				auto item_node = current_scope[str]; | ||||
| 				if (item_node->type == AST_STRUCT_ITEM) { | ||||
| 				if (item_node->type == AST_STRUCT_ITEM || item_node->type == AST_STRUCT) { | ||||
| 					// structure member, rewrite this node to reference the packed struct wire
 | ||||
| 					auto range = make_struct_member_range(this, item_node); | ||||
| 					newNode = new AstNode(AST_IDENTIFIER, range); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue