mirror of https://github.com/YosysHQ/yosys.git
Add bitwise `$bweqx` and `$bwmux` cells
The new bitwise case equality (`$bweqx`) and bitwise mux (`$bwmux`) cells enable compact encoding and decoding of 3-valued logic signals using multiple 2-valued signals.
This commit is contained in:
parent
f2c531e65f
commit
7203ba7bc1
|
@ -690,5 +690,28 @@ RTLIL::Const RTLIL::const_demux(const RTLIL::Const &arg1, const RTLIL::Const &ar
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RTLIL::Const RTLIL::const_bweqx(const RTLIL::Const &arg1, const RTLIL::Const &arg2)
|
||||||
|
{
|
||||||
|
log_assert(arg2.size() == arg1.size());
|
||||||
|
RTLIL::Const result(RTLIL::State::S0, arg1.size());
|
||||||
|
for (int i = 0; i < arg1.size(); i++)
|
||||||
|
result[i] = arg1[i] == arg2[i] ? State::S1 : State::S0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
RTLIL::Const RTLIL::const_bwmux(const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3)
|
||||||
|
{
|
||||||
|
log_assert(arg2.size() == arg1.size());
|
||||||
|
log_assert(arg3.size() == arg1.size());
|
||||||
|
RTLIL::Const result(RTLIL::State::Sx, arg1.size());
|
||||||
|
for (int i = 0; i < arg1.size(); i++) {
|
||||||
|
if (arg3[i] != State::Sx || arg1[i] == arg2[i])
|
||||||
|
result[i] = arg3[i] == State::S1 ? arg2[i] : arg1[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
YOSYS_NAMESPACE_END
|
YOSYS_NAMESPACE_END
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,8 @@ struct CellTypes
|
||||||
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
|
ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
|
||||||
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
|
ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
|
||||||
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow),
|
ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($divfloor), ID($modfloor), ID($pow),
|
||||||
ID($logic_and), ID($logic_or), ID($concat), ID($macc)
|
ID($logic_and), ID($logic_or), ID($concat), ID($macc),
|
||||||
|
ID($bweqx)
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto type : unary_ops)
|
for (auto type : unary_ops)
|
||||||
|
@ -125,7 +126,7 @@ struct CellTypes
|
||||||
for (auto type : binary_ops)
|
for (auto type : binary_ops)
|
||||||
setup_type(type, {ID::A, ID::B}, {ID::Y}, true);
|
setup_type(type, {ID::A, ID::B}, {ID::Y}, true);
|
||||||
|
|
||||||
for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux)}))
|
for (auto type : std::vector<RTLIL::IdString>({ID($mux), ID($pmux), ID($bwmux)}))
|
||||||
setup_type(type, {ID::A, ID::B, ID::S}, {ID::Y}, true);
|
setup_type(type, {ID::A, ID::B, ID::S}, {ID::Y}, true);
|
||||||
|
|
||||||
for (auto type : std::vector<RTLIL::IdString>({ID($bmux), ID($demux)}))
|
for (auto type : std::vector<RTLIL::IdString>({ID($bmux), ID($demux)}))
|
||||||
|
@ -430,6 +431,11 @@ struct CellTypes
|
||||||
return const_demux(arg1, arg2);
|
return const_demux(arg1, arg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cell->type == ID($bweqx))
|
||||||
|
{
|
||||||
|
return const_bweqx(arg1, arg2);
|
||||||
|
}
|
||||||
|
|
||||||
if (cell->type == ID($lut))
|
if (cell->type == ID($lut))
|
||||||
{
|
{
|
||||||
int width = cell->parameters.at(ID::WIDTH).as_int();
|
int width = cell->parameters.at(ID::WIDTH).as_int();
|
||||||
|
@ -490,6 +496,8 @@ struct CellTypes
|
||||||
{
|
{
|
||||||
if (cell->type.in(ID($mux), ID($_MUX_)))
|
if (cell->type.in(ID($mux), ID($_MUX_)))
|
||||||
return const_mux(arg1, arg2, arg3);
|
return const_mux(arg1, arg2, arg3);
|
||||||
|
if (cell->type == ID($bwmux))
|
||||||
|
return const_bwmux(arg1, arg2, arg3);
|
||||||
if (cell->type == ID($pmux))
|
if (cell->type == ID($pmux))
|
||||||
return const_pmux(arg1, arg2, arg3);
|
return const_pmux(arg1, arg2, arg3);
|
||||||
if (cell->type == ID($_AOI3_))
|
if (cell->type == ID($_AOI3_))
|
||||||
|
|
|
@ -1613,6 +1613,23 @@ namespace {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cell->type == ID($bweqx)) {
|
||||||
|
port(ID::A, param(ID::WIDTH));
|
||||||
|
port(ID::B, param(ID::WIDTH));
|
||||||
|
port(ID::Y, param(ID::WIDTH));
|
||||||
|
check_expected();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell->type == ID($bwmux)) {
|
||||||
|
port(ID::A, param(ID::WIDTH));
|
||||||
|
port(ID::B, param(ID::WIDTH));
|
||||||
|
port(ID::S, param(ID::WIDTH));
|
||||||
|
port(ID::Y, param(ID::WIDTH));
|
||||||
|
check_expected();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
|
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover))) {
|
||||||
port(ID::A, 1);
|
port(ID::A, 1);
|
||||||
port(ID::EN, 1);
|
port(ID::EN, 1);
|
||||||
|
@ -2466,6 +2483,7 @@ DEF_METHOD(Sshr, sig_a.size(), ID($sshr))
|
||||||
return sig_y; \
|
return sig_y; \
|
||||||
}
|
}
|
||||||
DEF_METHOD(Mux, ID($mux), 0)
|
DEF_METHOD(Mux, ID($mux), 0)
|
||||||
|
DEF_METHOD(Bwmux, ID($bwmux), 0)
|
||||||
DEF_METHOD(Pmux, ID($pmux), 1)
|
DEF_METHOD(Pmux, ID($pmux), 1)
|
||||||
#undef DEF_METHOD
|
#undef DEF_METHOD
|
||||||
|
|
||||||
|
@ -2489,6 +2507,24 @@ DEF_METHOD(Bmux, ID($bmux), 0)
|
||||||
DEF_METHOD(Demux, ID($demux), 1)
|
DEF_METHOD(Demux, ID($demux), 1)
|
||||||
#undef DEF_METHOD
|
#undef DEF_METHOD
|
||||||
|
|
||||||
|
#define DEF_METHOD(_func, _type) \
|
||||||
|
RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src) { \
|
||||||
|
RTLIL::Cell *cell = addCell(name, _type); \
|
||||||
|
cell->parameters[ID::WIDTH] = sig_a.size(); \
|
||||||
|
cell->setPort(ID::A, sig_a); \
|
||||||
|
cell->setPort(ID::B, sig_b); \
|
||||||
|
cell->setPort(ID::Y, sig_y); \
|
||||||
|
cell->set_src_attribute(src); \
|
||||||
|
return cell; \
|
||||||
|
} \
|
||||||
|
RTLIL::SigSpec RTLIL::Module::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src) { \
|
||||||
|
RTLIL::SigSpec sig_y = addWire(NEW_ID, sig_a.size()); \
|
||||||
|
add ## _func(name, sig_a, sig_s, sig_y, src); \
|
||||||
|
return sig_y; \
|
||||||
|
}
|
||||||
|
DEF_METHOD(Bweqx, ID($bweqx))
|
||||||
|
#undef DEF_METHOD
|
||||||
|
|
||||||
#define DEF_METHOD_2(_func, _type, _P1, _P2) \
|
#define DEF_METHOD_2(_func, _type, _P1, _P2) \
|
||||||
RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \
|
RTLIL::Cell* RTLIL::Module::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const std::string &src) { \
|
||||||
RTLIL::Cell *cell = addCell(name, _type); \
|
RTLIL::Cell *cell = addCell(name, _type); \
|
||||||
|
|
|
@ -505,6 +505,9 @@ namespace RTLIL
|
||||||
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);
|
||||||
|
|
||||||
|
RTLIL::Const const_bweqx (const RTLIL::Const &arg1, const RTLIL::Const &arg2);
|
||||||
|
RTLIL::Const const_bwmux (const RTLIL::Const &arg1, const RTLIL::Const &arg2, const RTLIL::Const &arg3);
|
||||||
|
|
||||||
|
|
||||||
// This iterator-range-pair is used for Design::modules(), Module::wires() and Module::cells().
|
// This iterator-range-pair is used for Design::modules(), Module::wires() and Module::cells().
|
||||||
// It maintains a reference counter that is used to make sure that the container is not modified while being iterated over.
|
// It maintains a reference counter that is used to make sure that the container is not modified while being iterated over.
|
||||||
|
@ -1303,6 +1306,9 @@ public:
|
||||||
RTLIL::Cell* addBmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
RTLIL::Cell* addBmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
||||||
RTLIL::Cell* addDemux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
RTLIL::Cell* addDemux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
||||||
|
|
||||||
|
RTLIL::Cell* addBweqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
||||||
|
RTLIL::Cell* addBwmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
||||||
|
|
||||||
RTLIL::Cell* addSlice (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src = "");
|
RTLIL::Cell* addSlice (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const std::string &src = "");
|
||||||
RTLIL::Cell* addConcat (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
RTLIL::Cell* addConcat (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const std::string &src = "");
|
||||||
RTLIL::Cell* addLut (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src = "");
|
RTLIL::Cell* addLut (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const std::string &src = "");
|
||||||
|
@ -1432,6 +1438,9 @@ public:
|
||||||
RTLIL::SigSpec Bmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src = "");
|
RTLIL::SigSpec Bmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src = "");
|
||||||
RTLIL::SigSpec Demux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src = "");
|
RTLIL::SigSpec Demux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const std::string &src = "");
|
||||||
|
|
||||||
|
RTLIL::SigSpec Bweqx (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const std::string &src = "");
|
||||||
|
RTLIL::SigSpec Bwmux (RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const std::string &src = "");
|
||||||
|
|
||||||
RTLIL::SigBit BufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
|
RTLIL::SigBit BufGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
|
||||||
RTLIL::SigBit NotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
|
RTLIL::SigBit NotGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const std::string &src = "");
|
||||||
RTLIL::SigBit AndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
|
RTLIL::SigBit AndGate (RTLIL::IdString name, const RTLIL::SigBit &sig_a, const RTLIL::SigBit &sig_b, const std::string &src = "");
|
||||||
|
|
|
@ -223,7 +223,33 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_)))
|
if (cell->type == ID($bweqx))
|
||||||
|
{
|
||||||
|
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
||||||
|
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
|
||||||
|
std::vector<int> y = importDefSigSpec(cell->getPort(ID::Y), timestep);
|
||||||
|
|
||||||
|
std::vector<int> bweqx = ez->vec_not(ez->vec_xor(a, b));
|
||||||
|
|
||||||
|
if (model_undef)
|
||||||
|
{
|
||||||
|
std::vector<int> undef_a = importUndefSigSpec(cell->getPort(ID::A), timestep);
|
||||||
|
std::vector<int> undef_b = importUndefSigSpec(cell->getPort(ID::B), timestep);
|
||||||
|
std::vector<int> undef_y = importUndefSigSpec(cell->getPort(ID::Y), timestep);
|
||||||
|
|
||||||
|
std::vector<int> both_undef = ez->vec_and(undef_a, undef_b);
|
||||||
|
std::vector<int> both_def = ez->vec_and(ez->vec_not(undef_a), ez->vec_not(undef_b));
|
||||||
|
|
||||||
|
bweqx = ez->vec_or(both_undef, ez->vec_and(both_def, bweqx));
|
||||||
|
|
||||||
|
for (int yx : undef_y)
|
||||||
|
ez->assume(ez->NOT(yx));
|
||||||
|
}
|
||||||
|
ez->assume(ez->vec_eq(bweqx, y));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cell->type.in(ID($_MUX_), ID($mux), ID($_NMUX_), ID($bwmux)))
|
||||||
{
|
{
|
||||||
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
std::vector<int> a = importDefSigSpec(cell->getPort(ID::A), timestep);
|
||||||
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
|
std::vector<int> b = importDefSigSpec(cell->getPort(ID::B), timestep);
|
||||||
|
@ -233,6 +259,8 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||||
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
|
std::vector<int> yy = model_undef ? ez->vec_var(y.size()) : y;
|
||||||
if (cell->type == ID($_NMUX_))
|
if (cell->type == ID($_NMUX_))
|
||||||
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy));
|
ez->assume(ez->vec_eq(ez->vec_not(ez->vec_ite(s.at(0), b, a)), yy));
|
||||||
|
else if (cell->type == ID($bwmux))
|
||||||
|
ez->assume(ez->vec_eq(ez->vec_ite(s, b, a), yy));
|
||||||
else
|
else
|
||||||
ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));
|
ez->assume(ez->vec_eq(ez->vec_ite(s.at(0), b, a), yy));
|
||||||
|
|
||||||
|
@ -245,7 +273,11 @@ bool SatGen::importCell(RTLIL::Cell *cell, int timestep)
|
||||||
|
|
||||||
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
|
std::vector<int> unequal_ab = ez->vec_not(ez->vec_iff(a, b));
|
||||||
std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b));
|
std::vector<int> undef_ab = ez->vec_or(unequal_ab, ez->vec_or(undef_a, undef_b));
|
||||||
std::vector<int> yX = ez->vec_ite(undef_s.at(0), undef_ab, ez->vec_ite(s.at(0), undef_b, undef_a));
|
std::vector<int> yX;
|
||||||
|
if (cell->type == ID($bwmux))
|
||||||
|
yX = ez->vec_ite(undef_s, undef_ab, ez->vec_ite(s, undef_b, undef_a));
|
||||||
|
else
|
||||||
|
yX = ez->vec_ite(undef_s.at(0), undef_ab, ez->vec_ite(s.at(0), undef_b, undef_a));
|
||||||
ez->assume(ez->vec_eq(yX, undef_y));
|
ez->assume(ez->vec_eq(yX, undef_y));
|
||||||
undefGating(y, yy, undef_y);
|
undefGating(y, yy, undef_y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,14 +58,17 @@ void simplemap_bitop(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
|
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
|
||||||
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
|
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
|
||||||
|
|
||||||
|
if (cell->type != ID($bweqx)) {
|
||||||
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
|
sig_a.extend_u0(GetSize(sig_y), cell->parameters.at(ID::A_SIGNED).as_bool());
|
||||||
sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID::B_SIGNED).as_bool());
|
sig_b.extend_u0(GetSize(sig_y), cell->parameters.at(ID::B_SIGNED).as_bool());
|
||||||
|
}
|
||||||
|
|
||||||
IdString gate_type;
|
IdString gate_type;
|
||||||
if (cell->type == ID($and)) gate_type = ID($_AND_);
|
if (cell->type == ID($and)) gate_type = ID($_AND_);
|
||||||
if (cell->type == ID($or)) gate_type = ID($_OR_);
|
if (cell->type == ID($or)) gate_type = ID($_OR_);
|
||||||
if (cell->type == ID($xor)) gate_type = ID($_XOR_);
|
if (cell->type == ID($xor)) gate_type = ID($_XOR_);
|
||||||
if (cell->type == ID($xnor)) gate_type = ID($_XNOR_);
|
if (cell->type == ID($xnor)) gate_type = ID($_XNOR_);
|
||||||
|
if (cell->type == ID($bweqx)) gate_type = ID($_XNOR_);
|
||||||
log_assert(!gate_type.empty());
|
log_assert(!gate_type.empty());
|
||||||
|
|
||||||
for (int i = 0; i < GetSize(sig_y); i++) {
|
for (int i = 0; i < GetSize(sig_y); i++) {
|
||||||
|
@ -270,6 +273,23 @@ void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simplemap_bwmux(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
|
{
|
||||||
|
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
|
||||||
|
RTLIL::SigSpec sig_b = cell->getPort(ID::B);
|
||||||
|
RTLIL::SigSpec sig_s = cell->getPort(ID::S);
|
||||||
|
RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
|
||||||
|
|
||||||
|
for (int i = 0; i < GetSize(sig_y); i++) {
|
||||||
|
RTLIL::Cell *gate = module->addCell(NEW_ID, ID($_MUX_));
|
||||||
|
gate->add_strpool_attribute(ID::src, cell->get_strpool_attribute(ID::src));
|
||||||
|
gate->setPort(ID::A, sig_a[i]);
|
||||||
|
gate->setPort(ID::B, sig_b[i]);
|
||||||
|
gate->setPort(ID::S, sig_s[i]);
|
||||||
|
gate->setPort(ID::Y, sig_y[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
|
void simplemap_tribuf(RTLIL::Module *module, RTLIL::Cell *cell)
|
||||||
{
|
{
|
||||||
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
|
RTLIL::SigSpec sig_a = cell->getPort(ID::A);
|
||||||
|
@ -395,6 +415,7 @@ void simplemap_get_mappers(dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)>
|
||||||
mappers[ID($or)] = simplemap_bitop;
|
mappers[ID($or)] = simplemap_bitop;
|
||||||
mappers[ID($xor)] = simplemap_bitop;
|
mappers[ID($xor)] = simplemap_bitop;
|
||||||
mappers[ID($xnor)] = simplemap_bitop;
|
mappers[ID($xnor)] = simplemap_bitop;
|
||||||
|
mappers[ID($bweqx)] = simplemap_bitop;
|
||||||
mappers[ID($reduce_and)] = simplemap_reduce;
|
mappers[ID($reduce_and)] = simplemap_reduce;
|
||||||
mappers[ID($reduce_or)] = simplemap_reduce;
|
mappers[ID($reduce_or)] = simplemap_reduce;
|
||||||
mappers[ID($reduce_xor)] = simplemap_reduce;
|
mappers[ID($reduce_xor)] = simplemap_reduce;
|
||||||
|
@ -408,6 +429,7 @@ void simplemap_get_mappers(dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)>
|
||||||
mappers[ID($ne)] = simplemap_eqne;
|
mappers[ID($ne)] = simplemap_eqne;
|
||||||
mappers[ID($nex)] = simplemap_eqne;
|
mappers[ID($nex)] = simplemap_eqne;
|
||||||
mappers[ID($mux)] = simplemap_mux;
|
mappers[ID($mux)] = simplemap_mux;
|
||||||
|
mappers[ID($bwmux)] = simplemap_bwmux;
|
||||||
mappers[ID($tribuf)] = simplemap_tribuf;
|
mappers[ID($tribuf)] = simplemap_tribuf;
|
||||||
mappers[ID($bmux)] = simplemap_bmux;
|
mappers[ID($bmux)] = simplemap_bmux;
|
||||||
mappers[ID($lut)] = simplemap_lut;
|
mappers[ID($lut)] = simplemap_lut;
|
||||||
|
|
|
@ -31,6 +31,7 @@ extern void simplemap_reduce(RTLIL::Module *module, RTLIL::Cell *cell);
|
||||||
extern void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell);
|
extern void simplemap_lognot(RTLIL::Module *module, RTLIL::Cell *cell);
|
||||||
extern void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell);
|
extern void simplemap_logbin(RTLIL::Module *module, RTLIL::Cell *cell);
|
||||||
extern void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell);
|
extern void simplemap_mux(RTLIL::Module *module, RTLIL::Cell *cell);
|
||||||
|
extern void simplemap_bwmux(RTLIL::Module *module, RTLIL::Cell *cell);
|
||||||
extern void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell);
|
extern void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell);
|
||||||
extern void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell);
|
extern void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell);
|
||||||
extern void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell);
|
extern void simplemap_concat(RTLIL::Module *module, RTLIL::Cell *cell);
|
||||||
|
|
|
@ -1601,6 +1601,43 @@ endmodule
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
module \$bweqx (A, B, Y);
|
||||||
|
|
||||||
|
parameter WIDTH = 0;
|
||||||
|
|
||||||
|
input [WIDTH-1:0] A, B;
|
||||||
|
output [WIDTH-1:0] Y;
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
for (i = 0; i < WIDTH; i = i + 1) begin:slices
|
||||||
|
assign Y[i] = A[i] === B[i];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
|
module \$bwmux (A, B, S, Y);
|
||||||
|
|
||||||
|
parameter WIDTH = 0;
|
||||||
|
|
||||||
|
input [WIDTH-1:0] A, B;
|
||||||
|
input [WIDTH-1:0] S;
|
||||||
|
output [WIDTH-1:0] Y;
|
||||||
|
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
for (i = 0; i < WIDTH; i = i + 1) begin:slices
|
||||||
|
assign Y[i] = S[i] ? B[i] : A[i];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
|
||||||
module \$assert (A, EN);
|
module \$assert (A, EN);
|
||||||
|
|
||||||
input A, EN;
|
input A, EN;
|
||||||
|
|
|
@ -59,7 +59,7 @@ module _90_simplemap_compare_ops;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
(* techmap_simplemap *)
|
(* techmap_simplemap *)
|
||||||
(* techmap_celltype = "$pos $slice $concat $mux $tribuf $bmux" *)
|
(* techmap_celltype = "$pos $slice $concat $mux $tribuf $bmux $bwmux $bweqx" *)
|
||||||
module _90_simplemap_various;
|
module _90_simplemap_various;
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue