slang::SVInt class

SystemVerilog arbitrary precision integer type. This type is designed to implement all of the operations supported by SystemVerilog expressions involving integer vectors. Each value has an arbitrary (but constant) size in bits, up to a maximum of 2**24-1.

Additionally, SVInt can represent a 4-state value, where each bit can take on additional states of X and Z.

Small integer values that fit within 64 bits are kept in a simple native integer. Otherwise, space is allocated on the heap. If there are any unknown bits in the number, an extra set of words are allocated adjacent in memory. The bits in these extra words indicate whether the corresponding bits in the low words are unknown or normal.

Public static functions

static auto fromString(string_view str) -> SVInt
static auto fromDigits(bitwidth_t bits, LiteralBase base, bool isSigned, bool anyUnknown, span<logic_t const> digits) -> SVInt
Construct from an array of digits.
static auto fromDouble(bitwidth_t bits, double value, bool isSigned) -> SVInt
Construct from a floating point value.
static auto conditional(const SVInt& condition, const SVInt& lhs, const SVInt& rhs) -> SVInt
Evaluates a conditional expression; i.e. condition ? left : right.
static auto logicalImpl(const SVInt& lhs, const SVInt& rhs) -> logic_t
Implements logical implication: lhs -> rhs. This is equivalent to (!lhs || rhs).
static auto logicalEquiv(const SVInt& lhs, const SVInt& rhs) -> logic_t
static auto concat(span<SVInt const> operands) -> SVInt
Concatenates one or more integers into one output integer.

Constructors, destructors, conversion operators

SVInt()
Simple default constructor for convenience, results in a 1 bit zero value.
SVInt(logic_t bit) explicit
Construct from a single bit that can be unknown.
template<typename T, typename = std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>>>
SVInt(T value)
Construct from a given integer value. Uses only the bits necessary to hold the value.
SVInt(bitwidth_t bits, uint64_t value, bool isSigned)
SVInt(bitwidth_t bits, span<const byte> bytes, bool isSigned)
Construct from numeric data already in memory as a range of bytes.
SVInt(const SVInt& other)
Copy construct.
SVInt(SVInt&& other) noexcept
Move construct.

Public functions

auto isSingleWord() const -> bool
Check if the integer can fit into a single 64-bit word.
auto getNumWords() const -> uint32_t
Gets the number of words required to hold the integer, including the unknown bits.
auto getRawPtr() const -> const uint64_t*
Gets a pointer to the underlying numeric data.
template<typename T, typename = std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>>>
auto as() const -> optional<T>
auto toDouble() const -> double
auto toFloat() const -> float
auto isNegative() const -> bool
auto isOdd() const -> bool
Check whether a number is odd or even. Ignores the unknown flag.
void setSigned(bool isSigned)
void setAllOnes()
Set all of the bits in the integer to 1, zero, X, or Z.
void flattenUnknowns()
Removes all unknown bits from the number, converting them to zeros.
void shrinkToFit()
auto pow(const SVInt& rhs) const -> SVInt
auto shl(const SVInt& rhs) const -> SVInt
Left shifting.
auto ashr(const SVInt& rhs) const -> SVInt
Arithmetic right shifting.
auto lshr(const SVInt& rhs) const -> SVInt
Logical right shifting.
auto replicate(const SVInt& times) const -> SVInt
Multiple concatenation/replication.
auto reductionOr() const -> logic_t
Reduces all of the bits in the integer to one by applying OR, AND, or XOR.
auto getActiveBits() const -> bitwidth_t
auto getMinRepresentedBits() const -> bitwidth_t
auto countLeadingZeros() const -> bitwidth_t
auto countLeadingOnes() const -> bitwidth_t
auto countOnes() const -> bitwidth_t
Count the number of 1 bits in the number.
auto countZeros() const -> bitwidth_t
Count the number of 0 bits in the number.
auto countXs() const -> bitwidth_t
Count the number of X bits in the number.
auto countZs() const -> bitwidth_t
Count the number of Z bits in the number.
auto slice(int32_t msb, int32_t lsb) const -> SVInt
Return a subset of the integer's bit range as a new integer.
void set(int32_t msb, int32_t lsb, const SVInt& value)
Replace a range of bits in the number with the given bit pattern.
auto sext(bitwidth_t bits) const -> SVInt
Perform sign extension to the given number of bits.
auto isSignExtendedFrom(bitwidth_t msb) const -> bool
Returns true if all bits in [bitWidth-1:msb] are exactly equal.
void signExtendFrom(bitwidth_t msb)
If bit msb is nonzero, duplicate it to all bits in [bitWidth-1:msb].
auto zext(bitwidth_t bits) const -> SVInt
Perform zero extension to the given number of bits.
auto extend(bitwidth_t bits, bool isSigned) const -> SVInt
auto trunc(bitwidth_t bits) const -> SVInt
Truncate the number to the given number of bits.
auto resize(bitwidth_t bits) const -> SVInt
auto reverse() const -> SVInt
Reverses the bit ordering of the number.
auto xnor(const SVInt& rhs) const -> SVInt
Bitwise xnor.
auto operator==(const SVInt& rhs) const -> logic_t

Friends

auto operator<<(std::ostream& os, const SVInt& rhs) -> std::ostream&
auto exactlyEqual(const SVInt& lhs, const SVInt& rhs) -> bool
Stricter equality, taking into account unknown bits.
auto condWildcardEqual(const SVInt& lhs, const SVInt& rhs) -> logic_t
auto caseXWildcardEqual(const SVInt& lhs, const SVInt& rhs) -> bool
auto caseZWildcardEqual(const SVInt& lhs, const SVInt& rhs) -> bool

Function documentation

static SVInt slang::SVInt::fromString(string_view str)

Constructs from a string (in SystemVerilog syntax). This is mostly for convenience; any errors will assert instead of being handled gracefully.

static logic_t slang::SVInt::logicalEquiv(const SVInt& lhs, const SVInt& rhs)

Implements logical equivalence: lhs <-> rhs. This is equivalent to ((lhs -> rhs) && (rhs -> lhs)).

slang::SVInt::SVInt(bitwidth_t bits, uint64_t value, bool isSigned)

Construct from a 64-bit value that can be given an arbitrarily large number of bits (sign extended if necessary).

template<typename T, typename = std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>>>
optional<T> slang::SVInt::as() const

Checks whether it's possible to convert the value to a simple built-in integer type and if so returns it.

double slang::SVInt::toDouble() const

Convert the integer to a double precision floating point value, rounding where necessary. Any unknown bits are converted to zero during conversion.

float slang::SVInt::toFloat() const

Convert the integer to a single precision floating point value, rounding where necessary. Any unknown bits are converted to zero during conversion.

bool slang::SVInt::isNegative() const

Check whether the number is negative. Note that this doesn't care about the sign flag; it simply looks at the highest bit to determine whether it is set.

void slang::SVInt::setSigned(bool isSigned)

Reinterpret the integer as a signed or unsigned value. This doesn't change the bits, only the representation.

void slang::SVInt::shrinkToFit()

Resize the number to be the minimum number of bits without changing the stored value. Note that this modifies the value in place.

SVInt slang::SVInt::pow(const SVInt& rhs) const

Power function. Note that the result will have the same bitwidth as this object. The value will be modulo the bit width.

bitwidth_t slang::SVInt::getActiveBits() const

Get the number of "active bits". An SVInt might have a large bit width but be set to a very small value, in which case it will have a low number of active bits.

bitwidth_t slang::SVInt::getMinRepresentedBits() const

Get the minimum number of bits required to hold this value, taking into account the sign flag and whether or not the value would be considered positive. Note that this ignores unknown bits.

bitwidth_t slang::SVInt::countLeadingZeros() const

Count the number of leading zeros. This doesn't do anything special for unknown values, so make sure you know what you're doing with it.

bitwidth_t slang::SVInt::countLeadingOnes() const

Count the number of leading ones. This doesn't do anything special for unknown values, so make sure you know what you're doing with it.

SVInt slang::SVInt::extend(bitwidth_t bits, bool isSigned) const

Extend the number to the given number of bits, performing sign extension if isSigned is true.

SVInt slang::SVInt::resize(bitwidth_t bits) const

Resize the number to the given number of bits, truncating if smaller, making a copy if the same size, zero extending if larger and unsigned, and sign extending if larger and signed.

logic_t slang::SVInt::operator==(const SVInt& rhs) const

Equality operator; if either value is unknown the result is unknown. Otherwise, if bit lengths are unequal we extend the smaller one and then compare.

std::ostream& operator<<(std::ostream& os, const SVInt& rhs)

Stream formatting operator. Guesses a nice base to use and writes the string representation into the stream.

logic_t condWildcardEqual(const SVInt& lhs, const SVInt& rhs)

Wildcard based equality, with unknown bits as wildcards. This method only looks for wildcard bits on the rhs, as needed by the conditional operator.

bool caseXWildcardEqual(const SVInt& lhs, const SVInt& rhs)

Wildcard based equality, with unknown bits as wildcards. This method implements matching as required by casex statements.

bool caseZWildcardEqual(const SVInt& lhs, const SVInt& rhs)

Wildcard based equality, with Z bits as wildcards. This method implements matching as required by casez statements.