diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 4403b538211..0d2ddf42888 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -28,6 +28,7 @@ #include #include +#include YOSYS_NAMESPACE_BEGIN @@ -280,9 +281,9 @@ int RTLIL::Const::as_int(bool is_signed) const return ret; } -void RTLIL::Const::compress(bool is_signed) +size_t RTLIL::Const::get_min_size(bool is_signed) const { - if (bits.empty()) return; + if (bits.empty()) return 0; // back to front (MSB to LSB) RTLIL::State leading_bit; @@ -301,11 +302,31 @@ void RTLIL::Const::compress(bool is_signed) idx++; } // must be at least one bit - idx = (idx == 0) ? 1 : idx; + return (idx == 0) ? 1 : idx; +} +void RTLIL::Const::compress(bool is_signed) +{ + size_t idx = get_min_size(is_signed); bits.erase(bits.begin() + idx, bits.end()); } +std::optional RTLIL::Const::as_int_compress(bool is_signed) const +{ + size_t size = get_min_size(is_signed); + if(size == 0 || size > 32) + return std::nullopt; + + int32_t ret = 0; + for (size_t i = 0; i < size && i < 32; i++) + if (bits[i] == State::S1) + ret |= 1 << i; + if (is_signed && bits[size-1] == State::S1) + for (size_t i = size; i < 32; i++) + ret |= 1 << i; + return ret; +} + std::string RTLIL::Const::as_string() const { std::string ret; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 7f47bf2889b..c5a02458536 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -703,9 +703,14 @@ struct RTLIL::Const return ret; } + // find the MSB without redundant leading bits + size_t get_min_size(bool is_signed) const; + // compress representation to the minimum required bits void compress(bool is_signed = false); + std::optional as_int_compress(bool is_signed) const; + void extu(int width) { bits.resize(width, RTLIL::State::S0); }