Skip to content

Commit

Permalink
Merge pull request #4608 from phsauter/rtlil-const-compress
Browse files Browse the repository at this point in the history
rtlil: add Const::compress helper function
  • Loading branch information
widlarizer authored Oct 13, 2024
2 parents 7f2bf31 + c53c87e commit 61ed9b6
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
47 changes: 47 additions & 0 deletions kernel/rtlil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <string.h>
#include <algorithm>
#include <optional>

YOSYS_NAMESPACE_BEGIN

Expand Down Expand Up @@ -280,6 +281,52 @@ int RTLIL::Const::as_int(bool is_signed) const
return ret;
}

size_t RTLIL::Const::get_min_size(bool is_signed) const
{
if (bits.empty()) return 0;

// 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++;
}
// must be at least one bit
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<int> 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;
Expand Down
8 changes: 8 additions & 0 deletions kernel/rtlil.h
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +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<int> as_int_compress(bool is_signed) const;

void extu(int width) {
bits.resize(width, RTLIL::State::S0);
}
Expand Down

0 comments on commit 61ed9b6

Please sign in to comment.