summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontends/ast/ast.cc8
-rw-r--r--frontends/ast/ast.h1
-rw-r--r--frontends/ast/simplify.cc33
3 files changed, 41 insertions, 1 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 6ac77144..0ea38b50 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -722,6 +722,14 @@ AstNode *AstNode::mkconst_str(const std::string &str)
return node;
}
+bool AstNode::bits_only_01()
+{
+ for (auto bit : bits)
+ if (bit != RTLIL::S0 && bit != RTLIL::S1)
+ return false;
+ return true;
+}
+
RTLIL::Const AstNode::bitsAsConst(int width, bool is_signed)
{
std::vector<RTLIL::State> bits = this->bits;
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 6ea241fa..ef54d76f 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -246,6 +246,7 @@ namespace AST
RTLIL::Const bitsAsConst(int width = -1);
RTLIL::Const asAttrConst();
RTLIL::Const asParaConst();
+ bool bits_only_01();
bool asBool();
// helper functions for real valued const eval
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 76d1f827..85671213 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1567,7 +1567,7 @@ skip_dynamic_range_lvalue_expansion:;
}
// perform const folding when activated
- if (const_fold && newNode == NULL)
+ if (const_fold)
{
bool string_op;
std::vector<RTLIL::State> tmp_bits;
@@ -1746,6 +1746,37 @@ skip_dynamic_range_lvalue_expansion:;
newNode->realvalue = -children[0]->asReal(sign_hint);
}
break;
+ case AST_CASE:
+ if (children[0]->type == AST_CONSTANT && children[0]->bits_only_01()) {
+ std::vector<AstNode*> new_children;
+ new_children.push_back(children[0]);
+ for (int i = 1; i < SIZE(children); i++) {
+ AstNode *child = children[i];
+ log_assert(child->type == AST_COND);
+ for (auto v : child->children) {
+ if (v->type == AST_DEFAULT)
+ goto keep_const_cond;
+ if (v->type == AST_BLOCK)
+ continue;
+ if (v->type == AST_CONSTANT && v->bits_only_01()) {
+ if (v->bits == children[0]->bits) {
+ while (i+1 < SIZE(children))
+ delete children[++i];
+ goto keep_const_cond;
+ }
+ continue;
+ }
+ goto keep_const_cond;
+ }
+ if (0)
+ keep_const_cond:
+ new_children.push_back(child);
+ else
+ delete child;
+ }
+ new_children.swap(children);
+ }
+ break;
case AST_TERNARY:
if (children[0]->isConst())
{