aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Snow <zach@zachjs.com>2021-06-05 16:21:09 -0400
committerZachary Snow <zachary.j.snow@gmail.com>2021-06-08 15:03:16 -0400
commit2e697f5655455fd8ce5fec40b94683a11ade24e8 (patch)
treec52389aa8feb3328e1a4c97bd5e3db303b187a96
parentc79fbfe0a130f1a2979413174c3e5688433bafe3 (diff)
downloadyosys-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().
-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