Combinational Logic#

Data Types#

class seqlogic.bits.Bits#

Sequence of bits.

A bit is a 4-state logical value in the set {0, 1, X, -}:

  • 0 is Boolean zero or “False”

  • 1 is Boolean one or “True”

  • X is an uninitialized or metastable value

  • - is a “don’t care” value

The values 0 and 1 are “known”. The values X and - are “unknown”.

Bits is the base class for a family of hardware-oriented data types. All Bits objects have a size attribute. Shaped subclasses (Empty, Scalar, Vector, Array) have a shape attribute. Composite subclasses (Struct, Union) have user-defined attributes.

Bits does NOT implement the Python Sequence protocol.

Children:

              Bits
                |
  +------+------+-----+------+-----+
  |      |      |     |      |     |
Empty Scalar Vector Array Struct Union
                |
              Enum

Do NOT construct a Bits object directly. Use one of the factory functions:

  • bits

  • stack

  • u2bv

  • i2bv

property size#

Number of bits

classmethod cast(x: Bits) Bits#

Convert Bits 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 xes() Bits#

Return an instance filled with X bits.

For example:

>>> Vector[4].xes()
bits("4bXXXX")
classmethod zeros() Bits#

Return an instance filled with 0 bits.

For example:

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

Return an instance filled with 1 bits.

For example:

>>> Vector[4].ones()
bits("4b1111")
classmethod dcs() Bits#

Return an instance filled with - bits.

For example:

>>> Vector[4].dcs()
bits("4b----")
classmethod xprop(sel: Bits) Bits#

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 – Bits object, typically a match subject

Returns:

Class instance filled with either - or X.

property data: tuple[int, int]#

Internal representation.

__bool__() bool#

Convert to Python bool.

A Bits 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_xes() int#

Return count of X bits.

count_zeros() int#

Return count of of 0 bits.

count_ones() int#

Return count of 1 bits.

count_dcs() 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_x() bool#

Return True if contains at least one X bit.

has_dc() bool#

Return True if contains at least one - bit.

has_unknown() bool#

Return True if contains at least one unknown bit.

class seqlogic.bits.Empty(d0: int, d1: int)#

Null dimensional sequence of bits.

Degenerate form of a Vector resulting from an empty slice.

>>> Vector[0] is Empty
True

To get a handle to an Empty instance:

>>> empty = bits()

Empty implements Vector methods, except for __getitem__:

>>> empty.size
0
>>> empty.shape
(0,)
>>> len(empty)
0
>>> empty[0]
Traceback (most recent call last):
    ...
TypeError: 'Empty' object is not subscriptable
class seqlogic.bits.Scalar(d0: int, d1: int)#

Zero dimensional (scalar) sequence of bits.

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

>>> Vector[1] is Scalar
True

To get a handle to a Scalar instance:

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

For convenience, False and True also work:

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

Scalar implements Vector methods, including __getitem__:

>>> t.size
1
>>> t.shape
(1,)
>>> len(t)
1
>>> t[0]
bits("1b1")

Operators#

Bitwise#

seqlogic.bits.not_(x: Bits | str) Bits#

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:

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

xBits or string literal.

Returns:

Bits of same type and equal size

Raises:
  • TypeErrorx0 is not a valid Bits object.

  • ValueError – Error parsing string literal.

seqlogic.bits.nor(x0: Bits | str, *xs: Bits | str) Bits#

N-ary bitwise logical NOR operator.

Perform logical NOR on each bit of the inputs:

x0

x1

NOR(x0, x1)

Note

0

0

1

0

1

0

1

0

0

1

1

0

X

{0, 1, -}

X

X dominates all

1

-

0

1 dominates -

-

{0, -}

-

- dominates 0

For example:

>>> nor("16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b-0-X_000X_-01X_XXXX")

In expressions, you can use the unary ~ and binary | operators:

>>> a = bits("16b----_1111_0000_XXXX")
>>> b = bits("16b-10X_-10X_-10X_-10X")
>>> ~(a | b)
bits("16b-0-X_000X_-01X_XXXX")
Parameters:
  • x0Bits or string literal.

  • xs – Sequence of Bits equal size to x0.

Returns:

Bits equal size to x0.

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

  • ValueError – Error parsing string literal.

seqlogic.bits.or_(x0: Bits | str, *xs: Bits | str) Bits#

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:

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

  • xs – Sequence of Bits equal size to x0.

Returns:

Bits equal size to x0.

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

  • ValueError – Error parsing string literal.

seqlogic.bits.nand(x0: Bits | str, *xs: Bits | str) Bits#

N-ary bitwise logical NAND operator.

Perform logical NAND on each bit of the inputs:

x0

x1

NAND(x0, x1)

Note

0

0

1

0

1

1

1

0

1

1

1

0

X

{0, 1, -}

X

X dominates all

0

-

1

0 dominates -

-

{1, -}

-

- dominates 1

For example:

>>> nand("16b----_1111_0000_XXXX", "16b-10X_-10X_-10X_-10X")
bits("16b--1X_-01X_111X_XXXX")

In expressions, you can use the unary ~ and binary & operators:

>>> a = bits("16b----_1111_0000_XXXX")
>>> b = bits("16b-10X_-10X_-10X_-10X")
>>> ~(a & b)
bits("16b--1X_-01X_111X_XXXX")
Parameters:
  • x0Bits or string literal.

  • xs – Sequence of Bits equal size to x0.

Returns:

Bits equal size to x0.

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

  • ValueError – Error parsing string literal.

seqlogic.bits.and_(x0: Bits | str, *xs: Bits | str) Bits#

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:

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

  • xs – Sequence of Bits equal size to x0.

Returns:

Bits equal size to x0.

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

  • ValueError – Error parsing string literal.

seqlogic.bits.xnor(x0: Bits | str, *xs: Bits | str) Bits#

N-ary bitwise logical XNOR operator.

Perform logical XNOR on each bit of the inputs:

x0

x1

XNOR(x0, x1)

Note

0

0

1

0

1

0

1

0

0

1

1

1

X

{0, 1, -}

X

X dominates all

-

{0, 1. -}

-

- dominates known

For example:

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

In expressions, you can use the unary ~ and binary ^ operators:

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

  • xs – Sequence of Bits equal size to x0.

Returns:

Bits equal size to x0.

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

  • ValueError – Error parsing string literal.

seqlogic.bits.xor(x0: Bits | str, *xs: Bits | str) Bits#

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:

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

  • xs – Sequence of Bits equal size to x0.

Returns:

Bits equal size to x0.

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

  • ValueError – Error parsing string literal.

seqlogic.bits.ite(s: Bits | str, x1: Bits | str, x0: Bits | str) Bits#

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:
  • s

  • x1Bits or string literal.

  • x0Bits or string literal equal size to x1.

Returns:

Bits equal size to x1.

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

  • ValueError – Error parsing string literal.

Unary#

seqlogic.bits.uor(x: Bits | str) 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:

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

xBits or string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Bits object.

  • ValueError – Error parsing string literal.

seqlogic.bits.uand(x: Bits | str) 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:

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

xBits or string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Bits object.

  • ValueError – Error parsing string literal.

seqlogic.bits.uxnor(x: Bits | str) Scalar#

Unary XNOR reduction operator.

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

For example:

>>> uxnor("4b1010")
bits("1b1")

Empty input returns identity:

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

xBits or string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Bits object.

  • ValueError – Error parsing string literal.

seqlogic.bits.uxor(x: Bits | str) 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:

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

xBits or string literal.

Returns:

Scalar

Raises:
  • TypeErrorx is not a valid Bits object.

  • ValueError – Error parsing string literal.

Arithmetic#

Word#

Predicate#

seqlogic.bits.eq(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.ne(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.lt(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.le(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.gt(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.ge(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.slt(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.sle(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.sgt(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

seqlogic.bits.sge(x0: Bits | str, x1: Bits | str) 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:
  • x0Bits or string literal.

  • x1Bits or string literal equal size to x0.

Returns:

Scalar

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

  • ValueError – Error parsing string literal.

Factory Functions#