Tuple

Represents a generic heterogeneous container type akin to records and structs in other HDLs.

A concrete Tuple type is created by describing the fields it consists of. There are two ways of creating a concrete Tuple type: with or without specifying the names of the fields. If field names are unimportant, the type is created by listing the field types in square brackets. For an example, a 2D Point type, where each coordinate is represented by an 8 bit unsigned integer (Uint) can be specified like this:

Point = Tuple[Uint[8], Uint[8]]

This is same as if the tuple of types were supplied:

fields = (Uint[8], Uint[8])
Point = Tuple[fields]

The Point type is now represented by a Tuple with two fields. If we want to name the fields, we need to specify the fields in form of the Python dict, with keys as field names and values as field types:

Point = Tuple[{
    'x': Uint[8],
    'y': Uint[8]
}]

If we want to create a type that is generic in terms of the field types, we can provide a placeholder name instead of the concrete type:

Point = Tuple[{
    'x': 'coord_t',
    'y': 'coord_t'
}]

Point is now a generic template type, represented by a Tuple with two fields of the same type, which is not yet specified. The Point template has a single parameter coord_t, which needs to be specified to get a concrete type. So if we want to obtain a Point with 8 bit coordinates, we can write:

PointU8 = Point[Uint[8]]

We can also be explicit which template parameter is assigned a concrete type:

PointU8 = Point[{'coord_t': Uint[8]}]

Tuples can have any other types for their fields, meaning they can be nested to create more complex structures:

Line = Tuple[Point, Point]
LineU8 = Line[Uint[8]]
>>> LineU8
Tuple[Tuple[{'x': Uint[8], 'y': Uint[8]}], Tuple[{'x': Uint[8], 'y': Uint[8]}]]

The above example shows that the set of template parameters of a Tuple template type is the union of the sets of template parameters of all Tuple fields. Since all Line template fields have the same template parameter coord_t, Line itself has only one template parameter, namely coord_t:

>>> Line.templates
['coord_t']

If this behaviour is not desired, template arguments can also be renamed by specifying a string instead of the concrete type for the template parameter:

Line = Tuple[Point['coord1_t'], Point['coord2_t']]
LineU8_U16 = Line[Uint[8], Uint[16]]
>>> Line
Tuple[Tuple[{'x': 'coord1_t', 'y': 'coord1_t'}], Tuple[{'x': 'coord2_t', 'y': 'coord2_t'}]]
>>> LineU8_U16
Tuple[Tuple[{'x': Uint[8], 'y': Uint[8]}], Tuple[{'x': Uint[16], 'y': Uint[16]}]]

Once a concrete type has been formed it can be instantiated which is useful for the verification. Type instance is obtained by specifying the values for the Tuple fields in parenthesis, grouped in the Python tuple (can be any iterable really):

ab = LineU8_U16(((0, 0), (1, 1)))
>>> ab[0]
(Uint[8](0), Uint[8](0))
>>> ab[0]['x']
Uint[8](0)
class TupleType

Bases: pygears.typing.base.EnumerableGenericMeta

Implements the Tuple generic type.

All operations on the Tuple type are implemented here in the TupleType class. Operations on the Tuple type instances are defined in the Tuple class.

__add__(other)

Combines the fields of two Tuple types.

>>> Tuple[{'x': Uint[8], 'y': Uint[8]}] + Tuple[{'x': Uint[8], 'z': Uint[8]}]
Tuple[{'x': Uint[8], 'y': Uint[8], 'z': Uint[8]}]
__getitem__(key)

Get the type of the field or fields specified by the key.

Point3 = Tuple[{'x': Uint[8], 'y': Uint[8], 'z': Uint[16]}]

The key can be a name of the field:

>>> Point3['x']
Uint[8]

The key can be a number that represents the index of the field within the Tuple:

>>> Point3[2]
Uint[16]

Negative keys are accepted to index from the end of the Tuple:

>>> Point3[-1]
Uint[16]

Slices are accepted to return a new Tuple with a subset of fields:

>>> Point3[:2]
Tuple[Uint[8], Uint[8]]

The key can be a sequence of the names, number indexes or slices, where a new Tuple is return with a subset of fields given by the keys in the sequence:

>>> Point3['x', -1]
Tuple[Uint[8], Uint[16]]
__int__()

Calculates the bit width of the type.

>>> int(Tuple[Uint[1], Uint[2]])
3
args

Returns a list of values supplied for each generic parameter.

>>> Tuple[Uint[1], Uint[2]].args
[Uint[1], Uint[2]]
base

Returns base generic class of the type.

>>> assert Uint[16].base == Uint
fields

Returns the names of the generic parameters.

>>> Tuple[Uint[1], Uint[2]].fields
('f0', 'f1')
>>> Tuple[{'u1': Uint[1], 'u2': Uint[2]}].fields
('u0', 'u1')
get(name, default=None)

Calls __getitem__() and returns the default value if it fails.

Parameters

default – Type to return if __getitem__() fails

is_generic()

Return True if no values have been supplied for the generic parameters.

>>> Uint.is_generic()
True
>>> Uint['template'].is_generic()
False
is_specified

Return True if all generic parameters were supplied concrete values.

>>> Uint['template'].is_specified()
False
>>> Uint[16].is_specified()
True
items()

Generator that yields (key, element) pairs.

keys()

Returns a list of keys that can be used for indexing the type.

templates

Returns a list of templated generic variables within the type. The type is searched recursively. Each template is reported only once.

>>> Tuple[Tuple['T1', 'T2'], 'T1'].templates
['T1', 'T2']
class Tuple

Bases: tuple

Implements the Tuple type instance.

The Tuple type instance can be initialized either with a dict that maps the field names to the desired values:

Point = Tuple[{'x': Uint[8], 'y': Uint[8]}]
>>> Point({'y': 0, 'x': 1})
(Uint[8](1), Uint[8](0))

or with an iterable which enumerates values for all the Tuple fields in order:

>>> Point((1, 0))
(Uint[8](1), Uint[8](0))
__getitem__(key)

Returns the value of the field or fields specified by the key.

Point3 = Tuple[{'x': Uint[8], 'y': Uint[8], 'z': Uint[16]}]
point_a = Point3((1, 2, 3))

The key can be a name of the field:

>>> point_a['x']
Uint[8](1)

The key can be a number that represents the index of the field within the Tuple:

>>> point_a[2]
Uint[16](3)

Negative keys are accepted to index from the end of the Tuple:

>>> point_a[-1]
Uint[16](3)

Slices are accepted to return a new Tuple with a subset of fields:

>>> point_a[:2]
(Uint[8](1), Uint[8](2))

The key can be a sequence of the names, number indexes or slices, where a new Tuple is return with a subset of fields given by the keys in the sequence:

>>> point_a['x', -1]
(Uint[8](1), Uint[16](3))
__int__()

Returns a packed integer representation of the Tuple instance.

Point = Tuple[{'x': Uint[8], 'y': Uint[8]}]
>>> int(Point((0xaa, 0xbb)))
48042
>>> hex(48042)
'0xbbaa'
classmethod decode(val)

Returns a Tuple instance from its packed integer representation.

Point = Tuple[{'x': Uint[8], 'y': Uint[8]}]
>>> Point.decode(0xbbaa)
(Uint[8](170), Uint[8](187))
get(name, default=None)

Calls __getitem__() and returns the default value if it fails.

Parameters

default – Type to return if __getitem__() fails