diff options
author | Clifford Wolf <clifford@clifford.at> | 2015-08-18 14:17:50 +0200 |
---|---|---|
committer | Clifford Wolf <clifford@clifford.at> | 2015-08-18 14:17:50 +0200 |
commit | 246e362717f23bb8cfbd22c33728d6517b7d3d8f (patch) | |
tree | 03b2cde6ca70a8b7b43cf45e3314375415b953a1 /passes/fsm/fsm_detect.cc | |
parent | f43815054e9784d9e1a1b28b5ea2db8404c91d58 (diff) | |
download | yosys-246e362717f23bb8cfbd22c33728d6517b7d3d8f.tar.gz yosys-246e362717f23bb8cfbd22c33728d6517b7d3d8f.tar.bz2 yosys-246e362717f23bb8cfbd22c33728d6517b7d3d8f.zip |
Bugfix in fsm_detect for complex muxtrees
Diffstat (limited to 'passes/fsm/fsm_detect.cc')
-rw-r--r-- | passes/fsm/fsm_detect.cc | 38 |
1 files 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_entry_t> sig2driver, sig2user; static std::set<RTLIL::Cell*> 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<Cell*> &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<sig2driver_entry_t> 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<Cell*> 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)) { |