mirror of https://github.com/YosysHQ/yosys.git
Fixed parsing of default cases when not last case
This commit is contained in:
parent
de03184150
commit
2a25e3bca3
|
@ -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));
|
||||||
}
|
}
|
||||||
sw->cases.push_back(current_case);
|
if (default_case != 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) {
|
||||||
addChunkActions(default_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
|
default_case = new RTLIL::CaseRule;
|
||||||
|
addChunkActions(default_case->actions, this_case_eq_ltemp, this_case_eq_rvalue);
|
||||||
|
}
|
||||||
sw->cases.push_back(default_case);
|
sw->cases.push_back(default_case);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue