diff options
author | Claire Wolf <claire@symbioticeda.com> | 2020-06-04 23:10:03 +0200 |
---|---|---|
committer | Claire Wolf <claire@symbioticeda.com> | 2020-06-04 23:25:59 +0200 |
commit | 7ad0c49905d97c3bea2b74b76ca0feb87d21f70d (patch) | |
tree | f6eec9686e745f420183eab7bffb6afe2eb39343 /frontends | |
parent | 7112f187cd5c8c34c7945132cb90d5a11fcfa554 (diff) | |
download | yosys-7ad0c49905d97c3bea2b74b76ca0feb87d21f70d.tar.gz yosys-7ad0c49905d97c3bea2b74b76ca0feb87d21f70d.tar.bz2 yosys-7ad0c49905d97c3bea2b74b76ca0feb87d21f70d.zip |
Add latch detection for use_case_method in part-select write, fixes #2040
Signed-off-by: Claire Wolf <claire@symbioticeda.com>
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/ast/ast.h | 1 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 57 |
2 files changed, 58 insertions, 0 deletions
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h index 6d556fae2..b8f24ee14 100644 --- a/frontends/ast/ast.h +++ b/frontends/ast/ast.h @@ -257,6 +257,7 @@ namespace AST bool mem2reg_check(pool<AstNode*> &mem2reg_set); void mem2reg_remove(pool<AstNode*> &mem2reg_set, vector<AstNode*> &delnodes); void meminfo(int &mem_width, int &mem_size, int &addr_bits); + bool detect_latch(const std::string &var); // additional functionality for evaluating constant functions struct varinfo_t { RTLIL::Const val; int offset; bool is_signed; }; diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index e88331621..1d80a5dc4 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -2017,6 +2017,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, use_case_method = true; } + if (!use_case_method && current_always->detect_latch(children[0]->str)) + use_case_method = true; + if (use_case_method) { // big case block @@ -4085,6 +4088,60 @@ void AstNode::meminfo(int &mem_width, int &mem_size, int &addr_bits) addr_bits++; } +bool AstNode::detect_latch(const std::string &var) +{ + switch (type) + { + case AST_ALWAYS: + for (auto &c : children) + { + switch (c->type) + { + case AST_POSEDGE: + case AST_NEGEDGE: + return false; + case AST_BLOCK: + if (!c->detect_latch(var)) + return false; + break; + default: + log_abort(); + } + } + return true; + case AST_BLOCK: + for (auto &c : children) + if (!c->detect_latch(var)) + return false; + return true; + case AST_CASE: + { + bool r = true; + for (auto &c : children) { + if (c->type == AST_COND) { + if (c->children.at(1)->detect_latch(var)) + return true; + r = false; + } + if (c->type == AST_DEFAULT) { + if (c->children.at(0)->detect_latch(var)) + return true; + r = false; + } + } + return r; + } + case AST_ASSIGN_EQ: + case AST_ASSIGN_LE: + if (children.at(0)->type == AST_IDENTIFIER && + children.at(0)->children.empty() && children.at(0)->str == var) + return false; + return true; + default: + return true; + } +} + bool AstNode::has_const_only_constructs(bool &recommend_const_eval) { if (type == AST_FOR) |