hdl.ast: recognize a Enum used as decoder and format it better.
This commit is contained in:
parent
7cc0b8cbf0
commit
0ab215e5ed
|
@ -3,6 +3,7 @@ import builtins
|
||||||
import traceback
|
import traceback
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from collections.abc import Iterable, MutableMapping, MutableSet, MutableSequence
|
from collections.abc import Iterable, MutableMapping, MutableSet, MutableSequence
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
from .. import tracer
|
from .. import tracer
|
||||||
from ..tools import *
|
from ..tools import *
|
||||||
|
@ -575,9 +576,11 @@ class Signal(Value, DUID):
|
||||||
defaults to 0) and ``max`` (exclusive, defaults to 2).
|
defaults to 0) and ``max`` (exclusive, defaults to 2).
|
||||||
attrs : dict
|
attrs : dict
|
||||||
Dictionary of synthesis attributes.
|
Dictionary of synthesis attributes.
|
||||||
decoder : function
|
decoder : function or Enum
|
||||||
A function converting integer signal values to human-readable strings (e.g. FSM state
|
A function converting integer signal values to human-readable strings (e.g. FSM state
|
||||||
names).
|
names). If an ``Enum`` subclass is passed, it is concisely decoded using format string
|
||||||
|
``"{0.name:}/{0.value:}"``, or a number if the signal value is not a member of
|
||||||
|
the enumeration.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
----------
|
----------
|
||||||
|
@ -627,7 +630,15 @@ class Signal(Value, DUID):
|
||||||
self.reset_less = bool(reset_less)
|
self.reset_less = bool(reset_less)
|
||||||
|
|
||||||
self.attrs = OrderedDict(() if attrs is None else attrs)
|
self.attrs = OrderedDict(() if attrs is None else attrs)
|
||||||
self.decoder = decoder
|
if isinstance(decoder, type) and issubclass(decoder, Enum):
|
||||||
|
def enum_decoder(value):
|
||||||
|
try:
|
||||||
|
return "{0.name:}/{0.value:}".format(decoder(value))
|
||||||
|
except ValueError:
|
||||||
|
return str(value)
|
||||||
|
self.decoder = enum_decoder
|
||||||
|
else:
|
||||||
|
self.decoder = decoder
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def like(cls, other, name=None, name_suffix=None, src_loc_at=0, **kwargs):
|
def like(cls, other, name=None, name_suffix=None, src_loc_at=0, **kwargs):
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
from ..hdl.ast import *
|
from ..hdl.ast import *
|
||||||
from .tools import *
|
from .tools import *
|
||||||
|
|
||||||
|
@ -486,6 +488,14 @@ class SignalTestCase(FHDLTestCase):
|
||||||
s8 = Signal.like(s1, name_suffix="_ff")
|
s8 = Signal.like(s1, name_suffix="_ff")
|
||||||
self.assertEqual(s8.name, "s1_ff")
|
self.assertEqual(s8.name, "s1_ff")
|
||||||
|
|
||||||
|
def test_decoder(self):
|
||||||
|
class Color(Enum):
|
||||||
|
RED = 1
|
||||||
|
BLUE = 2
|
||||||
|
s = Signal(decoder=Color)
|
||||||
|
self.assertEqual(s.decoder(1), "RED/1")
|
||||||
|
self.assertEqual(s.decoder(3), "3")
|
||||||
|
|
||||||
|
|
||||||
class ClockSignalTestCase(FHDLTestCase):
|
class ClockSignalTestCase(FHDLTestCase):
|
||||||
def test_domain(self):
|
def test_domain(self):
|
||||||
|
|
Loading…
Reference in a new issue