From 246e362717f23bb8cfbd22c33728d6517b7d3d8f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 18 Aug 2015 14:17:50 +0200 Subject: [PATCH] Bugfix in fsm_detect for complex muxtrees --- passes/fsm/fsm_detect.cc | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/passes/fsm/fsm_detect.cc b/passes/fsm/fsm_detect.cc index 7a621b567..feeaa347c 100644 --- a/passes/fsm/fsm_detect.cc +++ b/passes/fsm/fsm_detect.cc @@ -34,7 +34,7 @@ static SigSet sig2driver, sig2user; static std::set muxtree_cells; static SigPool sig_at_port; -static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, SigPool &recursion_monitor) +static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, pool &recursion_monitor) { if (sig_at_port.check_any(assign_map(sig))) return false; @@ -42,31 +42,39 @@ static bool check_state_mux_tree(RTLIL::SigSpec old_sig, RTLIL::SigSpec sig, Sig if (sig.is_fully_const() || old_sig == sig) return true; - if (recursion_monitor.check_any(sig)) { - log_warning("logic loop in mux tree at signal %s in module %s.\n", - log_signal(sig), RTLIL::id2cstr(module->name)); - return false; - } - - recursion_monitor.add(sig); - std::set cellport_list; sig2driver.find(sig, cellport_list); - for (auto &cellport : cellport_list) { + for (auto &cellport : cellport_list) + { if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux") || cellport.second != "\\Y") return false; + + if (recursion_monitor.count(cellport.first)) { + log_warning("logic loop in mux tree at signal %s in module %s.\n", + log_signal(sig), RTLIL::id2cstr(module->name)); + return false; + } + + recursion_monitor.insert(cellport.first); + RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A")); RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B")); - if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor)) + + if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor)) { + recursion_monitor.erase(cellport.first); return false; + } + for (int i = 0; i < sig_b.size(); i += sig_a.size()) - if (!check_state_mux_tree(old_sig, sig_b.extract(i, sig_a.size()), recursion_monitor)) + if (!check_state_mux_tree(old_sig, sig_b.extract(i, sig_a.size()), recursion_monitor)) { + recursion_monitor.erase(cellport.first); return false; + } + + recursion_monitor.erase(cellport.first); muxtree_cells.insert(cellport.first); } - recursion_monitor.del(sig); - return true; } @@ -111,7 +119,7 @@ static void detect_fsm(RTLIL::Wire *wire) if ((cellport.first->type != "$dff" && cellport.first->type != "$adff") || cellport.second != "\\Q") continue; muxtree_cells.clear(); - SigPool recursion_monitor; + pool recursion_monitor; RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort("\\Q")); RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort("\\D")); if (sig_q == RTLIL::SigSpec(wire) && check_state_mux_tree(sig_q, sig_d, recursion_monitor) && check_state_users(sig_q)) { -- 2.30.2