aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorclairexen <claire@symbioticeda.com>2020-06-09 18:27:59 +0200
committerGitHub <noreply@github.com>2020-06-09 18:27:59 +0200
commit5c426d2bff07825042b0fa0449805ea9cb8b9f58 (patch)
treee89942d6aa6ff5facaabd746d5c12c6d25190764
parent9a2cf5e3db15218af9a5320a8ca1a7f190aa236b (diff)
parent7ad0c49905d97c3bea2b74b76ca0feb87d21f70d (diff)
downloadyosys-5c426d2bff07825042b0fa0449805ea9cb8b9f58.tar.gz
yosys-5c426d2bff07825042b0fa0449805ea9cb8b9f58.tar.bz2
yosys-5c426d2bff07825042b0fa0449805ea9cb8b9f58.zip
Merge pull request #2112 from YosysHQ/claire/fix2040
Add latch detection for use_case_method in part-select write
-rw-r--r--frontends/ast/ast.h1
-rw-r--r--frontends/ast/simplify.cc57
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 6970135d0..5f026dfed 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -2136,6 +2136,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
@@ -4204,6 +4207,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)