Reference#

Data Types#

class bvwx.Array(d0: int, d1: int)#

Bases: Bits

Multi dimensional array of bits.

To create an Array instance, use the bits function:

>>> x = bits(["4b0100", "4b1110"])

Array implements size and shape attributes, and the __getitem__ method. Array does NOT implement a __len__ method.

>>> x.size
8
>>> x.shape
(2, 4)
>>> x[0]
bits("4b0100")
>>> x[1]
bits("4b1110")
>>> x[0,0]
bits("1b0")

An Array may be converted into an equal-size, multi-dimensional Array using the reshape method:

>>> x.reshape((4,2))
bits(["2b00", "2b01", "2b10", "2b11"])

An Array may be converted into an equal-size, one-dimensional Vector using the flatten method:

>>> x.flatten()
bits("8b1110_0100")
property shape: tuple[int, ...]#
property size: int#
classmethod cast(x: Array) Self#

Convert Array object to an instance of this class.

For example, to cast an Array[2,2] to a Vector[4]:

>>> x = bits(["2b00", "2b11"])
>>> Vector[4].cast(x)
bits("4b1100")
Raises:

TypeError – Object size does not match this class size.

classmethod xs() Self#

Return an instance filled with X bits.

For example:

>>> Vector[4].xs()
bits("4bXXXX")
classmethod zeros() Self#

Return an instance filled with 0 bits.

For example:

>>> Vector[4].zeros()
bits("4b0000")
classmethod ones() Self#

Return an instance filled with 1 bits.

For example:

>>> Vector[4].ones()
bits("4b1111")
classmethod ws() Self#

Return an instance filled with - bits.

For example:

>>> Vector[4].ws()
bits("4b----")
classmethod rand() Self#

Return an instance filled with random bits.

classmethod xprop(sel: Array) Self#

Propagate X in a wildcard pattern (default case).

If sel contains an X, propagate X. Otherwise, treat as a “don’t care”, and propagate -.

For example:

>>> def f(x: Vector[1]) -> Vector[1]:
...     match x:
...         case "1b0":
...             return bits("1b1")
...         case _:
...             return Vector[1].xprop(x)
>>> f(bits("1b0"))  # Match!
bits("1b1")
>>> f(bits("1b1"))  # No match; No X prop
bits("1b-")
>>> f(bits("1bX"))  # No match; Yes X prop
bits("1bX")
Parameters:

sel – Array object, typically a match subject

Returns:

Class instance filled with either - or X.

reshape(shape: tuple[int, ...]) Array#
flatten() Vector#
__bool__() bool#

Convert to Python bool.

An Array object is True if its value is known nonzero.

For example:

>>> bool(bits("1b0"))
False
>>> bool(bits("1b1"))
True
>>> bool(bits("4b0000"))
False
>>> bool(bits("4b1010"))
True

Warning

Be cautious about using any expression that might have an unknown value as the condition of a Python if or while statement.

Raises:

ValueError – Contains any unknown bits.

__int__() int#

Convert to Python int.

Use two’s complement representation:

  • If most significant bit is 1, result will be negative.

  • If most significant bit is 0, result will be non-negative.

For example:

>>> int(bits("4b1010"))
-6
>>> int(bits("4b0101"))
5
Raises:

ValueError – Contains any unknown bits.

to_uint() int#

Convert to unsigned integer.

Returns:

A non-negative int.

Raises:

ValueError – Contains any unknown bits.

to_int() int#

Convert to signed integer.

Returns:

An int, from two’s complement encoding.

Raises:

ValueError – Contains any unknown bits.

count_zeros() int#

Return count of of 0 bits.

count_ones() int#

Return count of 1 bits.

count_xs() int#

Return count of X bits.

count_ws() int#

Return count of - bits.

count_unknown() int#

Return count of unknown bits.

onehot() bool#

Return True if contains exactly one 1 bit.

onehot0() bool#

Return True if contains at most one 1 bit.

has_0() bool#

Return True if contains at least one 0 bit.

has_1() bool#

Return True if contains at least one 1 bit.

has_x() bool#

Return True if contains at least one X bit.

has_w() bool#

Return True if contains at least one - bit.

has_xw() bool#

Return True if contains at least one unknown bit.

has_unknown() bool#

Return True if contains at least one unknown bit.

vcd_var() str#

Return VCD variable type.

vcd_val() str#

Return VCD variable value.

class bvwx.Vector(d0: int, d1: int)#

Bases: Array

One dimensional sequence of bits.

To create a Vector instance, use binary, decimal, or hexadecimal string literals:

>>> bits("4b1010")
bits("4b1010")
>>> bits("4d10")
bits("4b1010")
>>> bits("4ha")
bits("4b1010")

Vector implements size and shape attributes, as well as __len__ and __getitem__ methods:

>>> x = bits("8b1111_0000")
>>> x.size
8
>>> x.shape
(8,)
>>> len(x)
8
>>> x[3]
bits("1b0")
>>> x[4]
bits("1b1")
>>> x[2:6]
bits("4b1100")

A Vector may be converted into an equal-size multi-dimensional Array using the reshape method:

>>> x.reshape((2,4))
bits(["4b0000", "4b1111"])
class bvwx.Scalar(d0: int, d1: int)#

Bases: Vector

Zero dimensional (scalar) sequence of bits.

Degenerate form of a Vector resulting from a one bit slice.

>>> from bvwx import Vec
>>> Vec[1] is Scalar
True

To get a handle to a Scalar instance:

>>> f = bits("1b0")
>>> t = bits("1b1")
>>> x = bits("1bX")
>>> w = bits("1b-")

For convenience, False and True also work:

>>> bits(False) == f and bits(True) == t
True

Scalar implements Vector methods, including __getitem__:

>>> t.size
1
>>> t.shape
(1,)
>>> len(t)
1
>>> t[0]
bits("1b1")
class bvwx.Empty(d0: int, d1: int)#

Bases: Vector

Null dimensional sequence of bits.

Degenerate form of a Vector resulting from an empty slice.

>>> from bvwx import Vec
>>> Vec[0] is Empty
True

To get a handle to an Empty instance:

>>> empty = bits()

Empty implements Vector methods, but __getitem__ will always raise an exception:

>>> empty.size
0
>>> empty.shape
(0,)
>>> len(empty)
0
>>> empty[0]
Traceback (most recent call last):
    ...
IndexError: Expected index in [0, 0), got 0
class bvwx.Enum#

Bases: object

User-defined enumerated data type.

Define a type from a collection of unique constants.

Extend from Enum to define an enumeration:

>>> from bvwx import Enum
>>> class Color(Enum):
...     RED = "2b00"
...     GREEN = "2b01"
...     BLUE = "2b10"

Enums behave like Vectors, but they have an extra name attribute:

>>> len(Color.RED)
2
>>> Color.RED[0]
bits("1b0")
>>> Color.RED == "2b00"
True
>>> Color.RED.name
'RED'

All Enums have X and W attributes defined automatically:

>>> Color.X == "2bXX"
True
>>> Color.W == "2b--"
True

To cast a Vec to an Enum, use the constructor:

>>> Color("2b00")
Color.RED

Values not included in the enumeration are allowed:

>>> Color("2b11")
Color("2b11")

To cast an Enum to a Vec, use the cast method:

>>> from bvwx import Vec
>>> Vec[2].cast(Color.RED)
bits("2b00")
property name: str#
class bvwx.Struct#

Bases: object

User defined struct data type.

Compose a type from a sequence of other types.

Extend from Struct to define a struct:

>>> from bvwx import Vec
>>> class Pixel(Struct):
...     red: Vec[8]
...     green: Vec[8]
...     blue: Vec[8]

Use the new type’s constructor to create Struct instances:

>>> maize = Pixel(red="8hff", green="8hcb", blue="8h05")

Access individual fields using attributes:

>>> maize.red
bits("8b1111_1111")
>>> maize.green
bits("8b1100_1011")

Structs have a size, but no shape.

>>> Pixel.size
24

Struct slicing behaves like a Vector:

>>> maize[8:16] == maize.green
True
class bvwx.Union#

Bases: object

User defined union data type.

Compose a type from the union of other types.

Extend from Union to define a union:

>>> from bvwx import Vec
>>> class Response(Union):
...     error: Vec[4]
...     data: Vec[8]

Use the new type’s constructor to create Union instances:

>>> rsp = Response("8h0f")

Access individual fields using attributes:

>>> rsp.error
bits("4b1111")
>>> rsp.data
bits("8b0000_1111")

Unions have a size, but no shape.

>>> Response.size
8

Union slicing behaves like a Vector:

>>> rsp[3:5]
bits("2b01")

Operators#

Bitwise#

bvwx.not_(x: ArrayLike) Array#

Unary bitwise logical NOT operator.

Perform logical negation on each bit of the input:

x

NOT(x)

0

1

1

0

X

X

-

-

For example:

>>> not_("4b-10X")
bits("4b-01X")

In expressions, you can use the unary ~ operator:

>>> from bvwx import bits
>>> a = bits("4b-10X")
>>> ~a
bits("4b-01X")
Parameters:

xArray or string literal.

Returns:

Array of same type and equal size

Raises:
  • TypeErrorx0 is not a valid Array object.

  • ValueError – Error parsing string literal.

bvwx.or_(x0: ArrayLike, *xs: ArrayLike) Array#

N-ary bitwise logical OR operator.

Perform logical OR on each bit of the inputs:

x0

x1

OR(x0, x1)

Note

0

0

0

0

1

1

1

0

1

1

1

1

X

{0, 1, -}

X

X dominates all

1

-

1

1 dominates -

-

{0, -}

-

- dominates 0

For example:

>>> or_("16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b-1-X_111X_-10X_XXXX")

In expressions, you can use the binary | operator:

>>> from bvwx import bits
>>> a = bits("16b----_1111_0000_XXXX")
>>> b = bits("16b-10X_-10X_-10X_-10X")
>>> a | b
bits("16b-1-X_111X_-10X_XXXX")
Parameters:
  • x0Array or string literal.

  • xs – Sequence of Array equal size to x0.

Returns:

Array equal size to x0.

Raises:
  • TypeErrorx0 is not a valid Array object, or xs[i] not equal size to x0.

  • ValueError – Error parsing string literal.

bvwx.and_(x0: ArrayLike, *xs: ArrayLike) Array#

N-ary bitwise logical AND operator.

Perform logical AND on each bit of the inputs:

x0

x1

AND(x0, x1)

Note

0

0

0

0

1

0

1

0

0

1

1

1

X

{0, 1, -}

X

X dominates all

0

-

0

0 dominates -

-

{1, -}

-

- dominates 1

For example:

>>> and_("16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b--0X_-10X_000X_XXXX")

In expressions, you can use the binary & operator:

>>> from bvwx import bits
>>> a = bits("16b----_1111_0000_XXXX")
>>> b = bits("16b-10X_-10X_-10X_-10X")
>>> a & b
bits("16b--0X_-10X_000X_XXXX")
Parameters:
  • x0Array or string literal.

  • xs – Sequence of Array equal size to x0.

Returns:

Array equal size to x0.

Raises:
  • TypeErrorx0 is not a valid Array object, or xs[i] not equal size to x0.

  • ValueError – Error parsing string literal.

bvwx.xor(x0: ArrayLike, *xs: ArrayLike) Array#

N-ary bitwise logical XOR operator.

Perform logical XOR on each bit of the inputs:

x0

x1

XOR(x0, x1)

Note

0

0

0

0

1

1

1

0

1

1

1

0

X

{0, 1, -}

X

X dominates all

-

{0, 1. -}

-

- dominates known

For example:

>>> xor("16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b---X_-01X_-10X_XXXX")

In expressions, you can use the binary ^ operator:

>>> from bvwx import bits
>>> a = bits("16b----_1111_0000_XXXX")
>>> b = bits("16b-10X_-10X_-10X_-10X")
>>> a ^ b
bits("16b---X_-01X_-10X_XXXX")
Parameters:
  • x0Array or string literal.

  • xs – Sequence of Array equal size to x0.

Returns:

Array equal size to x0.

Raises:
  • TypeErrorx0 is not a valid Array object, or xs[i] not equal size to x0.

  • ValueError – Error parsing string literal.

bvwx.impl(p: ArrayLike, q: ArrayLike) Array#

Binary bitwise logical IMPL (implies) operator.

Perform logical IMPL on each bit of the inputs:

Functionally equivalent to ~p | q.

For example:

>>> impl("16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b-1-X_-10X_111X_XXXX")
Parameters:
  • pArray or string literal.

  • qArray equal size to p.

Returns:

Array equal size to p.

Raises:
  • TypeErrorp is not a valid Array object, or q not equal size to p.

  • ValueError – Error parsing string literal.

bvwx.ite(s: ScalarLike, x1: ArrayLike, x0: ArrayLike) Array#

Ternary bitwise logical if-then-else (ITE) operator.

Perform logical ITE on each bit of the inputs:

s

x1

x0

ITE(s, x1, x0)

1

{0, 1, -}

x1

0

{0, 1, -}

x0

X

X

X

X

X

X

-

0

0

0

-

0

{1, -}

-

-

1

1

1

-

1

{0, -}

-

-

-

{0, 1, -}

-

For example:

>>> ite("1b0", "16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b-10X_-10X_-10X_XXXX")
>>> ite("1b1", "16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b---X_111X_000X_XXXX")
>>> ite("1b-", "16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b---X_-1-X_--0X_XXXX")
Parameters:
  • sArray select

  • x1Array or string literal.

  • x0Array or string literal equal size to x1.

Returns:

Array equal size to x1.

Raises:
  • TypeErrors or x1 are not valid Array objects, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.mux(s: ArrayLike, **xs: ArrayLike) Array#

Bitwise logical multiplex (mux) operator.

Parameters:
  • sArray select.

  • xsArray or string literal, all equal size.

Mux input names are in the form xN, where N is a valid int. Muxes require at least one input. Any inputs not specified will default to “don’t care”.

For example:

>>> mux("2b00", x0="4b0001", x1="4b0010", x2="4b0100", x3="4b1000")
bits("4b0001")
>>> mux("2b10", x0="4b0001", x1="4b0010", x2="4b0100", x3="4b1000")
bits("4b0100")

Handles X and W propagation:

>>> mux("2b1-", x0="4b0001", x1="4b0010", x2="4b0100", x3="4b1000")
bits("4b--00")
>>> mux("2b1X", x0="4b0001", x1="4b0010", x2="4b0100", x3="4b1000")
bits("4bXXXX")
Returns:

Array equal size to xN inputs.

Raises:
  • TypeErrors or xN are not valid Array objects, or xN mismatching size.

  • ValueError – Error parsing string literal.

Logical#

bvwx.lor(*xs: ScalarLike) Scalar#

N-ary logical OR operator.

The identity of OR is 0.

For example:

>>> lor(False, 0, "1b1")
bits("1b1")

Empty input returns identity:

>>> lor()
bits("1b0")
Parameters:

xs – Sequence of bool / Scalar / string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Scalar object.

  • ValueError – Error parsing string literal.

bvwx.land(*xs: ScalarLike) Scalar#

N-ary logical AND operator.

The identity of AND is 1.

For example:

>>> land(True, 1, "1b0")
bits("1b0")

Empty input returns identity:

>>> land()
bits("1b1")
Parameters:

xs – Sequence of bool / Scalar / string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Scalar object.

  • ValueError – Error parsing string literal.

bvwx.lxor(*xs: ScalarLike) Scalar#

N-ary logical XOR operator.

The identity of XOR is 0.

For example:

>>> lxor(False, 0, "1b1")
bits("1b1")

Empty input returns identity:

>>> lxor()
bits("1b0")
Parameters:

xs – Sequence of bool / Scalar / string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Scalar object.

  • ValueError – Error parsing string literal.

Unary#

bvwx.uor(x: ArrayLike) Scalar#

Unary OR reduction operator.

The identity of OR is 0. Compute an OR-sum over all the bits of x.

For example:

>>> uor("4b1000")
bits("1b1")

Empty input returns identity:

>>> from bvwx import bits
>>> uor(bits())
bits("1b0")
Parameters:

xArray or string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Array object.

  • ValueError – Error parsing string literal.

bvwx.uand(x: ArrayLike) Scalar#

Unary AND reduction operator.

The identity of AND is 1. Compute an AND-sum over all the bits of x.

For example:

>>> uand("4b0111")
bits("1b0")

Empty input returns identity:

>>> from bvwx import bits
>>> uand(bits())
bits("1b1")
Parameters:

xArray or string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Array object.

  • ValueError – Error parsing string literal.

bvwx.uxor(x: ArrayLike) Scalar#

Unary XOR reduction operator.

The identity of XOR is 0. Compute an XOR-sum (odd parity) over all the bits of x.

For example:

>>> uxor("4b1010")
bits("1b0")

Empty input returns identity:

>>> from bvwx import bits
>>> uxor(bits())
bits("1b0")
Parameters:

xArray or string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Array object.

  • ValueError – Error parsing string literal.

Arithmetic#

bvwx.add(a: ArrayLike, b: ArrayLike, ci: ScalarLike | None = None) Array#

Addition with carry-in, but NO carry-out.

For example:

>>> add("4d2", "4d2")
bits("4b0100")
>>> add("2d2", "2d2")
bits("2b00")
Parameters:
  • aArray or string literal

  • bArray or string literal

  • ciScalar carry-in, or None. None defaults to carry-in 0.

Returns:

Array sum w/ size equal to max(a.size, b.size).

Raises:
  • TypeErrora, b, or ci are not valid Array objects.

  • ValueError – Error parsing string literal.

bvwx.adc(a: ArrayLike, b: ArrayLike, ci: ScalarLike | None = None) Vector#

Addition with carry-in, and carry-out.

For example:

>>> adc("4d2", "4d2")
bits("5b0_0100")
>>> adc("2d2", "2d2")
bits("3b100")
Parameters:
  • aArray or string literal

  • bArray or string literal

  • ciScalar carry-in, or None. None defaults to carry-in 0.

Returns:

Vector sum w/ size equal to max(a.size, b.size) + 1. The most significant bit is the carry-out.

Raises:
  • TypeErrora, b, or ci are not valid Array objects.

  • ValueError – Error parsing string literal.

bvwx.sub(a: ArrayLike, b: ArrayLike) Array#

Twos complement subtraction, with NO carry-out.

Parameters:
  • aArray or string literal

  • bArray or string literal equal size to a.

Returns:

Array sum equal size to a and b.

Raises:
  • TypeErrora, or b are not valid Array objects, or a not equal size to b.

  • ValueError – Error parsing string literal.

bvwx.sbc(a: ArrayLike, b: ArrayLike) Vector#

Twos complement subtraction, with carry-out.

Parameters:
  • aArray or string literal

  • bArray or string literal equal size to a.

Returns:

Array sum w/ size one larger than a and b. The most significant bit is the carry-out.

Raises:
  • TypeErrora, or b are not valid Array objects, or a not equal size to b.

  • ValueError – Error parsing string literal.

bvwx.neg(x: ArrayLike) Array#

Twos complement negation, with NO carry-out.

Parameters:

xArray or string literal

Returns:

Array equal size to x.

Raises:
  • TypeErrorx is not a valid Array object.

  • ValueError – Error parsing string literal.

bvwx.ngc(x: ArrayLike) Vector#

Twos complement negation, with carry-out.

Parameters:

xArray or string literal

Returns:

Array w/ size one larger than x. The most significant bit is the carry-out.

Raises:
  • TypeErrorx is not a valid Array object.

  • ValueError – Error parsing string literal.

bvwx.mul(a: ArrayLike, b: ArrayLike) Vector#

Unsigned multiply.

For example:

>>> mul("4d2", "4d2")
bits("8b0000_0100")
>>> add("2d2", "2d2")
bits("2b00")
Parameters:
  • aArray or string literal

  • bArray or string literal

Returns:

Vector product w/ size a.size + b.size

Raises:
  • TypeErrora or b are not valid Array objects.

  • ValueError – Error parsing string literal.

bvwx.div(a: ArrayLike, b: ArrayLike) Array#

Unsigned divide.

Parameters:
  • aArray or string literal

  • bArray or string literal

Returns:

Vector quotient w/ size a.size

Raises:
  • TypeErrora or b are not valid Array objects.

  • ValueError – Error parsing string literal.

  • ZeroDivisionError – If b is zero.

bvwx.mod(a: ArrayLike, b: ArrayLike) Array#

Unsigned modulo.

Parameters:
  • aArray or string literal

  • bArray or string literal

Returns:

Vector remainder w/ size b.size

Raises:
  • TypeErrora or b are not valid Array objects.

  • ValueError – Error parsing string literal.

  • ZeroDivisionError – If b is zero.

bvwx.matmul(a: ArrayLike, b: ArrayLike) Array#

Matrix multiply.

Parameters:
  • aArray or string literal

  • bArray or string literal

Returns:

Array product

Raises:
  • TypeErrora or b are invalid or incompatible Array objects.

  • ValueError – Error parsing string literal.

bvwx.lsh(x: ArrayLike, n: UintLike) Array#

Logical left shift by n bits.

Fill bits with zeros.

For example:

>>> lsh("4b1011", 2)
bits("4b1100")
Parameters:
  • xArray or string literal.

  • nArray, string literal, or int Non-negative bit shift count.

Returns:

Array left-shifted by n bits.

Raises:
  • TypeErrorx is not a valid Array object, or n is not a valid bit shift count.

  • ValueError – Error parsing string literal, or negative shift amount.

bvwx.rsh(x: ArrayLike, n: UintLike) Array#

Logical right shift by n bits.

Fill bits with zeros.

For example:

>>> rsh("4b1101", 2)
bits("4b0011")
Parameters:
  • xArray or string literal.

  • nArray, string literal, or int Non-negative bit shift count.

Returns:

Array right-shifted by n bits.

Raises:
  • TypeErrorx is not a valid Array object, or n is not a valid bit shift count.

  • ValueError – Error parsing string literal, or negative shift amount.

bvwx.srsh(x: ArrayLike, n: UintLike) Array#

Arithmetic (signed) right shift by n bits.

Fill bits with most significant bit (sign).

For example:

>>> srsh("4b1101", 2)
bits("4b1111")
Parameters:
  • xArray or string literal.

  • nArray, string literal, or int Non-negative bit shift count.

Returns:

Array right-shifted by n bits.

Raises:
  • TypeErrorx is not a valid Array object, or n is not a valid bit shift count.

  • ValueError – Error parsing string literal, or negative shift amount.

Encode / Decode#

bvwx.encode_onehot(x: ArrayLike) Vector#

Compress one-hot encoding to an index.

The index is the highest bit set in the input.

For example:

>>> encode_onehot("2b01")
bits("1b0")
>>> encode_onehot("2b10")
bits("1b1")
>>> encode_onehot("3b010")
bits("2b01")
Parameters:

xArray or string literal.

Returns:

Vector w/ size = clog2(x.size)

Raises:
  • TypeErrorx is not a valid Array object.

  • ValueErrorx is not one-hot encoded.

bvwx.encode_priority(x: ArrayLike) tuple[Vector, Scalar]#

Compress priority encoding to (index, valid) tuple.

The index is the highest bit set in the input.

For example:

>>> encode_priority("2b01")
(bits("1b0"), bits("1b1"))
>>> encode_priority("2b10")
(bits("1b1"), bits("1b1"))
>>> encode_priority("3b1--")
(bits("2b10"), bits("1b1"))
Parameters:

xArray or string literal.

Returns:

Vector w/ size = clog2(x.size) Scalar valid bit

Return type:

Tuple of Vector and Scalar

Raises:

TypeErrorx is not a valid Array object.

bvwx.decode(x: ArrayLike) Vector#

Decode dense encoding to sparse, one-hot encoding.

For example:

>>> decode("2b00")
bits("4b0001")
>>> decode("2b01")
bits("4b0010")
>>> decode("2b10")
bits("4b0100")
>>> decode("2b11")
bits("4b1000")

Empty input returns 1b1:

>>> from bvwx import bits
>>> decode(bits())
bits("1b1")
Parameters:

xArray or string literal.

Returns:

One hot Scalar or Vector w/ size = 2**x.size

Raises:
  • TypeErrorx is not a valid Array object.

  • ValueError – Error parsing string literal.

Word#

bvwx.xt(x: ArrayLike, n: UintLike) Array#

Unsigned extend by n bits.

Fill high order bits with zero.

For example:

>>> xt("2b11", 2)
bits("4b0011")
Parameters:
  • xArray or string literal.

  • n – Non-negative number of bits.

Returns:

Array zero-extended by n bits.

Raises:
  • TypeErrorx is not a valid Array object.

  • ValueError – If n is negative.

bvwx.sxt(x: ArrayLike, n: UintLike) Array#

Sign extend by n bits.

Fill high order bits with sign.

For example:

>>> sxt("2b11", 2)
bits("4b1111")
Parameters:
  • xArray or string literal.

  • n – Non-negative number of bits.

Returns:

Array sign-extended by n bits.

Raises:
  • TypeErrorx is not a valid Array object, or empty.

  • ValueError – If n is negative.

bvwx.lrot(x: ArrayLike, n: UintLike) Array#

Rotate left by n bits.

For example:

>>> lrot("4b1011", 2)
bits("4b1110")
Parameters:
  • xArray or string literal.

  • nArray, string literal, or int Non-negative bit rotate count.

Returns:

Array left-rotated by n bits.

Raises:
  • TypeErrorx is not a valid Array object, or n is not a valid bit rotate count.

  • ValueError – Error parsing string literal, or negative rotate amount.

bvwx.rrot(x: ArrayLike, n: UintLike) Array#

Rotate right by n bits.

For example:

>>> rrot("4b1101", 2)
bits("4b0111")
Parameters:
  • xArray or string literal.

  • nArray, string literal, or int Non-negative bit rotate count.

Returns:

Array right-rotated by n bits.

Raises:
  • TypeErrorx is not a valid Array object, or n is not a valid bit rotate count.

  • ValueError – Error parsing string literal, or negative rotate amount.

bvwx.cat(*objs: ArrayLike) Array#

Concatenate a sequence of Vectors.

Parameters:

objs – a sequence of vec/bool/lit objects.

Returns:

A Vec instance.

Raises:

TypeError – If input obj is invalid.

bvwx.rep(obj: ArrayLike, n: int) Array#

Repeat a Vector n times.

bvwx.pack(x: ArrayLike, n: int = 1) Array#

Pack n-bit blocks in right to left order.

Predicate#

bvwx.eq(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Equal (==) reduction operator.

Equivalent to uand(xnor(x0, x1)).

For example:

>>> eq("2b01", "2b00")
bits("1b0")
>>> eq("2b01", "2b01")
bits("1b1")
>>> eq("2b01", "2b10")
bits("1b0")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.ne(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical NotEqual (!=) reduction operator.

Equivalent to uor(xor(x0, x1)).

For example:

>>> ne("2b01", "2b00")
bits("1b1")
>>> ne("2b01", "2b01")
bits("1b0")
>>> ne("2b01", "2b10")
bits("1b1")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.lt(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Unsigned LessThan (<) reduction operator.

Returns Scalar result of x0.to_uint() < x1.to_uint(). For performance reasons, use simple X/- propagation: X dominates {-, known}, and - dominates known.

For example:

>>> lt("2b01", "2b00")
bits("1b0")
>>> lt("2b01", "2b01")
bits("1b0")
>>> lt("2b01", "2b10")
bits("1b1")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.le(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Unsigned LessThanOrEqual (≤) reduction operator.

Returns Scalar result of x0.to_uint() <= x1.to_uint(). For performance reasons, use simple X/- propagation: X dominates {-, known}, and - dominates known.

For example:

>>> le("2b01", "2b00")
bits("1b0")
>>> le("2b01", "2b01")
bits("1b1")
>>> le("2b01", "2b10")
bits("1b1")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.gt(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Unsigned GreaterThan (>) reduction operator.

Returns Scalar result of x0.to_uint() > x1.to_uint(). For performance reasons, use simple X/- propagation: X dominates {-, known}, and - dominates known.

For example:

>>> gt("2b01", "2b00")
bits("1b1")
>>> gt("2b01", "2b01")
bits("1b0")
>>> gt("2b01", "2b10")
bits("1b0")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.ge(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Unsigned GreaterThanOrEqual (≥) reduction operator.

Returns Scalar result of x0.to_uint() >= x1.to_uint(). For performance reasons, use simple X/- propagation: X dominates {-, known}, and - dominates known.

For example:

>>> ge("2b01", "2b00")
bits("1b1")
>>> ge("2b01", "2b01")
bits("1b1")
>>> ge("2b01", "2b10")
bits("1b0")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.slt(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Signed LessThan (<) reduction operator.

Returns Scalar result of x0.to_int() < x1.to_int(). For performance reasons, use simple X/- propagation: X dominates {-, known}, and - dominates known.

For example:

>>> slt("2b00", "2b11")
bits("1b0")
>>> slt("2b00", "2b00")
bits("1b0")
>>> slt("2b00", "2b01")
bits("1b1")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.sle(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Signed LessThanOrEqual (≤) reduction operator.

Returns Scalar result of x0.to_int() <= x1.to_int(). For performance reasons, use simple X/- propagation: X dominates {-, known}, and - dominates known.

For example:

>>> sle("2b00", "2b11")
bits("1b0")
>>> sle("2b00", "2b00")
bits("1b1")
>>> sle("2b00", "2b01")
bits("1b1")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.sgt(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Signed GreaterThan (>) reduction operator.

Returns Scalar result of x0.to_int() > x1.to_int(). For performance reasons, use simple X/- propagation: X dominates {-, known}, and - dominates known.

For example:

>>> sgt("2b00", "2b11")
bits("1b1")
>>> sgt("2b00", "2b00")
bits("1b0")
>>> sgt("2b00", "2b01")
bits("1b0")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.sge(x0: ArrayLike, x1: ArrayLike) Scalar#

Binary logical Signed GreaterThanOrEqual (≥) reduction operator.

Returns Scalar result of x0.to_int() >= x1.to_int(). For performance reasons, use simple X/- propagation: X dominates {-, known}, and - dominates known.

For example:

>>> sge("2b00", "2b11")
bits("1b1")
>>> sge("2b00", "2b00")
bits("1b1")
>>> sge("2b00", "2b01")
bits("1b0")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

bvwx.match(x0: ArrayLike, x1: ArrayLike) Scalar#

Pattern match operator.

Similar to eq operator, but with support for - wildcards.

For example:

>>> match("2b01", "2b0-")
bits("1b1")
>>> match("2b--", "2b10")
bits("1b1")
>>> match("2b01", "2b10")
bits("1b0")
Parameters:
  • x0Array or string literal.

  • x1Array or string literal equal size to x0.

Returns:

Scalar

Raises:
  • TypeErrorx0 or x1 is not a valid Array object, or x0 not equal size to x1.

  • ValueError – Error parsing string literal.

Count#

bvwx.cpop(x: ArrayLike) Vector#

Count population: return number of set bits.

bvwx.clz(x: ArrayLike) Vector#

Count leading zeros.

bvwx.ctz(x: ArrayLike) Vector#

Count trailing zeros.

Factory Functions#

bvwx.bits(obj: Any = None) Array#

Create a shaped Array object using standard input formats.

For example, empty input returns an Empty instance.

>>> bits()
bits([])
>>> bits(None)
bits([])

bool, int, and string literal inputs:

>>> bits(False)
bits("1b0")
>>> bits([False, True, False, True])
bits("4b1010")
>>> bits("8d42")
bits("8b0010_1010")

Use a list of inputs to create arbitrary shaped inputs:

>>> x = bits([["2b00", "2b01"], ["2b10", "2b11"]])
>>> x
bits([["2b00", "2b01"],
      ["2b10", "2b11"]])
>>> x.shape
(2, 2, 2)
Parameters:

obj – Object that can be converted to an Array instance.

Returns:

Array instance.

Raises:

TypeError – If input obj is invalid.

bvwx.stack(*objs: ArrayLike) Array#

Stack a sequence of Arrays w/ same shape into a higher dimensional shape.

For a sequence length N with shape M, the output shape will be M x N.

For example, a sequence of scalars stacked to a vector:

>>> stack(0, 1, 0, 1)
bits("4b1010")

Or a sequence of vectors stacked to an array:

>>> x0 = stack("2b00", "2b01")
>>> x1 = stack("2b10", "2b11")
>>> y = stack(x0, x1)
>>> y
bits([["2b00", "2b01"],
      ["2b10", "2b11"]])
>>> y.shape
(2, 2, 2)
Parameters:

objs – a sequence of vec/bits/bool/lit objects.

Returns:

Array instance.

Raises:

TypeError – If input obj is invalid.

bvwx.lit2bv(lit: str) Vector#

Convert string literal to Vector.

A string literal is in the form {width}{base}{characters}, where width is the number of bits, base is either ‘b’ for binary or ‘h’ for hexadecimal, and characters is a string of legal characters. The character string can contains ‘_’ separators for readability.

For example:

  • "4b1010"

  • "6b11_-10X"

  • "64hdead_beef_feed_face"

Returns:

A Vec instance.

Raises:

ValueError – If input literal has a syntax error.

bvwx.u2bv(n: int, size: int | None = None) Vector#

Convert nonnegative int to Vector.

For example:

>>> u2bv(42, size=8)
bits("8b0010_1010")
Parameters:
  • n – Nonnegative int to convert.

  • size – Optional int output size. Defaults to minimum required size.

Returns:

Vector

Raises:

ValueErrorn is negative or overflows the output size.

bvwx.i2bv(n: int, size: int | None = None) Vector#

Convert int to Vector.

For example:

>>> i2bv(42, size=8)
bits("8b0010_1010")
>>> i2bv(-42, size=8)
bits("8b1101_0110")
Parameters:
  • nint to convert.

  • size – Optional int output size. Defaults to minimum required size.

Returns:

Vector

Raises:

ValueErrorn overflows the output size.