mirror of https://github.com/YosysHQ/yosys.git
Another bugfix in mem2reg code
This commit is contained in:
parent
dbdd8927e7
commit
82a4a0230f
|
@ -220,7 +220,7 @@ namespace AST
|
||||||
void replace_ids(const std::string &prefix, const 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(dict<AstNode*, pool<std::string>> &mem2reg_places,
|
void mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg_places,
|
||||||
dict<AstNode*, uint32_t> &mem2reg_flags, dict<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
|
dict<AstNode*, uint32_t> &mem2reg_flags, dict<AstNode*, uint32_t> &proc_flags, uint32_t &status_flags);
|
||||||
bool mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block);
|
bool mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block);
|
||||||
bool mem2reg_check(pool<AstNode*> &mem2reg_set);
|
bool mem2reg_check(pool<AstNode*> &mem2reg_set);
|
||||||
void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);
|
void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes);
|
||||||
void meminfo(int &mem_width, int &mem_size, int &addr_bits);
|
void meminfo(int &mem_width, int &mem_size, int &addr_bits);
|
||||||
|
|
|
@ -540,6 +540,7 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
log_error("Found parameter declaration in block without label at at %s:%d!\n", ast->filename.c_str(), ast->linenum);
|
log_error("Found parameter declaration in block without label at at %s:%d!\n", ast->filename.c_str(), ast->linenum);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AST_NONE:
|
||||||
case AST_TCALL:
|
case AST_TCALL:
|
||||||
case AST_FOR:
|
case AST_FOR:
|
||||||
break;
|
break;
|
||||||
|
@ -810,6 +811,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
|
||||||
// simply ignore this nodes.
|
// simply ignore this nodes.
|
||||||
// they are either leftovers from simplify() or are referenced by other nodes
|
// they are either leftovers from simplify() or are referenced by other nodes
|
||||||
// and are only accessed here thru this references
|
// and are only accessed here thru this references
|
||||||
|
case AST_NONE:
|
||||||
case AST_TASK:
|
case AST_TASK:
|
||||||
case AST_FUNCTION:
|
case AST_FUNCTION:
|
||||||
case AST_DPI_FUNCTION:
|
case AST_DPI_FUNCTION:
|
||||||
|
|
|
@ -148,7 +148,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (mem2reg_as_needed_pass2(mem2reg_set, this, NULL)) { }
|
AstNode *async_block = NULL;
|
||||||
|
while (mem2reg_as_needed_pass2(mem2reg_set, this, NULL, async_block)) { }
|
||||||
|
|
||||||
vector<AstNode*> delnodes;
|
vector<AstNode*> delnodes;
|
||||||
mem2reg_remove(mem2reg_set, delnodes);
|
mem2reg_remove(mem2reg_set, delnodes);
|
||||||
|
@ -2707,15 +2708,36 @@ void AstNode::mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &deln
|
||||||
}
|
}
|
||||||
|
|
||||||
// actually replace memories with registers
|
// actually replace memories with registers
|
||||||
bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block)
|
bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, AstNode *block, AstNode *&async_block)
|
||||||
{
|
{
|
||||||
bool did_something = false;
|
bool did_something = false;
|
||||||
|
|
||||||
if (type == AST_BLOCK)
|
if (type == AST_BLOCK)
|
||||||
block = this;
|
block = this;
|
||||||
|
|
||||||
if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && block != NULL &&
|
if (type == AST_FUNCTION || type == AST_TASK)
|
||||||
children[0]->mem2reg_check(mem2reg_set) && children[0]->children[0]->children[0]->type != AST_CONSTANT)
|
return false;
|
||||||
|
|
||||||
|
if (type == AST_ASSIGN && block == NULL && children[0]->mem2reg_check(mem2reg_set))
|
||||||
|
{
|
||||||
|
if (async_block == NULL) {
|
||||||
|
async_block = new AstNode(AST_ALWAYS, new AstNode(AST_BLOCK));
|
||||||
|
mod->children.push_back(async_block);
|
||||||
|
}
|
||||||
|
|
||||||
|
AstNode *newNode = clone();
|
||||||
|
newNode->type = AST_ASSIGN_EQ;
|
||||||
|
async_block->children[0]->children.push_back(newNode);
|
||||||
|
|
||||||
|
newNode = new AstNode(AST_NONE);
|
||||||
|
newNode->cloneInto(this);
|
||||||
|
delete newNode;
|
||||||
|
|
||||||
|
did_something = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ) && children[0]->mem2reg_check(mem2reg_set) &&
|
||||||
|
children[0]->children[0]->children[0]->type != AST_CONSTANT)
|
||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
|
sstr << "$mem2reg_wr$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
|
||||||
|
@ -2791,7 +2813,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::stringstream sstr;
|
std::stringstream sstr;
|
||||||
sstr << "$mem2reg_rd$" << children[0]->str << "$" << filename << ":" << linenum << "$" << (autoidx++);
|
sstr << "$mem2reg_rd$" << str << "$" << filename << ":" << linenum << "$" << (autoidx++);
|
||||||
std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
|
std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
|
||||||
|
|
||||||
int mem_width, mem_size, addr_bits;
|
int mem_width, mem_size, addr_bits;
|
||||||
|
@ -2871,7 +2893,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
|
||||||
|
|
||||||
auto children_list = children;
|
auto children_list = children;
|
||||||
for (size_t i = 0; i < children_list.size(); i++)
|
for (size_t i = 0; i < children_list.size(); i++)
|
||||||
if (children_list[i]->mem2reg_as_needed_pass2(mem2reg_set, mod, block))
|
if (children_list[i]->mem2reg_as_needed_pass2(mem2reg_set, mod, block, async_block))
|
||||||
did_something = true;
|
did_something = true;
|
||||||
|
|
||||||
return did_something;
|
return did_something;
|
||||||
|
|
|
@ -59,3 +59,25 @@ always @(posedge clk)
|
||||||
assign dout_b = dint_c[3];
|
assign dout_b = dint_c[3];
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
// ------------------------------------------------------
|
||||||
|
|
||||||
|
module mem2reg_test4(result1, result2, result3);
|
||||||
|
output signed [9:0] result1;
|
||||||
|
output signed [9:0] result2;
|
||||||
|
output signed [9:0] result3;
|
||||||
|
|
||||||
|
wire signed [9:0] intermediate [0:3];
|
||||||
|
|
||||||
|
function integer depth2Index;
|
||||||
|
input integer depth;
|
||||||
|
depth2Index = depth;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
assign intermediate[depth2Index(1)] = 1;
|
||||||
|
assign intermediate[depth2Index(2)] = 2;
|
||||||
|
assign intermediate[3] = 3;
|
||||||
|
assign result1 = intermediate[1];
|
||||||
|
assign result2 = intermediate[depth2Index(2)];
|
||||||
|
assign result3 = intermediate[depth2Index(3)];
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue