From 56ea2306764e1363688e0f9e1146f98bd48d3037 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 19 Oct 2013 00:50:13 +0200 Subject: [PATCH] Added handling of multiple async paths in proc_arst --- passes/proc/proc_arst.cc | 12 ++++++++++++ passes/proc/proc_clean.cc | 17 +++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/passes/proc/proc_arst.cc b/passes/proc/proc_arst.cc index d0a0d864c..021d87c81 100644 --- a/passes/proc/proc_arst.cc +++ b/passes/proc/proc_arst.cc @@ -23,6 +23,9 @@ #include #include +// defined in proc_clean.cc +extern void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count, int max_depth); + static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity) { if (signal.width != 1) @@ -132,10 +135,18 @@ static void eliminate_const(RTLIL::Module *mod, RTLIL::CaseRule *cs, RTLIL::SigS eliminate_const(mod, cs2, const_sig, polarity); } } + + int dummy_count = 0; + bool did_something = true; + while (did_something) { + did_something = false; + proc_clean_case(cs, did_something, dummy_count, 1); + } } static void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map) { +restart_proc_arst: if (proc->root_case.switches.size() != 1) return; @@ -173,6 +184,7 @@ static void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_m action.second = rval; } eliminate_const(mod, &proc->root_case, root_sig, polarity); + goto restart_proc_arst; } } } diff --git a/passes/proc/proc_clean.cc b/passes/proc/proc_clean.cc index e247f2882..83554df90 100644 --- a/passes/proc/proc_clean.cc +++ b/passes/proc/proc_clean.cc @@ -22,10 +22,10 @@ #include #include -static void switch_clean(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count); -static void case_clean(RTLIL::CaseRule *cs, bool &did_something, int &count); +extern void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count, int max_depth); +extern void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count, int max_depth); -static void switch_clean(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count) +void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count, int max_depth) { if (sw->signal.width > 0 && sw->signal.is_fully_const()) { @@ -76,7 +76,8 @@ static void switch_clean(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &d for (auto cs : sw->cases) { if (cs->actions.size() != 0 || cs->switches.size() != 0) all_cases_are_empty = false; - case_clean(cs, did_something, count); + if (max_depth != 0) + proc_clean_case(cs, did_something, count, max_depth-1); } if (all_cases_are_empty) { did_something = true; @@ -87,7 +88,7 @@ static void switch_clean(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &d } } -static void case_clean(RTLIL::CaseRule *cs, bool &did_something, int &count) +void proc_clean_case(RTLIL::CaseRule *cs, bool &did_something, int &count, int max_depth) { for (size_t i = 0; i < cs->actions.size(); i++) { if (cs->actions[i].first.width == 0) { @@ -102,8 +103,8 @@ static void case_clean(RTLIL::CaseRule *cs, bool &did_something, int &count) did_something = true; delete sw; count++; - } else - switch_clean(sw, cs, did_something, count); + } else if (max_depth != 0) + proc_clean_switch(sw, cs, did_something, count, max_depth-1); } } @@ -122,7 +123,7 @@ static void proc_clean(RTLIL::Module *mod, RTLIL::Process *proc, int &total_coun } while (did_something) { did_something = false; - case_clean(&proc->root_case, did_something, count); + proc_clean_case(&proc->root_case, did_something, count, -1); } if (count > 0) log("Found and cleaned up %d empty switch%s in `%s.%s'.\n", count, count == 1 ? "" : "es", mod->name.c_str(), proc->name.c_str()); -- 2.30.2