32 for (
auto &action : cs->
actions) {
33 if (action.first.size())
38 for (
auto cs2 : sw->cases) {
49 for (
auto &action : cs->
actions) {
56 for (
auto cs2 : sw->cases)
62 std::stringstream sstr;
63 sstr <<
"$procmux$" << (
autoidx++);
67 for (
auto comp : compare)
73 for (
int i = 0; i < comp.size(); i++)
89 eq_cell->attributes = sw->attributes;
105 if (cmp_wire->width == 1)
107 ctrl_wire = cmp_wire;
111 ctrl_wire = mod->
addWire(sstr.str() +
"_CTRL");
115 any_cell->attributes = sw->attributes;
121 any_cell->
setPort(
"\\A", cmp_wire);
132 std::stringstream sstr;
133 sstr <<
"$procmux$" << (
autoidx++);
136 if (compare.size() == 0 || when_signal == else_signal)
141 if (ctrl_sig.
size() == 0)
150 mux_cell->attributes = sw->attributes;
153 mux_cell->
setPort(
"\\A", else_signal);
154 mux_cell->
setPort(
"\\B", when_signal);
155 mux_cell->
setPort(
"\\S", ctrl_sig);
158 last_mux_cell = mux_cell;
169 last_mux_cell->
type =
"$pmux";
173 last_mux_cell->
setPort(
"\\S", new_s);
176 new_b.
append(when_signal);
177 last_mux_cell->
setPort(
"\\B", new_b);
186 for (
auto &action : cs->
actions) {
187 sig.
replace(action.first, action.second, &result);
188 action.first.remove2(sig, &action.second);
194 std::vector<int> pgroups(sw->cases.size());
195 if (!sw->get_bool_attribute(
"\\parallel_case")) {
197 bool extra_group_for_next_case =
false;
198 for (
size_t i = 0; i < sw->cases.size(); i++) {
201 pgroups[i] = pgroups[i-1];
202 if (extra_group_for_next_case) {
203 pgroups[i] = pgroups[i-1]+1;
204 extra_group_for_next_case =
false;
207 if (!pat.is_fully_const() || !pool.has_all(pat))
208 pgroups[i] = pgroups[i-1]+1;
210 pgroups[i] = pgroups[i-1]+1;
211 if (pgroups[i] != pgroups[i-1])
215 if (!pat.is_fully_const())
216 extra_group_for_next_case =
true;
225 for (
size_t i = 0; i < sw->cases.size(); i++) {
226 int case_idx = sw->cases.size() - i - 1;
229 if (last_mux_cell && pgroups[case_idx] == pgroups[case_idx+1])
232 result =
gen_mux(mod, sw->signal, cs2->
compare, value, result, last_mux_cell, sw);
256 log(
" creating decoder for signal `%s'.\n",
log_signal(sig));
269 log(
" proc_mux [selection]\n");
271 log(
"This pass converts the decision trees in processes (originating from if-else\n");
272 log(
"and case statements) to trees of multiplexer cells.\n");
277 log_header(
"Executing PROC_MUX pass (convert decision trees to multiplexers).\n");
281 for (
auto mod : design->
modules())
283 for (
auto &proc_it : mod->processes)
284 if (design->
selected(mod, proc_it.second))
const char * c_str() const
bool selected(T1 *module) const
std::string stringf(const char *fmt,...)
RTLIL::Cell * addCell(RTLIL::IdString name, RTLIL::IdString type)
void log_header(const char *format,...)
const char * log_signal(const RTLIL::SigSpec &sig, bool autoint)
void setPort(RTLIL::IdString portname, RTLIL::SigSpec signal)
RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector< RTLIL::SigSpec > &compare, RTLIL::SwitchRule *sw)
std::map< RTLIL::IdString, RTLIL::Const > parameters
void proc_mux(RTLIL::Module *mod, RTLIL::Process *proc)
void remove(const RTLIL::SigSpec &pattern)
std::vector< RTLIL::SigSpec > compare
void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector< RTLIL::SigSpec > &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw)
void connect(const RTLIL::SigSig &conn)
#define PRIVATE_NAMESPACE_BEGIN
RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, RTLIL::CaseRule *cs, const RTLIL::SigSpec &sig, const RTLIL::SigSpec &defval)
const RTLIL::SigSpec & getPort(RTLIL::IdString portname) const
#define log_assert(_assert_expr_)
RTLIL::Wire * addWire(RTLIL::IdString name, int width=1)
#define PRIVATE_NAMESPACE_END
#define USING_YOSYS_NAMESPACE
RTLIL::ObjRange< RTLIL::Module * > modules()
void replace(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec &with)
void extract_core_signal(const RTLIL::CaseRule *cs, RTLIL::SigSpec &sig)
USING_YOSYS_NAMESPACE PRIVATE_NAMESPACE_BEGIN RTLIL::SigSpec find_any_lvalue(const RTLIL::CaseRule *cs)
void log(const char *format,...)
RTLIL::SigSpec extract(const RTLIL::SigSpec &pattern, const RTLIL::SigSpec *other=NULL) const
void append(const RTLIL::SigSpec &signal)
std::vector< RTLIL::SigSig > actions
void extra_args(std::vector< std::string > args, size_t argidx, RTLIL::Design *design, bool select=true)
bool take(RTLIL::SigSpec sig)
std::vector< RTLIL::SwitchRule * > switches
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
std::pair< SigSpec, SigSpec > SigSig
YOSYS_NAMESPACE_BEGIN int autoidx
RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector< RTLIL::SigSpec > &compare, RTLIL::SigSpec when_signal, RTLIL::SigSpec else_signal, RTLIL::Cell *&last_mux_cell, RTLIL::SwitchRule *sw)
RTLIL_ATTRIBUTE_MEMBERS RTLIL::CaseRule root_case