aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--frontends/ast/ast.h3
-rw-r--r--frontends/ast/genrtlil.cc11
-rw-r--r--frontends/ast/simplify.cc29
-rw-r--r--tests/simple/module_scope_case.v11
4 files changed, 41 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
diff --git a/tests/simple/module_scope_case.v b/tests/simple/module_scope_case.v
new file mode 100644
index 000000000..1472b6912
--- /dev/null
+++ b/tests/simple/module_scope_case.v
@@ -0,0 +1,11 @@
+module top(
+ input wire x,
+ output reg y
+);
+ always @* begin
+ case (top.x)
+ 1: top.y = 0;
+ 0: top.y = 1;
+ endcase
+ end
+endmodule