mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-06 14:13:23 +00:00
Consistent $mux undef handling
* Change simlib's $mux cell to use the ternary operator as $_MUX_ already does * Stop opt_expr -keepdc from changing S=x to S=0 * Change const eval of $mux and $pmux to match the updated simlib (fixes sim) * The sat behavior of $mux already matches the updated simlib The verilog frontend uses $mux for the ternary operators and this changes all interpreations of the $mux cell (that I found) to match the verilog simulation behavior for the ternary operator. For 'if' and 'case' expressions the frontend may also use $mux but uses $eqx if the verilog simulation behavior is requested with the '-ifx' option. For $pmux there is a remaining mismatch between the sat behavior and the simlib behavior. Resolving this requires more discussion, as the $pmux cell does not directly correspond to a specific verilog construct.
This commit is contained in:
parent
4f4cff0080
commit
c77b7343d0
5 changed files with 38 additions and 15 deletions
|
@ -609,6 +609,36 @@ RTLIL::Const RTLIL::const_neg(const RTLIL::Const &arg1, const RTLIL::Const&, boo
|
|||
return RTLIL::const_sub(zero, arg1_ext, true, signed1, result_len);
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_mux(const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3)
|
||||
{
|
||||
log_assert(arg2.size() == arg1.size());
|
||||
if (arg3[0] == State::S0)
|
||||
return arg1;
|
||||
else if (arg3[0] == State::S1)
|
||||
return arg2;
|
||||
|
||||
RTLIL::Const ret = arg1;
|
||||
for (int i = 0; i < ret.size(); i++)
|
||||
if (ret[i] != arg2[i])
|
||||
ret[i] = State::Sx;
|
||||
return ret;
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_pmux(const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3)
|
||||
{
|
||||
if (arg3.is_fully_zero())
|
||||
return arg1;
|
||||
|
||||
if (!arg3.is_onehot())
|
||||
return RTLIL::Const(State::Sx, arg1.size());
|
||||
|
||||
for (int i = 0; i < arg3.size(); i++)
|
||||
if (arg3[i] == State::S1)
|
||||
return RTLIL::Const(std::vector<RTLIL::State>(arg2.bits.begin() + i*arg1.bits.size(), arg2.bits.begin() + (i+1)*arg1.bits.size()));
|
||||
|
||||
log_abort(); // unreachable
|
||||
}
|
||||
|
||||
RTLIL::Const RTLIL::const_bmux(const RTLIL::Const &arg1, const RTLIL::Const &arg2)
|
||||
{
|
||||
std::vector<RTLIL::State> t = arg1.bits;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue