diff options
author | Zachary Snow <zach@zachjs.com> | 2021-06-05 16:21:09 -0400 |
---|---|---|
committer | Zachary Snow <zachary.j.snow@gmail.com> | 2021-06-08 15:03:16 -0400 |
commit | 2e697f5655455fd8ce5fec40b94683a11ade24e8 (patch) | |
tree | c52389aa8feb3328e1a4c97bd5e3db303b187a96 /frontends/ast | |
parent | c79fbfe0a130f1a2979413174c3e5688433bafe3 (diff) | |
download | yosys-2e697f5655455fd8ce5fec40b94683a11ade24e8.tar.gz yosys-2e697f5655455fd8ce5fec40b94683a11ade24e8.tar.bz2 yosys-2e697f5655455fd8ce5fec40b94683a11ade24e8.zip |
verilog: check for module scope identifiers during width detection
The recent fix for case expression width detection causes the width of
the expressions to be queried before they are simplified. Because the
logic supporting module scope identifiers only existed in simplify,
looking them up would fail during width detection. This moves the logic
to a common helper used in both simplify() and detectSignWidthWorker().
Diffstat (limited to 'frontends/ast')
-rw-r--r-- | frontends/ast/ast.h | 3 | ||||
-rw-r--r-- | frontends/ast/genrtlil.cc | 11 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 29 |
3 files changed, 30 insertions, 13 deletions
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 9887d24ea..b6b15b738 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -326,6 +326,9 @@ namespace AST // helpers for locations std::string loc_string() const; + + // Helper for looking up identifiers which are prefixed with the current module name + std::string try_pop_module_prefix() const; }; // process an AST tree (ast must point to an AST_DESIGN node) and generate RTLIL code diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index b8b9f715e..e886844be 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -767,8 +767,15 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun case AST_IDENTIFIER: id_ast = id2ast; - if (id_ast == NULL && current_scope.count(str)) - id_ast = current_scope.at(str); + if (!id_ast) { + if (current_scope.count(str)) + id_ast = current_scope[str]; + else { + std::string alt = try_pop_module_prefix(); + if (current_scope.count(alt)) + id_ast = current_scope[alt]; + } + } if (!id_ast) log_file_error(filename, location.first_line, "Failed to resolve identifier %s for width detection!\n", str.c_str()); if (id_ast->type == AST_PARAMETER || id_ast->type == AST_LOCALPARAM || id_ast->type == AST_ENUM_ITEM) { diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 44b11da74..cd27a720a 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1698,17 +1698,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_IDENTIFIER) { if (current_scope.count(str) == 0) { AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; - size_t pos = str.find('.', 1); - if (str[0] == '\\' && pos != std::string::npos) { - std::string new_str = "\\" + str.substr(pos + 1); - if (current_scope.count(new_str)) { - std::string prefix = str.substr(0, pos); - auto it = current_scope_ast->attributes.find(ID::hdlname); - if ((it != current_scope_ast->attributes.end() && it->second->str == prefix) - || prefix == current_scope_ast->str) - str = new_str; - } - } + str = try_pop_module_prefix(); for (auto node : current_scope_ast->children) { //log("looking at mod scope child %s\n", type2str(node->type).c_str()); switch (node->type) { @@ -5124,4 +5114,21 @@ std::pair<AstNode*, AstNode*> AstNode::get_tern_choice() return {choice, not_choice}; } +std::string AstNode::try_pop_module_prefix() const +{ + AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; + size_t pos = str.find('.', 1); + if (str[0] == '\\' && pos != std::string::npos) { + std::string new_str = "\\" + str.substr(pos + 1); + if (current_scope.count(new_str)) { + std::string prefix = str.substr(0, pos); + auto it = current_scope_ast->attributes.find(ID::hdlname); + if ((it != current_scope_ast->attributes.end() && it->second->str == prefix) + || prefix == current_scope_ast->str) + return new_str; + } + } + return str; +} + YOSYS_NAMESPACE_END |