Fixed handling of parameters and const functions in casex/casez pattern
authorClifford Wolf <clifford@clifford.at>
Thu, 21 Apr 2016 13:31:54 +0000 (15:31 +0200)
committerClifford Wolf <clifford@clifford.at>
Thu, 21 Apr 2016 13:31:54 +0000 (15:31 +0200)
frontends/ast/ast.cc
frontends/ast/ast.h
frontends/ast/genrtlil.cc
frontends/ast/simplify.cc
frontends/verilog/verilog_parser.y

index 834ee82ab7217cbefe10d9d3ff8b6ed4c64327ee..c49f29ce728731663388dac8da321d273a4c9e74 100644 (file)
@@ -146,6 +146,8 @@ std::string AST::type2str(AstNodeType type)
        X(AST_ASSIGN_LE)
        X(AST_CASE)
        X(AST_COND)
+       X(AST_CONDX)
+       X(AST_CONDZ)
        X(AST_DEFAULT)
        X(AST_FOR)
        X(AST_WHILE)
@@ -501,7 +503,12 @@ void AstNode::dumpVlog(FILE *f, std::string indent)
                break;
 
        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, "");
                fprintf(f, ")\n");
                for (size_t i = 1; i < children.size(); i++) {
@@ -512,6 +519,8 @@ void AstNode::dumpVlog(FILE *f, std::string indent)
                break;
 
        case AST_COND:
+       case AST_CONDX:
+       case AST_CONDZ:
                for (auto child : children) {
                        if (child->type == AST_BLOCK) {
                                fprintf(f, ":\n");
index b5349db5e46147931a8a74da723d4a4be9124d79..b4e58d79f31e2e3dde8545afb9f851a4cd495a7c 100644 (file)
@@ -122,6 +122,8 @@ namespace AST
                AST_ASSIGN_LE,
                AST_CASE,
                AST_COND,
+               AST_CONDX,
+               AST_CONDZ,
                AST_DEFAULT,
                AST_FOR,
                AST_WHILE,
index 9fc5903761bc6955686af06173f59323c4112dfa..173930a1be98dee23e7b607c4923b95a82953cf9 100644 (file)
@@ -338,12 +338,14 @@ struct AST_INTERNAL::ProcessGenerator
                case AST_CASE:
                        for (auto child : ast->children)
                                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);
                                }
                        break;
 
                case AST_COND:
+               case AST_CONDX:
+               case AST_CONDZ:
                case AST_ALWAYS:
                case AST_INITIAL:
                        for (auto child : ast->children)
@@ -467,7 +469,7 @@ struct AST_INTERNAL::ProcessGenerator
                                {
                                        if (child == ast->children[0])
                                                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_rvalue_map.save();
index c56ac7d5f7bac3c18e10c51aa5079919d323c36b..e000872802784c6350cd62a2cfd845a863134daf 100644 (file)
@@ -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)
        {
                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]);
                        for (int i = 1; i < GetSize(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) {
                                        if (v->type == AST_DEFAULT)
                                                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;
                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;
                        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++)
                        {
                                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) {
                                        sel_case = stmt->children.at(i)->children.back();
index 568cadd94b183e481c0f9d6fb3c46ca97f2f939f..f9584913308a9f0fbb92b1453e0012636aa9b9b0 100644 (file)
@@ -1094,7 +1094,9 @@ case_body:
 
 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.push_back(node);
        } case_select {
@@ -1114,7 +1116,9 @@ gen_case_body:
 
 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.push_back(node);
        } case_select {