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
.
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: