From 91dd87e60b120119ee34a9961a7b5f33f340282e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 12:15:53 +0200 Subject: [PATCH] Improved scope resolution of local regs in Verilog+AST frontend --- frontends/ast/ast.h | 2 +- frontends/ast/simplify.cc | 31 +++++++++++++++---- frontends/verilog/parser.y | 3 +- tests/simple/scopes.v | 63 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 tests/simple/scopes.v diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 83798edf0..00b044bc4 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 &name_map); - void replace_ids(std::map &rules); + void replace_ids(const std::string &prefix, const std::map &rules); void mem2reg_as_needed_pass1(std::map> &mem2reg_places, std::map &mem2reg_flags, std::map &proc_flags, uint32_t &status_flags); void mem2reg_as_needed_pass2(std::set &mem2reg_set, AstNode *mod, AstNode *block); diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 20edc1739..29d00be96 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 &rules) +void AstNode::replace_ids(const std::string &prefix, const std::map &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 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 1e0168a5f..26e2ddc34 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 000000000..eecc1a0b2 --- /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 -- 2.30.2