mirror of https://github.com/YosysHQ/yosys.git
Improved scope resolution of local regs in Verilog+AST frontend
This commit is contained in:
parent
0129d41efa
commit
91dd87e60b
|
@ -200,7 +200,7 @@ namespace AST
|
||||||
// it also sets the id2ast pointers so that identifier lookups are fast in genRTLIL()
|
// 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);
|
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 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,
|
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);
|
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);
|
void mem2reg_as_needed_pass2(std::set<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block);
|
||||||
|
|
|
@ -794,6 +794,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
if (children[i]->type == AST_WIRE) {
|
if (children[i]->type == AST_WIRE) {
|
||||||
children[i]->simplify(false, false, false, stage, -1, false, false);
|
children[i]->simplify(false, false, false, stage, -1, false, false);
|
||||||
current_ast_mod->children.push_back(children[i]);
|
current_ast_mod->children.push_back(children[i]);
|
||||||
|
current_scope[children[i]->str] = children[i];
|
||||||
} else
|
} else
|
||||||
new_children.push_back(children[i]);
|
new_children.push_back(children[i]);
|
||||||
|
|
||||||
|
@ -1492,7 +1493,7 @@ skip_dynamic_range_lvalue_expansion:;
|
||||||
if (child->type != AST_WIRE)
|
if (child->type != AST_WIRE)
|
||||||
{
|
{
|
||||||
AstNode *stmt = child->clone();
|
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++) {
|
for (auto it = current_block->children.begin(); it != current_block->children.end(); it++) {
|
||||||
if (*it != current_block_child)
|
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)
|
// 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)
|
if (type == AST_BLOCK)
|
||||||
str = rules[str];
|
{
|
||||||
for (auto child : children)
|
std::map<std::string, std::string> new_rules = rules;
|
||||||
child->replace_ids(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
|
// helper function for mem2reg_as_needed_pass1
|
||||||
|
|
|
@ -599,12 +599,11 @@ wire_name:
|
||||||
if (node->is_input || node->is_output)
|
if (node->is_input || node->is_output)
|
||||||
frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str());
|
frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str());
|
||||||
}
|
}
|
||||||
ast_stack.back()->children.push_back(node);
|
|
||||||
} else {
|
} else {
|
||||||
if (node->is_input || node->is_output)
|
if (node->is_input || node->is_output)
|
||||||
node->port_id = current_function_or_task_port_id++;
|
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;
|
delete $1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue