diff options
author | Clifford Wolf <clifford@clifford.at> | 2014-02-16 13:16:38 +0100 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2014-02-16 13:16:38 +0100 |
commit | 7ac524e8e8d1745dec4605c32944e318f46daf4e (patch) | |
tree | 07809d010935fd9c6fcf9f93a153b72fa4717b7e /frontends/ast/simplify.cc | |
parent | b0ae19fa92787436e4c139f42af5f5890f0d4dd8 (diff) | |
download | yosys-7ac524e8e8d1745dec4605c32944e318f46daf4e.tar.gz yosys-7ac524e8e8d1745dec4605c32944e318f46daf4e.tar.bz2 yosys-7ac524e8e8d1745dec4605c32944e318f46daf4e.zip |
Improved support for constant functions
Diffstat (limited to 'frontends/ast/simplify.cc')
-rw-r--r-- | frontends/ast/simplify.cc | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2ae3cae08..5e37911d3 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -1167,9 +1167,11 @@ skip_dynamic_range_lvalue_expansion:; if (in_param) { bool all_args_const = true; - for (auto child : children) + for (auto child : children) { + while (child->simplify(true, false, false, 1, -1, false, true)) { } if (child->type != AST_CONSTANT) all_args_const = false; + } if (all_args_const) { AstNode *func_workspace = current_scope[str]->clone(); @@ -1931,6 +1933,53 @@ AstNode *AstNode::eval_const_function(AstNode *fcall) continue; } + if (stmt->type == AST_CASE) + { + AstNode *expr = stmt->children.at(0)->clone(); + expr->replace_variables(variables, fcall); + while (expr->simplify(true, false, false, 1, -1, false, true)) { } + + AstNode *sel_case = NULL; + for (size_t i = 1; i < stmt->children.size(); i++) + { + bool found_match = false; + log_assert(stmt->children.at(i)->type == AST_COND); + + if (stmt->children.at(i)->children.front()->type == AST_DEFAULT) { + sel_case = stmt->children.at(i)->children.back(); + continue; + } + + for (size_t j = 0; j+1 < stmt->children.at(i)->children.size() && !found_match; j++) + { + AstNode *cond = stmt->children.at(i)->children.at(j)->clone(); + cond->replace_variables(variables, fcall); + + cond = new AstNode(AST_EQ, expr->clone(), cond); + while (cond->simplify(true, false, false, 1, -1, false, true)) { } + + if (cond->type != AST_CONSTANT) + log_error("Non-constant expression in constant function at %s:%d (called from %s:%d).\n", + stmt->filename.c_str(), stmt->linenum, fcall->filename.c_str(), fcall->linenum); + + found_match = cond->asBool(); + delete cond; + } + + if (found_match) { + sel_case = stmt->children.at(i)->children.back(); + break; + } + } + + block->children.erase(block->children.begin()); + if (sel_case) + block->children.insert(block->children.begin(), sel_case->clone()); + delete stmt; + delete expr; + continue; + } + if (stmt->type == AST_BLOCK) { block->children.erase(block->children.begin()); |