proc_mux: consider \src attribute on CaseRule.

This commit is contained in:
whitequark 2019-07-08 13:18:18 +00:00
parent 55c1f40277
commit 48655dfb8b
1 changed files with 16 additions and 10 deletions

View File

@ -144,7 +144,13 @@ struct SnippetSwCache
} }
}; };
RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SwitchRule *sw, bool ifxmode) void apply_attrs(RTLIL::Cell *cell, const RTLIL::SwitchRule *sw, const RTLIL::CaseRule *cs)
{
cell->attributes = sw->attributes;
cell->add_strpool_attribute("\\src", cs->get_strpool_attribute("\\src"));
}
RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SwitchRule *sw, RTLIL::CaseRule *cs, bool ifxmode)
{ {
std::stringstream sstr; std::stringstream sstr;
sstr << "$procmux$" << (autoidx++); sstr << "$procmux$" << (autoidx++);
@ -173,7 +179,7 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
{ {
// create compare cell // create compare cell
RTLIL::Cell *eq_cell = mod->addCell(stringf("%s_CMP%d", sstr.str().c_str(), cmp_wire->width), ifxmode ? "$eqx" : "$eq"); RTLIL::Cell *eq_cell = mod->addCell(stringf("%s_CMP%d", sstr.str().c_str(), cmp_wire->width), ifxmode ? "$eqx" : "$eq");
eq_cell->attributes = sw->attributes; apply_attrs(eq_cell, sw, cs);
eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(0); eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(0);
@ -199,7 +205,7 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
// reduce cmp vector to one logic signal // reduce cmp vector to one logic signal
RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", "$reduce_or"); RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", "$reduce_or");
any_cell->attributes = sw->attributes; apply_attrs(any_cell, sw, cs);
any_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0); any_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width); any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width);
@ -212,7 +218,7 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
return RTLIL::SigSpec(ctrl_wire); return RTLIL::SigSpec(ctrl_wire);
} }
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, bool ifxmode) 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::CaseRule *cs, bool ifxmode)
{ {
log_assert(when_signal.size() == else_signal.size()); log_assert(when_signal.size() == else_signal.size());
@ -224,7 +230,7 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
return when_signal; return when_signal;
// compare results // compare results
RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, ifxmode); RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode);
if (ctrl_sig.size() == 0) if (ctrl_sig.size() == 0)
return when_signal; return when_signal;
log_assert(ctrl_sig.size() == 1); log_assert(ctrl_sig.size() == 1);
@ -234,7 +240,7 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
// create the multiplexer itself // create the multiplexer itself
RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), "$mux"); RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), "$mux");
mux_cell->attributes = sw->attributes; apply_attrs(mux_cell, sw, cs);
mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size()); mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size());
mux_cell->setPort("\\A", else_signal); mux_cell->setPort("\\A", else_signal);
@ -246,7 +252,7 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
return RTLIL::SigSpec(result_wire); return RTLIL::SigSpec(result_wire);
} }
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, bool ifxmode) 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, RTLIL::CaseRule *cs, bool ifxmode)
{ {
log_assert(last_mux_cell != NULL); log_assert(last_mux_cell != NULL);
log_assert(when_signal.size() == last_mux_cell->getPort("\\A").size()); log_assert(when_signal.size() == last_mux_cell->getPort("\\A").size());
@ -254,7 +260,7 @@ void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::ve
if (when_signal == last_mux_cell->getPort("\\A")) if (when_signal == last_mux_cell->getPort("\\A"))
return; return;
RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, ifxmode); RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode);
log_assert(ctrl_sig.size() == 1); log_assert(ctrl_sig.size() == 1);
last_mux_cell->type = "$pmux"; last_mux_cell->type = "$pmux";
@ -395,9 +401,9 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d
RTLIL::CaseRule *cs2 = sw->cases[case_idx]; RTLIL::CaseRule *cs2 = sw->cases[case_idx];
RTLIL::SigSpec value = signal_to_mux_tree(mod, swcache, swpara, cs2, sig, initial_val, ifxmode); RTLIL::SigSpec value = signal_to_mux_tree(mod, swcache, swpara, cs2, sig, initial_val, ifxmode);
if (last_mux_cell && pgroups[case_idx] == pgroups[case_idx+1]) if (last_mux_cell && pgroups[case_idx] == pgroups[case_idx+1])
append_pmux(mod, sw->signal, cs2->compare, value, last_mux_cell, sw, ifxmode); append_pmux(mod, sw->signal, cs2->compare, value, last_mux_cell, sw, cs2, ifxmode);
else else
result = gen_mux(mod, sw->signal, cs2->compare, value, result, last_mux_cell, sw, ifxmode); result = gen_mux(mod, sw->signal, cs2->compare, value, result, last_mux_cell, sw, cs2, ifxmode);
} }
} }