Fixed parsing of default cases when not last case
authorClifford Wolf <clifford@clifford.at>
Mon, 18 Nov 2013 15:10:50 +0000 (16:10 +0100)
committerClifford Wolf <clifford@clifford.at>
Mon, 18 Nov 2013 15:10:50 +0000 (16:10 +0100)
frontends/ast/genrtlil.cc
tests/simple/muxtree.v

index e64193f6e2eee1a695ff27cda1aaaa234d1b0f96..550f7245e26566b61401c05267d8661ec8860db1 100644 (file)
@@ -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);
                                }
 
index 6996206c01d9d20ce6972f0e027e9be88a3fc343..c5060eae978d42dbd2404782490e37ea5086e0e8 100644 (file)
@@ -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
+