Bugfix in fsm_detect for complex muxtrees
This commit is contained in:
parent
f43815054e
commit
246e362717
1 changed files with 23 additions and 15 deletions
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue