mirror of https://github.com/YosysHQ/yosys.git
Fixed handling of parameters and const functions in casex/casez pattern
This commit is contained in:
parent
f38ca3e18f
commit
5a09fa4553
|
@ -146,6 +146,8 @@ std::string AST::type2str(AstNodeType type)
|
||||||
X(AST_ASSIGN_LE)
|
X(AST_ASSIGN_LE)
|
||||||
X(AST_CASE)
|
X(AST_CASE)
|
||||||
X(AST_COND)
|
X(AST_COND)
|
||||||
|
X(AST_CONDX)
|
||||||
|
X(AST_CONDZ)
|
||||||
X(AST_DEFAULT)
|
X(AST_DEFAULT)
|
||||||
X(AST_FOR)
|
X(AST_FOR)
|
||||||
X(AST_WHILE)
|
X(AST_WHILE)
|
||||||
|
@ -501,7 +503,12 @@ void AstNode::dumpVlog(FILE *f, std::string indent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_CASE:
|
case AST_CASE:
|
||||||
fprintf(f, "%s" "case (", indent.c_str());
|
if (!children.empty() && children[0]->type == AST_CONDX)
|
||||||
|
fprintf(f, "%s" "casex (", indent.c_str());
|
||||||
|
else if (!children.empty() && children[0]->type == AST_CONDZ)
|
||||||
|
fprintf(f, "%s" "casez (", indent.c_str());
|
||||||
|
else
|
||||||
|
fprintf(f, "%s" "case (", indent.c_str());
|
||||||
children[0]->dumpVlog(f, "");
|
children[0]->dumpVlog(f, "");
|
||||||
fprintf(f, ")\n");
|
fprintf(f, ")\n");
|
||||||
for (size_t i = 1; i < children.size(); i++) {
|
for (size_t i = 1; i < children.size(); i++) {
|
||||||
|
@ -512,6 +519,8 @@ void AstNode::dumpVlog(FILE *f, std::string indent)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_COND:
|
case AST_COND:
|
||||||
|
case AST_CONDX:
|
||||||
|
case AST_CONDZ:
|
||||||
for (auto child : children) {
|
for (auto child : children) {
|
||||||
if (child->type == AST_BLOCK) {
|
if (child->type == AST_BLOCK) {
|
||||||
fprintf(f, ":\n");
|
fprintf(f, ":\n");
|
||||||
|
|
|
@ -122,6 +122,8 @@ namespace AST
|
||||||
AST_ASSIGN_LE,
|
AST_ASSIGN_LE,
|
||||||
AST_CASE,
|
AST_CASE,
|
||||||
AST_COND,
|
AST_COND,
|
||||||
|
AST_CONDX,
|
||||||
|
AST_CONDZ,
|
||||||
AST_DEFAULT,
|
AST_DEFAULT,
|
||||||
AST_FOR,
|
AST_FOR,
|
||||||
AST_WHILE,
|
AST_WHILE,
|
||||||
|
|
|
@ -338,12 +338,14 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
case AST_CASE:
|
case AST_CASE:
|
||||||
for (auto child : ast->children)
|
for (auto child : ast->children)
|
||||||
if (child != ast->children[0]) {
|
if (child != ast->children[0]) {
|
||||||
log_assert(child->type == AST_COND);
|
log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
|
||||||
collect_lvalues(reg, child, type_eq, type_le, false);
|
collect_lvalues(reg, child, type_eq, type_le, false);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_COND:
|
case AST_COND:
|
||||||
|
case AST_CONDX:
|
||||||
|
case AST_CONDZ:
|
||||||
case AST_ALWAYS:
|
case AST_ALWAYS:
|
||||||
case AST_INITIAL:
|
case AST_INITIAL:
|
||||||
for (auto child : ast->children)
|
for (auto child : ast->children)
|
||||||
|
@ -467,7 +469,7 @@ struct AST_INTERNAL::ProcessGenerator
|
||||||
{
|
{
|
||||||
if (child == ast->children[0])
|
if (child == ast->children[0])
|
||||||
continue;
|
continue;
|
||||||
log_assert(child->type == AST_COND);
|
log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
|
||||||
|
|
||||||
subst_lvalue_map.save();
|
subst_lvalue_map.save();
|
||||||
subst_rvalue_map.save();
|
subst_rvalue_map.save();
|
||||||
|
|
|
@ -540,6 +540,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type == AST_CONDX && children.size() > 0 && children.at(0)->type == AST_CONSTANT) {
|
||||||
|
for (auto &bit : children.at(0)->bits)
|
||||||
|
if (bit == State::Sz || bit == State::Sx)
|
||||||
|
bit = State::Sa;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == AST_CONDZ && children.size() > 0 && children.at(0)->type == AST_CONSTANT) {
|
||||||
|
for (auto &bit : children.at(0)->bits)
|
||||||
|
if (bit == State::Sz)
|
||||||
|
bit = State::Sa;
|
||||||
|
}
|
||||||
|
|
||||||
if (const_fold && type == AST_CASE)
|
if (const_fold && type == AST_CASE)
|
||||||
{
|
{
|
||||||
while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
|
while (children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
|
||||||
|
@ -548,7 +560,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
new_children.push_back(children[0]);
|
new_children.push_back(children[0]);
|
||||||
for (int i = 1; i < GetSize(children); i++) {
|
for (int i = 1; i < GetSize(children); i++) {
|
||||||
AstNode *child = children[i];
|
AstNode *child = children[i];
|
||||||
log_assert(child->type == AST_COND);
|
log_assert(child->type == AST_COND || child->type == AST_CONDX || child->type == AST_CONDZ);
|
||||||
for (auto v : child->children) {
|
for (auto v : child->children) {
|
||||||
if (v->type == AST_DEFAULT)
|
if (v->type == AST_DEFAULT)
|
||||||
goto keep_const_cond;
|
goto keep_const_cond;
|
||||||
|
@ -1125,7 +1137,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
|
||||||
AstNode *selected_case = NULL;
|
AstNode *selected_case = NULL;
|
||||||
for (size_t i = 1; i < children.size(); i++)
|
for (size_t i = 1; i < children.size(); i++)
|
||||||
{
|
{
|
||||||
log_assert(children.at(i)->type == AST_COND);
|
log_assert(children.at(i)->type == AST_COND || children.at(i)->type == AST_CONDX || children.at(i)->type == AST_CONDZ);
|
||||||
|
|
||||||
AstNode *this_genblock = NULL;
|
AstNode *this_genblock = NULL;
|
||||||
for (auto child : children.at(i)->children) {
|
for (auto child : children.at(i)->children) {
|
||||||
|
@ -2984,7 +2996,7 @@ AstNode *AstNode::eval_const_function(AstNode *fcall)
|
||||||
for (size_t i = 1; i < stmt->children.size(); i++)
|
for (size_t i = 1; i < stmt->children.size(); i++)
|
||||||
{
|
{
|
||||||
bool found_match = false;
|
bool found_match = false;
|
||||||
log_assert(stmt->children.at(i)->type == AST_COND);
|
log_assert(stmt->children.at(i)->type == AST_COND || stmt->children.at(i)->type == AST_CONDX || stmt->children.at(i)->type == AST_CONDZ);
|
||||||
|
|
||||||
if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) {
|
if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) {
|
||||||
sel_case = stmt->children.at(i)->children.back();
|
sel_case = stmt->children.at(i)->children.back();
|
||||||
|
|
|
@ -1094,7 +1094,9 @@ case_body:
|
||||||
|
|
||||||
case_item:
|
case_item:
|
||||||
{
|
{
|
||||||
AstNode *node = new AstNode(AST_COND);
|
AstNode *node = new AstNode(
|
||||||
|
case_type_stack.size() && case_type_stack.back() == 'x' ? AST_CONDX :
|
||||||
|
case_type_stack.size() && case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND);
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
ast_stack.push_back(node);
|
ast_stack.push_back(node);
|
||||||
} case_select {
|
} case_select {
|
||||||
|
@ -1114,7 +1116,9 @@ gen_case_body:
|
||||||
|
|
||||||
gen_case_item:
|
gen_case_item:
|
||||||
{
|
{
|
||||||
AstNode *node = new AstNode(AST_COND);
|
AstNode *node = new AstNode(
|
||||||
|
case_type_stack.size() && case_type_stack.back() == 'x' ? AST_CONDX :
|
||||||
|
case_type_stack.size() && case_type_stack.back() == 'z' ? AST_CONDZ : AST_COND);
|
||||||
ast_stack.back()->children.push_back(node);
|
ast_stack.back()->children.push_back(node);
|
||||||
ast_stack.push_back(node);
|
ast_stack.push_back(node);
|
||||||
} case_select {
|
} case_select {
|
||||||
|
|
Loading…
Reference in New Issue