ast: Fix handling of identifiers in the global scope
authorDavid Shah <dave@ds0.me>
Thu, 16 Apr 2020 09:27:59 +0000 (10:27 +0100)
committerDavid Shah <dave@ds0.me>
Thu, 16 Apr 2020 09:30:07 +0000 (10:30 +0100)
Signed-off-by: David Shah <dave@ds0.me>
frontends/ast/ast.cc
frontends/ast/simplify.cc
tests/various/global_scope.ys [new file with mode: 0644]

index 2b60025488bf4c67aa40d8cc832e2f3878f3c37d..245a53611ac578d141b93ec22f4363438640e228 100644 (file)
@@ -1153,6 +1153,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
                bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire)
 {
        current_ast = ast;
+       current_ast_mod = nullptr;
        flag_dump_ast1 = dump_ast1;
        flag_dump_ast2 = dump_ast2;
        flag_no_dump_ptr = no_dump_ptr;
@@ -1219,6 +1220,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
                        }
 
                        design->add(process_module(*it, defer));
+                       current_ast_mod = nullptr;
                }
                else if ((*it)->type == AST_PACKAGE) {
                        // process enum/other declarations
index cb89f58baf0169d5f958db53902061fc331f4873..372dcf95c59575c79bd547139352d788700ec974 100644 (file)
@@ -1169,7 +1169,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
        // annotate identifiers using scope resolution and create auto-wires as needed
        if (type == AST_IDENTIFIER) {
                if (current_scope.count(str) == 0) {
-                       for (auto node : current_ast_mod->children) {
+                       AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod;
+                       for (auto node : current_scope_ast->children) {
                                //log("looking at mod scope child %s\n", type2str(node->type).c_str());
                                switch (node->type) {
                                case AST_PARAMETER:
@@ -1203,7 +1204,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                        }
                }
                if (current_scope.count(str) == 0) {
-                       if (flag_autowire || str == "\\$global_clock") {
+                       if (current_ast_mod == nullptr) {
+                               log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared outside of a module.\n", str.c_str());
+                       } else if (flag_autowire || str == "\\$global_clock") {
                                AstNode *auto_wire = new AstNode(AST_AUTOWIRE);
                                auto_wire->str = str;
                                current_ast_mod->children.push_back(auto_wire);
diff --git a/tests/various/global_scope.ys b/tests/various/global_scope.ys
new file mode 100644 (file)
index 0000000..8c8618e
--- /dev/null
@@ -0,0 +1,18 @@
+read_verilog -sv <<EOT
+parameter A = 10;
+parameter B = A;
+
+typedef enum {
+       CONST_A = A,
+       CONST_B = A+1
+} enum_t;
+
+module top(output [3:0] q, output [3:0] r);
+assign q = 10;
+assign r = CONST_B;
+endmodule
+EOT
+
+hierarchy -top top
+sat -verify -prove q 10 top
+sat -verify -prove r 11 top