From: Claire Wolf Date: Thu, 4 Jun 2020 21:10:03 +0000 (+0200) Subject: Add latch detection for use_case_method in part-select write, fixes #2040 X-Git-Tag: working-ls180~485^2 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7ad0c49905d97c3bea2b74b76ca0feb87d21f70d;p=yosys.git Add latch detection for use_case_method in part-select write, fixes #2040 Signed-off-by: Claire Wolf --- 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 &mem2reg_set); void mem2reg_remove(pool &mem2reg_set, vector &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)