Language reference

Warning

This reference is a work in progress and is seriously incomplete!

While the wording below states that anything not described in this document isn’t covered by the backwards compatibility guarantee, this should be ignored until the document is complete and this warning is removed.

This reference describes the Python classes that underlie the Amaranth language’s syntax. It assumes familiarity with the language guide.

Backwards compatibility

As part of the Amaranth backwards compatibility guarantee, any behaviors described in this document will not change from a version to another without at least one version including a warning about the impending change. Any nontrivial change to these behaviors must also go through the public review as a part of the Amaranth Request for Comments process.

Conversely, any behavior not documented here is subject to change at any time with or without notice, and any names under the amaranth.hdl module that are not explicitly included in this document, even if they do not begin with an underscore, are internal to the implementation of the language.

Importing syntax

There are two ways to import the Amaranth syntax into a Python file: by importing the prelude or by importing individual names from the amaranth.hdl module. Since the prelude is kept small and rarely extended to avoid breaking downstream code that uses a glob import, there are some names that are only exported from the amaranth.hdl module. The following three snippets are equivalent:

from amaranth import *

m = Module()
import amaranth as am

m = am.Module()
from amaranth.hdl import Module

m = Module()

The prelude exports exactly the following names:

  • Shape

  • unsigned()

  • signed()

  • Value

  • Const

  • C()

  • Mux()

  • Cat

  • Repl (deprecated)

  • Array

  • Signal

  • ClockSignal

  • ResetSignal

  • Module

  • ClockDomain

  • Elaboratable

  • Fragment

  • Instance

  • Memory

  • Record (deprecated)

  • DomainRenamer

  • ResetInserter

  • EnableInserter

Source locations

Many functions and methods in Amaranth take the src_loc_at=0 keyword argument. These language constructs may inspect the call stack to determine the file and line of its call site, which will be used to annotate generated code when a netlist is generated or to improve diagnostic messages.

Some call sites are not relevant for an Amaranth designer; e.g. when an Amaranth language construct is called from a user-defined utility function, the source location of the call site within this utility function is usually not interesting to the designer. In these cases, one or more levels of function calls can be removed from consideration using the src_loc_at argument as follows (using Shape.cast() to demonstrate the concept):

def my_shape_cast(obj, *, src_loc_at=0):
    ... # additionally process `obj`...
    return Shape.cast(obj, src_loc_at=1 + src_loc_at)

The number 1 corresponds to the number of call stack frames that should be skipped.

Shapes

See also the introduction to shapes and casting from shape-like objects in the language guide.

class amaranth.hdl.Shape(width=1, signed=False)

Bit width and signedness of a value.

A Shape can be obtained by:

  • constructing with explicit bit width and signedness;

  • using the signed() and unsigned() aliases if the signedness is known upfront;

  • casting from a variety of objects using the cast() method.

Parameters:
  • width (int) – The number of bits in the representation of a value. This includes the sign bit for signed values. Cannot be zero if the value is signed.

  • signed (bool) – Whether the value is signed. Signed values use the two’s complement representation.

static cast(obj, *, src_loc_at=0)

Cast obj to a shape.

Many shape-like objects can be cast to a shape:

  • a Shape, where the result is itself;

  • an int, where the result is unsigned(obj);

  • a range, where the result is wide enough to represent any element of the range, and is signed if any element of the range is signed;

  • an enum.Enum whose members are all constant-castable or enum.IntEnum, where the result is wide enough to represent any member of the enumeration, and is signed if any member of the enumeration is signed;

  • a ShapeCastable object, where the result is obtained by repeatedly calling obj.as_shape().

Raises:
__repr__()

Python code that creates this shape.

Returns f"signed({self.width})" or f"unsigned({self.width})".

amaranth.hdl.unsigned(width)

Returns Shape(width, signed=False).

amaranth.hdl.signed(width)

Returns Shape(width, signed=True).

class amaranth.hdl.ShapeCastable

Interface class for objects that can be cast to a Shape.

Shapes of values in the Amaranth language are specified using shape-like objects. Inheriting a class from ShapeCastable and implementing all of the methods described below adds instances of that class to the list of shape-like objects recognized by the Shape.cast() method. This is a part of the mechanism for seamlessly extending the Amaranth language in third-party code.

To illustrate their purpose, consider constructing a signal from a shape-castable object shape_castable:

value_like = Signal(shape_castable, reset=initializer)

The code above is equivalent to:

value_like = shape_castable(Signal(
    shape_castable.as_shape(),
    reset=shape_castable.const(initializer)
))

Note that the shape_castable(x) syntax performs shape_castable.__call__(x).

Tip

The source code of the amaranth.lib.data module can be used as a reference for implementing a fully featured shape-castable object.

as_shape()

Convert self to a shape-like object.

This method is called by the Amaranth language to convert self to a concrete Shape. It will usually return a Shape object, but it may also return another shape-like object to delegate its functionality.

This method must be idempotent: when called twice on the same object, the result must be exactly the same.

This method may also be called by code that is not a part of the Amaranth language.

Return type:

Any other object recognized by Shape.cast().

Raises:

Exception – When the conversion cannot be done. This exception must be propagated by callers (except when checking whether an object is shape-castable or not), either directly or as a cause of another exception.

const(obj)

Convert a constant initializer obj to its value representation.

This method is called by the Amaranth language to convert obj, which may be an arbitrary Python object, to a concrete value-like object. The object obj will usually be a Python literal that can conveniently represent a constant value whose shape is described by self. While not constrained here, the result will usually be an instance of the return type of __call__().

For any obj, the following condition must hold:

Shape.cast(self) == Const.cast(self.const(obj)).shape()

This method may also be called by code that is not a part of the Amaranth language.

Return type:

A value-like object that is constant-castable.

Raises:

Exception – When the conversion cannot be done. This exception must be propagated by callers, either directly or as a cause of another exception. While not constrained here, usually the exception class will be TypeError or ValueError.

__call__(obj)

Lift a value-like object to a higher-level representation.

This method is called by the Amaranth language to lift obj, which may be any value-like object whose shape equals Shape.cast(self), to a higher-level representation, which may be any value-like object with the same shape. While not constrained here, usually a ShapeCastable implementation will be paired with a ValueCastable implementation, and this method will return an instance of the latter.

If obj is not as described above, this interface does not constrain the behavior of this method. This may be used to implement another call-based protocol at the same time.

For any compliant obj, the following condition must hold:

Value.cast(self(obj)) == Value.cast(obj)

This method may also be called by code that is not a part of the Amaranth language.

Return type:

A value-like object.

class amaranth.hdl.ShapeLike(*args, **kwargs)

An abstract class representing all objects that can be cast to a Shape.

issubclass(cls, ShapeLike) returns True for:

isinstance(obj, ShapeLike) returns True for:

This class cannot be instantiated or subclassed. It can only be used for checking types of objects.