summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontends/ast/ast.h2
-rw-r--r--frontends/ast/simplify.cc31
-rw-r--r--frontends/verilog/parser.y3
-rw-r--r--tests/simple/scopes.v63
4 files changed, 90 insertions, 9 deletions
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 83798edf..00b044bc 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -200,7 +200,7 @@ namespace AST
// it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL()
bool simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, int width_hint, bool sign_hint, bool in_param);
void expand_genblock(std::string index_var, std::string prefix, std::map<std::string, std::string> &name_map);
- void replace_ids(std::map<std::string, std::string> &rules);
+ void replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules);
void mem2reg_as_needed_pass1(std::map<AstNode*, std::set<std::string>> &mem2reg_places,
std::map<AstNode*, uint32_t> &mem2reg_flags, std::map<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
void mem2reg_as_needed_pass2(std::set<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block);
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 20edc173..29d00be9 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -794,6 +794,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (children[i]->type == AST_WIRE) {
children[i]->simplify(false, false, false, stage, -1, false, false);
current_ast_mod->children.push_back(children[i]);
+ current_scope[children[i]->str] = children[i];
} else
new_children.push_back(children[i]);
@@ -1492,7 +1493,7 @@ skip_dynamic_range_lvalue_expansion:;
if (child->type != AST_WIRE)
{
AstNode *stmt = child->clone();
- stmt->replace_ids(replace_rules);
+ stmt->replace_ids(prefix, replace_rules);
for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
if (*it != current_block_child)
@@ -1855,12 +1856,30 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
}
// rename stuff (used when tasks of functions are instanciated)
-void AstNode::replace_ids(std::map<std::string, std::string> &rules)
+void AstNode::replace_ids(const std::string &prefix, const std::map<std::string, std::string> &rules)
{
- if (type == AST_IDENTIFIER && rules.count(str) > 0)
- str = rules[str];
- for (auto child : children)
- child->replace_ids(rules);
+ if (type == AST_BLOCK)
+ {
+ std::map<std::string, std::string> new_rules = rules;
+ std::string new_prefix = prefix + str;
+
+ for (auto child : children)
+ if (child->type == AST_WIRE) {
+ new_rules[child->str] = new_prefix + child->str;
+ child->str = new_prefix + child->str;
+ }
+
+ for (auto child : children)
+ if (child->type != AST_WIRE)
+ child->replace_ids(new_prefix, new_rules);
+ }
+ else
+ {
+ if (type == AST_IDENTIFIER && rules.count(str) > 0)
+ str = rules.at(str);
+ for (auto child : children)
+ child->replace_ids(prefix, rules);
+ }
}
// helper function for mem2reg_as_needed_pass1
diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y
index 1e0168a5..26e2ddc3 100644
--- a/frontends/verilog/parser.y
+++ b/frontends/verilog/parser.y
@@ -599,12 +599,11 @@ wire_name:
if (node->is_input || node->is_output)
frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str());
}
- ast_stack.back()->children.push_back(node);
} else {
if (node->is_input || node->is_output)
node->port_id = current_function_or_task_port_id++;
- current_function_or_task->children.push_back(node);
}
+ ast_stack.back()->children.push_back(node);
delete $1;
};
diff --git a/tests/simple/scopes.v b/tests/simple/scopes.v
new file mode 100644
index 00000000..eecc1a0b
--- /dev/null
+++ b/tests/simple/scopes.v
@@ -0,0 +1,63 @@
+module scopes_test_01(input [3:0] k, output reg [15:0] x, y);
+ function [15:0] func_01;
+ input [15:0] x, y;
+ begin
+ func_01 = x + y;
+ begin:blk
+ reg [15:0] x;
+ x = y;
+ func_01 = func_01 ^ x;
+ end
+ func_01 = func_01 ^ x;
+ end
+ endfunction
+
+ function [15:0] func_02;
+ input [15:0] x, y;
+ begin
+ func_02 = x - y;
+ begin:blk
+ reg [15:0] func_02;
+ func_02 = 0;
+ end
+ end
+ endfunction
+
+ task task_01;
+ input [3:0] a;
+ reg [15:0] y;
+ begin
+ y = a * 23;
+ x = x + y;
+ end
+ endtask
+
+ task task_02;
+ input [3:0] a;
+ begin:foo
+ reg [15:0] x, z;
+ x = y;
+ begin:bar
+ reg [15:0] x;
+ x = 77 + a;
+ z = -x;
+ end
+ y = x ^ z;
+ end
+ endtask
+
+ always @* begin
+ x = func_01(11, 22);
+ y = func_02(33, 44);
+ task_01(k);
+ task_02(k);
+ begin:foo
+ reg [15:0] y;
+ y = x;
+ y = y + k;
+ x = y;
+ end
+ x = func_01(y, x);
+ y = func_02(y, x);
+ end
+endmodule