diff --git a/backends/cxxrtl/cxxrtl.h b/backends/cxxrtl/cxxrtl.h index 30f4667c5..c988c9e80 100644 --- a/backends/cxxrtl/cxxrtl.h +++ b/backends/cxxrtl/cxxrtl.h @@ -829,6 +829,48 @@ constexpr T max(const T &a, const T &b) { // Logic operations template +value logic_not(const value &a) { + return value { a ? 0u : 1u }; +} + +template +value logic_and(const value &a, const value &b) { + return value { (bool(a) & bool(b)) ? 1u : 0u }; +} + +template +value logic_or(const value &a, const value &b) { + return value { (bool(a) | bool(b)) ? 1u : 0u }; +} + +// Reduction operations +template +value reduce_and(const value &a) { + return value { a.bit_not().is_zero() ? 1u : 0u }; +} + +template +value reduce_or(const value &a) { + return value { a ? 1u : 0u }; +} + +template +value reduce_xor(const value &a) { + return value { (a.ctpop() % 2) ? 1u : 0u }; +} + +template +value reduce_xnor(const value &a) { + return value { (a.ctpop() % 2) ? 0u : 1u }; +} + +template +value reduce_bool(const value &a) { + return value { a ? 1u : 0u }; +} + +// Bitwise operations +template value not_u(const value &a) { return a.template zcast().bit_not(); } @@ -838,66 +880,6 @@ value not_s(const value &a) { return a.template scast().bit_not(); } -template -value logic_not_u(const value &a) { - return value { a ? 0u : 1u }; -} - -template -value logic_not_s(const value &a) { - return value { a ? 0u : 1u }; -} - -template -value reduce_and_u(const value &a) { - return value { a.bit_not().is_zero() ? 1u : 0u }; -} - -template -value reduce_and_s(const value &a) { - return value { a.bit_not().is_zero() ? 1u : 0u }; -} - -template -value reduce_or_u(const value &a) { - return value { a ? 1u : 0u }; -} - -template -value reduce_or_s(const value &a) { - return value { a ? 1u : 0u }; -} - -template -value reduce_xor_u(const value &a) { - return value { (a.ctpop() % 2) ? 1u : 0u }; -} - -template -value reduce_xor_s(const value &a) { - return value { (a.ctpop() % 2) ? 1u : 0u }; -} - -template -value reduce_xnor_u(const value &a) { - return value { (a.ctpop() % 2) ? 0u : 1u }; -} - -template -value reduce_xnor_s(const value &a) { - return value { (a.ctpop() % 2) ? 0u : 1u }; -} - -template -value reduce_bool_u(const value &a) { - return value { a ? 1u : 0u }; -} - -template -value reduce_bool_s(const value &a) { - return value { a ? 1u : 0u }; -} - template value and_uu(const value &a, const value &b) { return a.template zcast().bit_and(b.template zcast()); @@ -938,26 +920,6 @@ value xnor_ss(const value &a, const value &b) { return a.template scast().bit_xor(b.template scast()).bit_not(); } -template -value logic_and_uu(const value &a, const value &b) { - return value { (bool(a) & bool(b)) ? 1u : 0u }; -} - -template -value logic_and_ss(const value &a, const value &b) { - return value { (bool(a) & bool(b)) ? 1u : 0u }; -} - -template -value logic_or_uu(const value &a, const value &b) { - return value { (bool(a) | bool(b)) ? 1u : 0u }; -} - -template -value logic_or_ss(const value &a, const value &b) { - return value { (bool(a) | bool(b)) ? 1u : 0u }; -} - template value shl_uu(const value &a, const value &b) { return a.template zcast().template shl(b); diff --git a/backends/cxxrtl/cxxrtl_backend.cc b/backends/cxxrtl/cxxrtl_backend.cc index bf01b263a..2646f9371 100644 --- a/backends/cxxrtl/cxxrtl_backend.cc +++ b/backends/cxxrtl/cxxrtl_backend.cc @@ -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));