Enumerations
The amaranth.lib.enum
module is a drop-in replacement for the standard enum
module that provides extended Enum
, IntEnum
, Flag
, and IntFlag
classes with the ability to specify a shape explicitly.
A shape can be specified for an enumeration with the shape=
keyword argument:
from amaranth.lib import enum
class Funct(enum.Enum, shape=4):
ADD = 0
SUB = 1
MUL = 2
>>> Shape.cast(Funct)
unsigned(4)
>>> Value.cast(Funct.ADD)
(const 4'd0)
Any constant-castable expression can be used as the value of a member:
class Op(enum.Enum, shape=1):
REG = 0
IMM = 1
class Instr(enum.Enum, shape=5):
ADD = Cat(Funct.ADD, Op.REG)
ADDI = Cat(Funct.ADD, Op.IMM)
SUB = Cat(Funct.SUB, Op.REG)
SUBI = Cat(Funct.SUB, Op.IMM)
...
>>> Instr.SUBI
<Instr.SUBI: 17>
The shape=
argument is optional. If not specified, classes from this module behave exactly the same as classes from the standard enum
module, and likewise, this module re-exports everything exported by the standard enum
module.
import amaranth.lib.enum
class NormalEnum(amaranth.lib.enum.Enum):
SPAM = 0
HAM = 1
In this way, this module is a drop-in replacement for the standard enum
module, and in an Amaranth project, all import enum
statements may be replaced with from amaranth.lib import enum
.
Signals with Enum
or Flag
based shape are automatically wrapped in the EnumView
or FlagView
value-like wrappers, which ensure type safety. Any value-like can also be explicitly wrapped in a view class by casting it to the enum type:
>>> a = Signal(Funct)
>>> b = Signal(Op)
>>> type(a)
<class 'amaranth.lib.enum.EnumView'>
>>> a == b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an EnumView can only be compared to value or other EnumView of the same enum type
>>> c = Signal(4)
>>> type(Funct(c))
<class 'amaranth.lib.enum.EnumView'>
Like the standard Python enum.IntEnum
and enum.IntFlag
classes, the Amaranth IntEnum
and IntFlag
classes are loosely typed and will not be subject to wrapping in view classes:
class TransparentEnum(enum.IntEnum, shape=unsigned(4)):
FOO = 0
BAR = 1
>>> a = Signal(TransparentEnum)
>>> type(a) is Signal
True
It is also possible to define a custom view class for a given enum:
class InstrView(enum.EnumView):
def has_immediate(self):
return (self == Instr.ADDI) | (self == Instr.SUBI)
class Instr(enum.Enum, shape=5, view_class=InstrView):
ADD = Cat(Funct.ADD, Op.REG)
ADDI = Cat(Funct.ADD, Op.IMM)
SUB = Cat(Funct.SUB, Op.REG)
SUBI = Cat(Funct.SUB, Op.IMM)
>>> a = Signal(Instr)
>>> type(a)
<class 'InstrView'>
>>> a.has_immediate()
(| (== (sig a) (const 5'd16)) (== (sig a) (const 5'd17)))
Metaclass
- class amaranth.lib.enum.EnumMeta
Subclass of the standard
enum.EnumMeta
that implements theShapeCastable
protocol.This metaclass provides the
as_shape()
method, making its instances shape-like, and accepts ashape=
keyword argument to specify a shape explicitly. Other than this, it acts the same as the standardenum.EnumMeta
class; if theshape=
argument is not specified andas_shape()
is never called, it places no restrictions on the enumeration class or the values of its members.When a value-like is cast to an enum type that is an instance of this metaclass, it can be automatically wrapped in a view class. A custom view class can be specified by passing the
view_class=
keyword argument when creating the enum class.- as_shape()
Cast this enumeration to a shape.
- Returns:
Explicitly provided shape. If not provided, returns the result of shape-casting this class as a standard Python enumeration.
- Return type:
Shape
- Raises:
TypeError – If the enumeration has neither an explicitly provided shape nor any members.
- __call__(value, *args, **kwargs)
Cast the value to this enum type.
When given an integer constant, it returns the corresponding enum value, like a standard Python enumeration.
When given a value-like, it is cast to a value, then wrapped in the
view_class
specified for this enum type (EnumView
forEnum
,FlagView
forFlag
, or a custom user-defined class). If the type has noview_class
(likeIntEnum
orIntFlag
), a plainValue
is returned.- Returns:
instance of itself – For integer values, or instances of itself.
EnumView
or its subclass – For value-castables, as defined by theview_class
keyword argument.Value
– For value-castables, when a view class is not specified for this enum.
- 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 objectobj
will usually be a Python literal that can conveniently represent a constant value whose shape is described byself
. 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
orValueError
.
- from_bits(bits)
Lift a bit pattern to a higher-level representation.
This method is called by the Amaranth language to lift
raw
, which is anint
, to a higher-level representation, which may be any object accepted byconst()
. Most importantly, the simulator calls this method when the value of a shape-castable object is retrieved.For any valid bit pattern
raw
, the following condition must hold:Const.cast(self.const(self.from_bits(raw))).value == raw
While
const()
will usually return an Amaranth value or a custom value-castable object that is convenient to use while constructing the design, this method will usually return a Python object that is convenient to use while simulating the design. While not constrained here, these objects should have the same type whenever feasible.This method may also be called by code that is not a part of the Amaranth language.
- Return type:
unspecified type
- Raises:
Exception – When the bit pattern isn’t valid. 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
ValueError
.
Base classes
- class amaranth.lib.enum.Enum
Subclass of the standard
enum.Enum
that hasEnumMeta
as its metaclass andEnumView
as its view class.
- class amaranth.lib.enum.IntEnum
Subclass of the standard
enum.IntEnum
that hasEnumMeta
as its metaclass.
- class amaranth.lib.enum.Flag
Subclass of the standard
enum.Flag
that hasEnumMeta
as its metaclass andFlagView
as its view class.
- class amaranth.lib.enum.IntFlag
Subclass of the standard
enum.IntFlag
that hasEnumMeta
as its metaclass.
View classes
- class amaranth.lib.enum.EnumView
The view class used for
Enum
.Wraps a
Value
and only allows type-safe operations. The only operators allowed are equality comparisons (==
and!=
) with anotherEnumView
of the same enum type.- __init__(enum, target)
Constructs a view with the given enum type and target (a value-like).
- shape()
Returns the underlying enum type.
- as_value()
Returns the underlying value.
- eq(other)
Assign to the underlying value.
- Returns:
self.as_value().eq(other)
- Return type:
Assign
- class amaranth.lib.enum.FlagView
The view class used for
Flag
.In addition to the operations allowed by
EnumView
, it allows bitwise operations among values of the same enum type.- __invert__()
Inverts all flags in this value and returns another
FlagView
.Note that this is not equivalent to applying bitwise negation to the underlying value: just like the Python
enum.Flag
class, only bits corresponding to flags actually defined in the enumeration are included in the result.- Return type:
- __and__(other)
Performs a bitwise AND and returns another
FlagView
.The other operand has to be either another
FlagView
of the same enum type, or a plain value of the underlying enum type.- Return type:
- __or__(other)
Performs a bitwise OR and returns another
FlagView
.The other operand has to be either another
FlagView
of the same enum type, or a plain value of the underlying enum type.- Return type:
- __xor__(other)
Performs a bitwise XOR and returns another
FlagView
.The other operand has to be either another
FlagView
of the same enum type, or a plain value of the underlying enum type.- Return type:
- __rand__(other)
Performs a bitwise AND and returns another
FlagView
.The other operand has to be either another
FlagView
of the same enum type, or a plain value of the underlying enum type.- Return type: