mirror of https://github.com/YosysHQ/yosys.git
cxxrtl: ignore cell input signedness when it is irrelevant.
Before this commit, Verilog expressions like `x && 1` would result in references to `logic_and_us` in generated CXXRTL code, which would not compile. After this commit, since cells like that actually behave the same regardless of signedness attributes, the signedness is ignored, which also reduces the template instantiation pressure.
This commit is contained in:
parent
4351194e8c
commit
ef4e159447
|
@ -829,6 +829,48 @@ constexpr T max(const T &a, const T &b) {
|
|||
|
||||
// Logic operations
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> logic_not(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 0u : 1u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
value<BitsY> logic_and(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return value<BitsY> { (bool(a) & bool(b)) ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
value<BitsY> logic_or(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return value<BitsY> { (bool(a) | bool(b)) ? 1u : 0u };
|
||||
}
|
||||
|
||||
// Reduction operations
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_and(const value<BitsA> &a) {
|
||||
return value<BitsY> { a.bit_not().is_zero() ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_or(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_xor(const value<BitsA> &a) {
|
||||
return value<BitsY> { (a.ctpop() % 2) ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_xnor(const value<BitsA> &a) {
|
||||
return value<BitsY> { (a.ctpop() % 2) ? 0u : 1u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_bool(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 1u : 0u };
|
||||
}
|
||||
|
||||
// Bitwise operations
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> not_u(const value<BitsA> &a) {
|
||||
return a.template zcast<BitsY>().bit_not();
|
||||
}
|
||||
|
@ -838,66 +880,6 @@ value<BitsY> not_s(const value<BitsA> &a) {
|
|||
return a.template scast<BitsY>().bit_not();
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> logic_not_u(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 0u : 1u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> logic_not_s(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 0u : 1u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_and_u(const value<BitsA> &a) {
|
||||
return value<BitsY> { a.bit_not().is_zero() ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_and_s(const value<BitsA> &a) {
|
||||
return value<BitsY> { a.bit_not().is_zero() ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_or_u(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_or_s(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_xor_u(const value<BitsA> &a) {
|
||||
return value<BitsY> { (a.ctpop() % 2) ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_xor_s(const value<BitsA> &a) {
|
||||
return value<BitsY> { (a.ctpop() % 2) ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_xnor_u(const value<BitsA> &a) {
|
||||
return value<BitsY> { (a.ctpop() % 2) ? 0u : 1u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_xnor_s(const value<BitsA> &a) {
|
||||
return value<BitsY> { (a.ctpop() % 2) ? 0u : 1u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_bool_u(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA>
|
||||
value<BitsY> reduce_bool_s(const value<BitsA> &a) {
|
||||
return value<BitsY> { a ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
value<BitsY> and_uu(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return a.template zcast<BitsY>().bit_and(b.template zcast<BitsY>());
|
||||
|
@ -938,26 +920,6 @@ value<BitsY> xnor_ss(const value<BitsA> &a, const value<BitsB> &b) {
|
|||
return a.template scast<BitsY>().bit_xor(b.template scast<BitsY>()).bit_not();
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
value<BitsY> logic_and_uu(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return value<BitsY> { (bool(a) & bool(b)) ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
value<BitsY> logic_and_ss(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return value<BitsY> { (bool(a) & bool(b)) ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
value<BitsY> logic_or_uu(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return value<BitsY> { (bool(a) | bool(b)) ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
value<BitsY> logic_or_ss(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return value<BitsY> { (bool(a) | bool(b)) ? 1u : 0u };
|
||||
}
|
||||
|
||||
template<size_t BitsY, size_t BitsA, size_t BitsB>
|
||||
value<BitsY> shl_uu(const value<BitsA> &a, const value<BitsB> &b) {
|
||||
return a.template zcast<BitsY>().template shl(b);
|
||||
|
|
|
@ -192,6 +192,13 @@ bool is_binary_cell(RTLIL::IdString type)
|
|||
ID($add), ID($sub), ID($mul), ID($div), ID($mod));
|
||||
}
|
||||
|
||||
bool is_extending_cell(RTLIL::IdString type)
|
||||
{
|
||||
return !type.in(
|
||||
ID($logic_not), ID($logic_and), ID($logic_or),
|
||||
ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool));
|
||||
}
|
||||
|
||||
bool is_elidable_cell(RTLIL::IdString type)
|
||||
{
|
||||
return is_unary_cell(type) || is_binary_cell(type) || type.in(
|
||||
|
@ -907,17 +914,19 @@ struct CxxrtlWorker {
|
|||
{
|
||||
// Unary cells
|
||||
if (is_unary_cell(cell->type)) {
|
||||
f << cell->type.substr(1) << '_' <<
|
||||
(cell->getParam(ID::A_SIGNED).as_bool() ? 's' : 'u') <<
|
||||
"<" << cell->getParam(ID::Y_WIDTH).as_int() << ">(";
|
||||
f << cell->type.substr(1);
|
||||
if (is_extending_cell(cell->type))
|
||||
f << '_' << (cell->getParam(ID::A_SIGNED).as_bool() ? 's' : 'u');
|
||||
f << "<" << cell->getParam(ID::Y_WIDTH).as_int() << ">(";
|
||||
dump_sigspec_rhs(cell->getPort(ID::A));
|
||||
f << ")";
|
||||
// Binary cells
|
||||
} else if (is_binary_cell(cell->type)) {
|
||||
f << cell->type.substr(1) << '_' <<
|
||||
(cell->getParam(ID::A_SIGNED).as_bool() ? 's' : 'u') <<
|
||||
(cell->getParam(ID::B_SIGNED).as_bool() ? 's' : 'u') <<
|
||||
"<" << cell->getParam(ID::Y_WIDTH).as_int() << ">(";
|
||||
f << cell->type.substr(1);
|
||||
if (is_extending_cell(cell->type))
|
||||
f << '_' << (cell->getParam(ID::A_SIGNED).as_bool() ? 's' : 'u') <<
|
||||
(cell->getParam(ID::B_SIGNED).as_bool() ? 's' : 'u');
|
||||
f << "<" << cell->getParam(ID::Y_WIDTH).as_int() << ">(";
|
||||
dump_sigspec_rhs(cell->getPort(ID::A));
|
||||
f << ", ";
|
||||
dump_sigspec_rhs(cell->getPort(ID::B));
|
||||
|
|
Loading…
Reference in New Issue