mirror of https://github.com/YosysHQ/yosys.git
Added handling of multiple async paths in proc_arst
This commit is contained in:
parent
8e8f1994b8
commit
56ea230676
|
@ -23,6 +23,9 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
// 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)
|
static bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref, bool &polarity)
|
||||||
{
|
{
|
||||||
if (signal.width != 1)
|
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);
|
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)
|
static void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_map)
|
||||||
{
|
{
|
||||||
|
restart_proc_arst:
|
||||||
if (proc->root_case.switches.size() != 1)
|
if (proc->root_case.switches.size() != 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -173,6 +184,7 @@ static void proc_arst(RTLIL::Module *mod, RTLIL::Process *proc, SigMap &assign_m
|
||||||
action.second = rval;
|
action.second = rval;
|
||||||
}
|
}
|
||||||
eliminate_const(mod, &proc->root_case, root_sig, polarity);
|
eliminate_const(mod, &proc->root_case, root_sig, polarity);
|
||||||
|
goto restart_proc_arst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
static void switch_clean(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count);
|
extern void proc_clean_switch(RTLIL::SwitchRule *sw, RTLIL::CaseRule *parent, bool &did_something, int &count, int max_depth);
|
||||||
static void case_clean(RTLIL::CaseRule *cs, bool &did_something, int &count);
|
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())
|
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) {
|
for (auto cs : sw->cases) {
|
||||||
if (cs->actions.size() != 0 || cs->switches.size() != 0)
|
if (cs->actions.size() != 0 || cs->switches.size() != 0)
|
||||||
all_cases_are_empty = false;
|
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) {
|
if (all_cases_are_empty) {
|
||||||
did_something = true;
|
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++) {
|
for (size_t i = 0; i < cs->actions.size(); i++) {
|
||||||
if (cs->actions[i].first.width == 0) {
|
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;
|
did_something = true;
|
||||||
delete sw;
|
delete sw;
|
||||||
count++;
|
count++;
|
||||||
} else
|
} else if (max_depth != 0)
|
||||||
switch_clean(sw, cs, did_something, count);
|
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) {
|
while (did_something) {
|
||||||
did_something = false;
|
did_something = false;
|
||||||
case_clean(&proc->root_case, did_something, count);
|
proc_clean_case(&proc->root_case, did_something, count, -1);
|
||||||
}
|
}
|
||||||
if (count > 0)
|
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());
|
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());
|
||||||
|
|
Loading…
Reference in New Issue