From 2a25e3bca351ad85b328ed808f4efdcf45f6b02c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Nov 2013 16:10:50 +0100 Subject: [PATCH] Fixed parsing of default cases when not last case --- frontends/ast/genrtlil.cc | 28 ++++++++++++++++------------ tests/simple/muxtree.v | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 12 deletions(-) diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index e64193f6e..550f7245e 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -481,11 +481,11 @@ struct AST_INTERNAL::ProcessGenerator RTLIL::SigSpec backup_subst_rvalue_from = subst_rvalue_from; 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; for (auto child : ast->children) { - if (child == ast->children[0] || generated_default_case) + if (child == ast->children[0]) continue; assert(child->type == AST_COND); @@ -506,23 +506,27 @@ struct AST_INTERNAL::ProcessGenerator last_generated_case = current_case; addChunkActions(current_case->actions, this_case_eq_ltemp, this_case_eq_rvalue); for (auto node : child->children) { - if (node->type == AST_DEFAULT) { - generated_default_case = true; - current_case->compare.clear(); - } else if (node->type == AST_BLOCK) { + if (node->type == AST_DEFAULT) + default_case = current_case; + else if (node->type == AST_BLOCK) processAst(node); - } else if (!generated_default_case) + else 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; } - 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(); - } else if (!generated_default_case) { - RTLIL::CaseRule *default_case = new RTLIL::CaseRule; - addChunkActions(default_case->actions, this_case_eq_ltemp, this_case_eq_rvalue); + } else { + if (default_case == NULL) { + default_case = new RTLIL::CaseRule; + addChunkActions(default_case->actions, this_case_eq_ltemp, this_case_eq_rvalue); + } sw->cases.push_back(default_case); } diff --git a/tests/simple/muxtree.v b/tests/simple/muxtree.v index 6996206c0..c5060eae9 100644 --- a/tests/simple/muxtree.v +++ b/tests/simple/muxtree.v @@ -48,3 +48,25 @@ always @(state or TxValid_i) end 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 + -- 2.30.2