diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 2d3135378..0a3d2082d 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -280,6 +280,30 @@ int RTLIL::Const::as_int(bool is_signed) const return ret; } +void RTLIL::Const::compress(bool is_signed) +{ + if (bits.empty()) return; + + // back to front (MSB to LSB) + RTLIL::State leading_bit; + if(is_signed) + leading_bit = (bits.back() == RTLIL::State::Sx) ? RTLIL::State::S0 : bits.back(); + else + leading_bit = RTLIL::State::S0; + + size_t idx = bits.size(); + while (idx > 0 && bits[idx -1] == leading_bit) { + --idx; + } + + // signed needs one leading bit + if (is_signed && idx < bits.size()) { + ++idx; + } + + bits.erase(bits.begin() + idx, bits.end()); +} + std::string RTLIL::Const::as_string() const { std::string ret; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c49734cd0..7f47bf288 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -703,6 +703,9 @@ struct RTLIL::Const return ret; } + // compress representation to the minimum required bits + void compress(bool is_signed = false); + void extu(int width) { bits.resize(width, RTLIL::State::S0); }