mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #3526 from jix/mux-simlib-eval
Consistent $mux undef handling
This commit is contained in:
commit
408fc60c95
|
@ -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);
|
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)
|
RTLIL::Const RTLIL::const_bmux(const RTLIL::Const &arg1, const RTLIL::Const &arg2)
|
||||||
{
|
{
|
||||||
std::vector<RTLIL::State> t = arg1.bits;
|
std::vector<RTLIL::State> t = arg1.bits;
|
||||||
|
|
|
@ -488,16 +488,10 @@ struct CellTypes
|
||||||
|
|
||||||
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)
|
static RTLIL::Const eval(RTLIL::Cell *cell, const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3, bool *errp = nullptr)
|
||||||
{
|
{
|
||||||
if (cell->type.in(ID($mux), ID($pmux), ID($_MUX_))) {
|
if (cell->type.in(ID($mux), ID($_MUX_)))
|
||||||
RTLIL::Const ret = arg1;
|
return const_mux(arg1, arg2, arg3);
|
||||||
for (size_t i = 0; i < arg3.bits.size(); i++)
|
if (cell->type == ID($pmux))
|
||||||
if (arg3.bits[i] == RTLIL::State::S1) {
|
return const_pmux(arg1, arg2, arg3);
|
||||||
std::vector<RTLIL::State> bits(arg2.bits.begin() + i*arg1.bits.size(), arg2.bits.begin() + (i+1)*arg1.bits.size());
|
|
||||||
ret = RTLIL::Const(bits);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cell->type == ID($_AOI3_))
|
if (cell->type == ID($_AOI3_))
|
||||||
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1));
|
return eval_not(const_or(const_and(arg1, arg2, false, false, 1), arg3, false, false, 1));
|
||||||
if (cell->type == ID($_OAI3_))
|
if (cell->type == ID($_OAI3_))
|
||||||
|
|
|
@ -500,6 +500,8 @@ namespace RTLIL
|
||||||
RTLIL::Const const_pos (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
RTLIL::Const const_pos (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||||
RTLIL::Const const_neg (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
RTLIL::Const const_neg (const RTLIL::Const &arg1, const RTLIL::Const &arg2, bool signed1, bool signed2, int result_len);
|
||||||
|
|
||||||
|
RTLIL::Const const_mux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);
|
||||||
|
RTLIL::Const const_pmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);
|
||||||
RTLIL::Const const_bmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
RTLIL::Const const_bmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
||||||
RTLIL::Const const_demux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
RTLIL::Const const_demux (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
||||||
|
|
||||||
|
|
|
@ -1494,7 +1494,7 @@ skip_identity:
|
||||||
RTLIL::SigSpec input = assign_map(cell->getPort(ID::S));
|
RTLIL::SigSpec input = assign_map(cell->getPort(ID::S));
|
||||||
RTLIL::SigSpec inA = assign_map(cell->getPort(ID::A));
|
RTLIL::SigSpec inA = assign_map(cell->getPort(ID::A));
|
||||||
RTLIL::SigSpec inB = assign_map(cell->getPort(ID::B));
|
RTLIL::SigSpec inB = assign_map(cell->getPort(ID::B));
|
||||||
if (input.is_fully_const())
|
if (input.is_fully_const() && (!keepdc || input.is_fully_def()))
|
||||||
ACTION_DO(ID::Y, input.as_bool() ? cell->getPort(ID::B) : cell->getPort(ID::A));
|
ACTION_DO(ID::Y, input.as_bool() ? cell->getPort(ID::B) : cell->getPort(ID::A));
|
||||||
else if (inA == inB)
|
else if (inA == inB)
|
||||||
ACTION_DO(ID::Y, cell->getPort(ID::A));
|
ACTION_DO(ID::Y, cell->getPort(ID::A));
|
||||||
|
|
|
@ -1282,10 +1282,7 @@ input S;
|
||||||
output reg [WIDTH-1:0] Y;
|
output reg [WIDTH-1:0] Y;
|
||||||
|
|
||||||
always @* begin
|
always @* begin
|
||||||
if (S)
|
assign Y = S ? B : A;
|
||||||
Y = B;
|
|
||||||
else
|
|
||||||
Y = A;
|
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue