Added support for local regs in named blocks

This commit is contained in:
Clifford Wolf 2013-12-04 09:10:16 +01:00
parent b5afd75b0a
commit 507c63d112
3 changed files with 30 additions and 2 deletions

View 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;

View 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)
{

View 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)