verilog: support module scope identifiers in parametric modules
authorZachary Snow <zach@zachjs.com>
Thu, 4 Mar 2021 19:07:56 +0000 (14:07 -0500)
committerZachary Snow <zachary.j.snow@gmail.com>
Tue, 16 Mar 2021 15:01:30 +0000 (11:01 -0400)
frontends/ast/simplify.cc
tests/simple/module_scope.v [new file with mode: 0644]

index d68b13b2a9aee5bd499dbc0abd5c3a3894dd173b..d9eae3a06128d9e6b5d9e6af0ca0d765ebe6193f 100644 (file)
@@ -1691,11 +1691,15 @@ 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;
-                       const std::string& mod_scope = current_scope_ast->str;
-                       if (str[0] == '\\' && str.substr(0, mod_scope.size()) == mod_scope) {
-                               std::string new_str = "\\" + str.substr(mod_scope.size() + 1);
+                       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)) {
-                                       str = 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;
                                }
                        }
                        for (auto node : current_scope_ast->children) {
diff --git a/tests/simple/module_scope.v b/tests/simple/module_scope.v
new file mode 100644 (file)
index 0000000..3e46b72
--- /dev/null
@@ -0,0 +1,29 @@
+`default_nettype none
+
+module Example(o1, o2);
+   parameter [31:0] v1 = 10;
+   parameter [31:0] v2 = 20;
+   output [31:0] o1, o2;
+   assign Example.o1 = Example.v1;
+   assign Example.o2 = Example.v2;
+endmodule
+
+module ExampleLong(o1, o2);
+   parameter [31:0] ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1 = 10;
+   parameter [31:0] ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2 = 20;
+   output [31:0] o1, o2;
+   assign ExampleLong.o1 = ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum1;
+   assign ExampleLong.o2 = ExampleLong.ThisIsAnExtremelyLongParameterNameToTriggerTheSHA1Checksum2;
+endmodule
+
+module top(
+   output [31:0] a1, a2, b1, b2, c1, c2,
+   output [31:0] d1, d2, e1, e2, f1, f2
+);
+   Example a(a1, a2);
+   Example #(1) b(b1, b2);
+   Example #(1, 2) c(c1, c2);
+   ExampleLong d(d1, d2);
+   ExampleLong #(1) e(e1, e2);
+   ExampleLong #(1, 2) f(f1, f2);
+endmodule