diff --git a/Makefile b/Makefile index ff3b68768..d46ff6208 100644 --- a/Makefile +++ b/Makefile @@ -155,7 +155,7 @@ ifeq ($(OS), Haiku) CXXFLAGS += -D_DEFAULT_SOURCE endif -YOSYS_VER := 0.46+11 +YOSYS_VER := 0.46+20 # Note: We arrange for .gitcommit to contain the (short) commit hash in # tarballs generated with git-archive(1) using .gitattributes. The git repo diff --git a/backends/cxxrtl/runtime/cxxrtl/cxxrtl_vcd.h b/backends/cxxrtl/runtime/cxxrtl/cxxrtl_vcd.h index e4c9a6770..e8be70028 100644 --- a/backends/cxxrtl/runtime/cxxrtl/cxxrtl_vcd.h +++ b/backends/cxxrtl/runtime/cxxrtl/cxxrtl_vcd.h @@ -127,6 +127,8 @@ class vcd_writer { bool bit_curr = var.curr[bit / (8 * sizeof(chunk_t))] & (1 << (bit % (8 * sizeof(chunk_t)))); buffer += (bit_curr ? '1' : '0'); } + if (var.width == 0) + buffer += '0'; buffer += ' '; emit_ident(var.ident); buffer += '\n'; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 7092eb0ed..54ac0019c 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -28,6 +28,7 @@ #include #include +#include YOSYS_NAMESPACE_BEGIN @@ -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 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 713718499..c55587e52 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -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 as_int_compress(bool is_signed) const; + void extu(int width) { bits.resize(width, RTLIL::State::S0); }