diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index dd78b202d..9f5972c32 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -380,6 +380,30 @@ int RTLIL::Const::as_int(bool is_signed) const return ret; } +bool RTLIL::Const::convertible_to_int(bool is_signed) const +{ + auto size = get_min_size(is_signed); + return (size > 0 && size <= 32); +} + +std::optional RTLIL::Const::try_as_int(bool is_signed) const +{ + if (!convertible_to_int(is_signed)) + return std::nullopt; + return as_int(is_signed); +} + +int RTLIL::Const::as_int_saturating(bool is_signed) const +{ + if (!convertible_to_int(is_signed)) { + const auto min_size = get_min_size(is_signed); + log_assert(min_size > 0); + const auto neg = get_bits().at(min_size - 1); + return neg ? std::numeric_limits::min() : std::numeric_limits::max(); + } + return as_int(is_signed); +} + int RTLIL::Const::get_min_size(bool is_signed) const { if (empty()) return 0; @@ -5462,6 +5486,38 @@ int RTLIL::SigSpec::as_int(bool is_signed) const return 0; } +bool RTLIL::SigSpec::convertible_to_int(bool is_signed) const +{ + cover("kernel.rtlil.sigspec.convertible_to_int"); + + pack(); + if (!is_fully_const()) + return false; + + return RTLIL::Const(chunks_[0].data).convertible_to_int(is_signed); +} + +std::optional RTLIL::SigSpec::try_as_int(bool is_signed) const +{ + cover("kernel.rtlil.sigspec.try_as_int"); + + pack(); + if (!is_fully_const()) + return std::nullopt; + + return RTLIL::Const(chunks_[0].data).try_as_int(is_signed); +} + +int RTLIL::SigSpec::as_int_saturating(bool is_signed) const +{ + cover("kernel.rtlil.sigspec.try_as_int"); + + pack(); + log_assert(is_fully_const() && GetSize(chunks_) <= 1); + log_assert(!empty()); + return RTLIL::Const(chunks_[0].data).as_int_saturating(is_signed); +} + std::string RTLIL::SigSpec::as_string() const { cover("kernel.rtlil.sigspec.as_string"); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index 96c8c523b..50c96c71b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -754,6 +754,9 @@ public: std::vector& bits(); bool as_bool() const; int as_int(bool is_signed = false) const; + bool convertible_to_int(bool is_signed = false) const; + std::optional try_as_int(bool is_signed = false) const; + int as_int_saturating(bool is_signed = false) const; std::string as_string(const char* any = "-") const; static Const from_string(const std::string &str); std::vector to_bits() const; @@ -1131,6 +1134,9 @@ public: bool as_bool() const; int as_int(bool is_signed = false) const; + bool convertible_to_int(bool is_signed = false) const; + std::optional try_as_int(bool is_signed = false) const; + int as_int_saturating(bool is_signed = false) const; std::string as_string() const; RTLIL::Const as_const() const; RTLIL::Wire *as_wire() const;