Fixed parsing of default cases when not last case

This commit is contained in:
Clifford Wolf 2013-11-18 16:10:50 +01:00
parent de03184150
commit 2a25e3bca3
2 changed files with 38 additions and 12 deletions

View File

@ -481,11 +481,11 @@ struct AST_INTERNAL::ProcessGenerator
RTLIL::SigSpec backup_subst_rvalue_from = subst_rvalue_from; RTLIL::SigSpec backup_subst_rvalue_from = subst_rvalue_from;
RTLIL::SigSpec backup_subst_rvalue_to = subst_rvalue_to; RTLIL::SigSpec backup_subst_rvalue_to = subst_rvalue_to;
bool generated_default_case = false; RTLIL::CaseRule *default_case = NULL;
RTLIL::CaseRule *last_generated_case = NULL; RTLIL::CaseRule *last_generated_case = NULL;
for (auto child : ast->children) for (auto child : ast->children)
{ {
if (child == ast->children[0] || generated_default_case) if (child == ast->children[0])
continue; continue;
assert(child->type == AST_COND); assert(child->type == AST_COND);
@ -506,23 +506,27 @@ struct AST_INTERNAL::ProcessGenerator
last_generated_case = current_case; last_generated_case = current_case;
addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue); addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
for (auto node : child->children) { for (auto node : child->children) {
if (node->type == AST_DEFAULT) { if (node->type == AST_DEFAULT)
generated_default_case = true; default_case = current_case;
current_case->compare.clear(); else if (node->type == AST_BLOCK)
} else if (node->type == AST_BLOCK) {
processAst(node); processAst(node);
} else if (!generated_default_case) else
current_case->compare.push_back(node->genWidthRTLIL(sw->signal.width, &subst_rvalue_from, &subst_rvalue_to)); current_case->compare.push_back(node->genWidthRTLIL(sw->signal.width, &subst_rvalue_from, &subst_rvalue_to));
} }
if (default_case != current_case)
sw->cases.push_back(current_case); sw->cases.push_back(current_case);
else
log_assert(current_case->compare.size() == 0);
current_case = backup_case; current_case = backup_case;
} }
if (last_generated_case != NULL && ast->get_bool_attribute("\\full_case")) { if (last_generated_case != NULL && ast->get_bool_attribute("\\full_case") && default_case == NULL) {
last_generated_case->compare.clear(); last_generated_case->compare.clear();
} else if (!generated_default_case) { } else {
RTLIL::CaseRule *default_case = new RTLIL::CaseRule; if (default_case == NULL) {
default_case = new RTLIL::CaseRule;
addChunkActions(default_case->actions, this_case_eq_ltemp, this_case_eq_rvalue); addChunkActions(default_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
}
sw->cases.push_back(default_case); sw->cases.push_back(default_case);
} }

View File

@ -48,3 +48,25 @@ always @(state or TxValid_i)
end end
endmodule endmodule
// test case inspired by softusb_navre code:
// default not as last case
module default_cases(a, y);
input [2:0] a;
output reg [3:0] y;
always @* begin
case (a)
3'b000, 3'b111: y <= 0;
default: y <= 4;
3'b001: y <= 1;
3'b010: y <= 2;
3'b100: y <= 3;
endcase
end
endmodule