Added support for local regs in named blocks
authorClifford Wolf <clifford@clifford.at>
Wed, 4 Dec 2013 08:10:16 +0000 (09:10 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 4 Dec 2013 08:10:16 +0000 (09:10 +0100)
frontends/ast/genrtlil.cc
frontends/ast/simplify.cc
frontends/verilog/parser.y

index 1453d13a95c4a83c99cc44f96aabf3828b654b66..e9c689ac231cbad74702d70cc5c4438ef93311a6 100644 (file)
@@ -576,6 +576,10 @@ struct AST_INTERNAL::ProcessGenerator
                        }
                        break;
 
+               case AST_WIRE:
+                       log_error("Found wire declaration in block without label at at %s:%d!\n", ast->filename.c_str(), ast->linenum);
+                       break;
+
                case AST_TCALL:
                case AST_FOR:
                        break;
index 80cf230e6a9361c8ff2258494339b4eaedfb7e40..0a32e950656859547bc2b6e856beb828bd6d1026 100644 (file)
@@ -350,6 +350,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                        break;
                if (type == AST_GENBLOCK)
                        break;
+               if (type == AST_BLOCK && !str.empty())
+                       break;
                if (type == AST_PREFIX && i >= 1)
                        break;
                while (did_something_here && i < children.size()) {
@@ -678,6 +680,25 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
                did_something = true;
        }
 
+       // transform block with name
+       if (type == AST_BLOCK && !str.empty())
+       {
+               std::map<std::string, std::string> name_map;
+               expand_genblock(std::string(), str + ".", name_map);
+
+               std::vector<AstNode*> new_children;
+               for (size_t i = 0; i < children.size(); i++)
+                       if (children[i]->type == AST_WIRE) {
+                               children[i]->simplify(false, false, false, stage, -1, false);
+                               current_ast_mod->children.push_back(children[i]);
+                       } else
+                               new_children.push_back(children[i]);
+
+               children.swap(new_children);
+               did_something = true;
+               str.clear();
+       }
+
        // simplify unconditional generate block
        if (type == AST_GENBLOCK && children.size() != 0)
        {
index 1ffa4e942844e864ba184495fbc7f835709e51cc..5a45a776166aed9a1c2d2a6f1a8d4222fa534587 100644 (file)
@@ -407,7 +407,6 @@ opt_signed:
        };
 
 task_func_body:
-       task_func_body wire_decl |
        task_func_body behavioral_stmt |
        /* empty */;
 
@@ -761,7 +760,7 @@ simple_behavioral_stmt:
 
 // this production creates the obligatory if-else shift/reduce conflict
 behavioral_stmt:
-       defattr |
+       defattr | wire_decl |
        simple_behavioral_stmt ';' |
        hierarchical_id attr {
                AstNode *node = new AstNode(AST_TCALL);
@@ -778,7 +777,11 @@ behavioral_stmt:
                ast_stack.back()->children.push_back(node);
                ast_stack.push_back(node);
                append_attr(node, $1);
+               if ($3 != NULL)
+                       node->str = *$3;
        } behavioral_stmt_list TOK_END opt_label {
+               if ($3 != NULL && $7 != NULL && *$3 != *$7)
+                       frontend_verilog_yyerror("Syntax error.");
                if ($3 != NULL)
                        delete $3;
                if ($7 != NULL)