Added support for global tasks and functions
authorClifford Wolf <clifford@clifford.at>
Thu, 21 Aug 2014 10:42:28 +0000 (12:42 +0200)
committerClifford Wolf <clifford@clifford.at>
Thu, 21 Aug 2014 10:42:28 +0000 (12:42 +0200)
frontends/ast/ast.cc
frontends/verilog/parser.y
frontends/verilog/verilog_frontend.cc

index 0ea38b50628ec87492548400711dbabf5504bc24..d59ff1bb640b3f9c084e2bcbf1f51ba3bdb3207d 100644 (file)
@@ -945,21 +945,35 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump
        flag_icells = icells;
        flag_autowire = autowire;
 
+       std::vector<AstNode*> global_decls;
+
        log_assert(current_ast->type == AST_DESIGN);
-       for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++) {
-               if (flag_icells && (*it)->str.substr(0, 2) == "\\$")
-                       (*it)->str = (*it)->str.substr(1);
-               if (defer)
-                       (*it)->str = "$abstract" + (*it)->str;
-               if (design->has((*it)->str)) {
-                       if (!ignore_redef)
-                               log_error("Re-definition of module `%s' at %s:%d!\n",
+       for (auto it = current_ast->children.begin(); it != current_ast->children.end(); it++)
+       {
+               if ((*it)->type == AST_MODULE)
+               {
+                       for (auto n : global_decls)
+                               (*it)->children.push_back(n->clone());
+
+                       if (flag_icells && (*it)->str.substr(0, 2) == "\\$")
+                               (*it)->str = (*it)->str.substr(1);
+
+                       if (defer)
+                               (*it)->str = "$abstract" + (*it)->str;
+
+                       if (design->has((*it)->str)) {
+                               if (!ignore_redef)
+                                       log_error("Re-definition of module `%s' at %s:%d!\n",
+                                                       (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
+                               log("Ignoring re-definition of module `%s' at %s:%d!\n",
                                                (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
-                       log("Ignoring re-definition of module `%s' at %s:%d!\n",
-                                       (*it)->str.c_str(), (*it)->filename.c_str(), (*it)->linenum);
-                       continue;
+                               continue;
+                       }
+
+                       design->add(process_module(*it, defer));
                }
-               design->add(process_module(*it, defer));
+               else
+                       global_decls.push_back(*it);
        }
 }
 
index bf9b21bb647668aa1d334ffa50a6095dba6db649..acd904e55d985667e73f25ca6c2f6ec44a6179ee 100644 (file)
@@ -137,14 +137,21 @@ static void free_attr(std::map<std::string, AstNode*> *al)
 
 %%
 
-input:
-       module input |
-       defattr input |
-       /* empty */ {
-               for (auto &it : default_attr_list)
-                       delete it.second;
-               default_attr_list.clear();
-       };
+input: {
+       ast_stack.push_back(current_ast);
+} design {
+       ast_stack.pop_back();
+       log_assert(SIZE(ast_stack) == 0);
+       for (auto &it : default_attr_list)
+               delete it.second;
+       default_attr_list.clear();
+};
+
+design:
+       module design |
+       defattr design |
+       task_func_decl design |
+       /* empty */;
 
 attr:
        {
@@ -214,9 +221,9 @@ module:
        attr TOK_MODULE TOK_ID {
                do_not_require_port_stubs = false;
                AstNode *mod = new AstNode(AST_MODULE);
-               current_ast->children.push_back(mod);
-               current_ast_mod = mod;
+               ast_stack.back()->children.push_back(mod);
                ast_stack.push_back(mod);
+               current_ast_mod = mod;
                port_stubs.clear();
                port_counter = 0;
                mod->str = *$3;
@@ -227,7 +234,8 @@ module:
                        frontend_verilog_yyerror("Missing details for module port `%s'.",
                                        port_stubs.begin()->first.c_str());
                ast_stack.pop_back();
-               log_assert(ast_stack.size() == 0);
+               log_assert(ast_stack.size() == 1);
+               current_ast_mod = NULL;
        };
 
 module_para_opt:
index 4466e1cb6eb7b8f465029d870167202ab77e1c0f..19578908665ff1a655c82aaa4fa637d26932df82 100644 (file)
@@ -285,10 +285,10 @@ struct VerilogFrontend : public Frontend {
                frontend_verilog_yylex_destroy();
 
                for (auto &child : current_ast->children) {
-                       log_assert(child->type == AST::AST_MODULE);
-                       for (auto &attr : attributes)
-                               if (child->attributes.count(attr) == 0)
-                                       child->attributes[attr] = AST::AstNode::mkconst_int(1, false);
+                       if (child->type == AST::AST_MODULE)
+                               for (auto &attr : attributes)
+                                       if (child->attributes.count(attr) == 0)
+                                               child->attributes[attr] = AST::AstNode::mkconst_int(1, false);
                }
 
                AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire);