mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Add autowires in genblk/for expension
Signed-off-by: Yannick Lamarre <yan.lamarre@gmail.com>
This commit is contained in:
		
							parent
							
								
									702e1f2467
								
							
						
					
					
						commit
						b56c4f8dc5
					
				
					 1 changed files with 88 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -4656,6 +4656,7 @@ void AstNode::expand_genblock(const std::string &prefix)
 | 
			
		|||
 | 
			
		||||
		switch (child->type) {
 | 
			
		||||
		case AST_WIRE:
 | 
			
		||||
		case AST_AUTOWIRE:
 | 
			
		||||
		case AST_MEMORY:
 | 
			
		||||
		case AST_STRUCT:
 | 
			
		||||
		case AST_UNION:
 | 
			
		||||
| 
						 | 
				
			
			@ -4684,6 +4685,93 @@ void AstNode::expand_genblock(const std::string &prefix)
 | 
			
		|||
			}
 | 
			
		||||
			break;
 | 
			
		||||
 | 
			
		||||
		case AST_IDENTIFIER:
 | 
			
		||||
			if (!child->str.empty() && prefix.size() > 0) {
 | 
			
		||||
				bool is_resolved = false;
 | 
			
		||||
				std::string identifier_str = child->str;
 | 
			
		||||
				if (current_ast_mod != nullptr && identifier_str.compare(0, current_ast_mod->str.size(), current_ast_mod->str) == 0) {
 | 
			
		||||
					if (identifier_str.at(current_ast_mod->str.size()) == '.') {
 | 
			
		||||
						identifier_str = '\\' + identifier_str.substr(current_ast_mod->str.size()+1, identifier_str.size());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				// search starting in the innermost scope and then stepping outward
 | 
			
		||||
				for (size_t ppos = prefix.size() - 1; ppos; --ppos) {
 | 
			
		||||
					if (prefix.at(ppos) != '.') continue;
 | 
			
		||||
 | 
			
		||||
					std::string new_prefix = prefix.substr(0, ppos + 1);
 | 
			
		||||
					auto attempt_resolve = [&new_prefix](const std::string &ident) -> std::string {
 | 
			
		||||
						std::string new_name = prefix_id(new_prefix, ident);
 | 
			
		||||
						if (current_scope.count(new_name))
 | 
			
		||||
							return new_name;
 | 
			
		||||
						return {};
 | 
			
		||||
					};
 | 
			
		||||
 | 
			
		||||
					// attempt to resolve the full identifier
 | 
			
		||||
					std::string resolved = attempt_resolve(identifier_str);
 | 
			
		||||
					if (!resolved.empty()) {
 | 
			
		||||
						is_resolved = true;
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
					// attempt to resolve hierarchical prefixes within the identifier,
 | 
			
		||||
					// as the prefix could refer to a local scope which exists but
 | 
			
		||||
					// hasn't yet been elaborated
 | 
			
		||||
					for (size_t spos = identifier_str.size() - 1; spos; --spos) {
 | 
			
		||||
						if (identifier_str.at(spos) != '.') continue;
 | 
			
		||||
						resolved = attempt_resolve(identifier_str.substr(0, spos));
 | 
			
		||||
						if (!resolved.empty()) {
 | 
			
		||||
							is_resolved = true;
 | 
			
		||||
							identifier_str = resolved + identifier_str.substr(spos);
 | 
			
		||||
							ppos = 1; // break outer loop
 | 
			
		||||
							break;
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
					if (current_scope.count(identifier_str) == 0) {
 | 
			
		||||
						AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod;
 | 
			
		||||
						for (auto& node : current_scope_ast->children) {
 | 
			
		||||
							switch (node->type) {
 | 
			
		||||
							case AST_PARAMETER:
 | 
			
		||||
							case AST_LOCALPARAM:
 | 
			
		||||
							case AST_WIRE:
 | 
			
		||||
							case AST_AUTOWIRE:
 | 
			
		||||
							case AST_GENVAR:
 | 
			
		||||
							case AST_MEMORY:
 | 
			
		||||
							case AST_FUNCTION:
 | 
			
		||||
							case AST_TASK:
 | 
			
		||||
							case AST_DPI_FUNCTION:
 | 
			
		||||
								if (prefix_id(new_prefix, identifier_str) == node->str) {
 | 
			
		||||
									is_resolved = true;
 | 
			
		||||
									current_scope[node->str] = node.get();
 | 
			
		||||
								}
 | 
			
		||||
								break;
 | 
			
		||||
							case AST_ENUM:
 | 
			
		||||
								current_scope[node->str] = node.get();
 | 
			
		||||
								for (auto& enum_node : node->children) {
 | 
			
		||||
									log_assert(enum_node->type==AST_ENUM_ITEM);
 | 
			
		||||
									if (prefix_id(new_prefix, identifier_str) == enum_node->str) {
 | 
			
		||||
										is_resolved = true;
 | 
			
		||||
										current_scope[enum_node->str] = enum_node.get();
 | 
			
		||||
									}
 | 
			
		||||
								}
 | 
			
		||||
								break;
 | 
			
		||||
							default:
 | 
			
		||||
								break;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if ((current_scope.count(identifier_str) == 0) && is_resolved == false) {
 | 
			
		||||
					if (current_ast_mod == nullptr) {
 | 
			
		||||
						input_error("Identifier `%s' is implicitly declared outside of a module.\n", child->str.c_str());
 | 
			
		||||
					} else if (flag_autowire || identifier_str == "\\$global_clock") {
 | 
			
		||||
						auto auto_wire = std::make_unique<AstNode>(child->location, AST_AUTOWIRE);
 | 
			
		||||
						auto_wire->str = identifier_str;
 | 
			
		||||
						children.push_back(std::move(auto_wire));
 | 
			
		||||
					} else {
 | 
			
		||||
						input_error("Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", identifier_str.c_str());
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue