Skip to content

Commit 61ed9b6

Browse files
authored
Merge pull request #4608 from phsauter/rtlil-const-compress
rtlil: add Const::compress helper function
2 parents 7f2bf31 + c53c87e commit 61ed9b6

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

kernel/rtlil.cc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
#include <string.h>
3030
#include <algorithm>
31+
#include <optional>
3132

3233
YOSYS_NAMESPACE_BEGIN
3334

@@ -280,6 +281,52 @@ int RTLIL::Const::as_int(bool is_signed) const
280281
return ret;
281282
}
282283

284+
size_t RTLIL::Const::get_min_size(bool is_signed) const
285+
{
286+
if (bits.empty()) return 0;
287+
288+
// back to front (MSB to LSB)
289+
RTLIL::State leading_bit;
290+
if (is_signed)
291+
leading_bit = (bits.back() == RTLIL::State::Sx) ? RTLIL::State::S0 : bits.back();
292+
else
293+
leading_bit = RTLIL::State::S0;
294+
295+
size_t idx = bits.size();
296+
while (idx > 0 && bits[idx -1] == leading_bit) {
297+
idx--;
298+
}
299+
300+
// signed needs one leading bit
301+
if (is_signed && idx < bits.size()) {
302+
idx++;
303+
}
304+
// must be at least one bit
305+
return (idx == 0) ? 1 : idx;
306+
}
307+
308+
void RTLIL::Const::compress(bool is_signed)
309+
{
310+
size_t idx = get_min_size(is_signed);
311+
bits.erase(bits.begin() + idx, bits.end());
312+
}
313+
314+
std::optional<int> RTLIL::Const::as_int_compress(bool is_signed) const
315+
{
316+
size_t size = get_min_size(is_signed);
317+
if(size == 0 || size > 32)
318+
return std::nullopt;
319+
320+
int32_t ret = 0;
321+
for (size_t i = 0; i < size && i < 32; i++)
322+
if (bits[i] == State::S1)
323+
ret |= 1 << i;
324+
if (is_signed && bits[size-1] == State::S1)
325+
for (size_t i = size; i < 32; i++)
326+
ret |= 1 << i;
327+
return ret;
328+
}
329+
283330
std::string RTLIL::Const::as_string() const
284331
{
285332
std::string ret;

kernel/rtlil.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,14 @@ struct RTLIL::Const
703703
return ret;
704704
}
705705

706+
// find the MSB without redundant leading bits
707+
size_t get_min_size(bool is_signed) const;
708+
709+
// compress representation to the minimum required bits
710+
void compress(bool is_signed = false);
711+
712+
std::optional<int> as_int_compress(bool is_signed) const;
713+
706714
void extu(int width) {
707715
bits.resize(width, RTLIL::State::S0);
708716
}

0 commit comments

Comments
 (0)