diff options
author | whitequark <whitequark@whitequark.org> | 2020-06-09 09:54:09 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-09 09:54:09 +0000 |
commit | 74e3ac2449f521a50d5e88daa951acee1062e620 (patch) | |
tree | f4f51475500f800019bfeea2c72a554bb4364e00 /backends/cxxrtl | |
parent | c172b30c24285faa2b57f84a2a5162c5f3dcfb4c (diff) | |
parent | ef4e1594470b46eab6f311998511a5eee22a96d3 (diff) | |
download | yosys-74e3ac2449f521a50d5e88daa951acee1062e620.tar.gz yosys-74e3ac2449f521a50d5e88daa951acee1062e620.tar.bz2 yosys-74e3ac2449f521a50d5e88daa951acee1062e620.zip |
Merge pull request #2126 from whitequark/cxxrtl-non-ext-logic-ops
cxxrtl: ignore cell input signedness when it is irrelevant
Diffstat (limited to 'backends/cxxrtl')
-rw-r--r-- | backends/cxxrtl/cxxrtl.h | 76 | ||||
-rw-r--r-- | backends/cxxrtl/cxxrtl_backend.cc | 23 |
2 files changed, 35 insertions, 64 deletions
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,73 +829,55 @@ constexpr T max(const T &a, const T &b) { // Logic operations template<size_t BitsY, size_t BitsA> -value<BitsY> not_u(const value<BitsA> &a) { - return a.template zcast<BitsY>().bit_not(); -} - -template<size_t BitsY, size_t BitsA> -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) { +value<BitsY> logic_not(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, 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> -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, 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_s(const value<BitsA> &a) { +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_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) { +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_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) { +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_u(const value<BitsA> &a) { +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_xnor_s(const value<BitsA> &a) { - return value<BitsY> { (a.ctpop() % 2) ? 0u : 1u }; +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> reduce_bool_u(const value<BitsA> &a) { - return value<BitsY> { a ? 1u : 0u }; +value<BitsY> not_u(const value<BitsA> &a) { + return a.template zcast<BitsY>().bit_not(); } template<size_t BitsY, size_t BitsA> -value<BitsY> reduce_bool_s(const value<BitsA> &a) { - return value<BitsY> { a ? 1u : 0u }; +value<BitsY> not_s(const value<BitsA> &a) { + return a.template scast<BitsY>().bit_not(); } template<size_t BitsY, size_t BitsA, size_t BitsB> @@ -939,26 +921,6 @@ value<BitsY> xnor_ss(const value<BitsA> &a, const value<BitsB> &b) { } 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); } 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)); |