mirror of https://github.com/YosysHQ/yosys.git
proc_mux: consider \src attribute on CaseRule.
This commit is contained in:
parent
55c1f40277
commit
48655dfb8b
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue