hdl.ast: recognize a Enum used as decoder and format it better.

This commit is contained in:
whitequark 2019-07-02 19:02:16 +00:00
parent 7cc0b8cbf0
commit 0ab215e5ed
2 changed files with 24 additions and 3 deletions

View file

@ -3,6 +3,7 @@ import builtins
import traceback
from collections import OrderedDict
from collections.abc import Iterable, MutableMapping, MutableSet, MutableSequence
from enum import Enum
from .. import tracer
from ..tools import *
@ -575,9 +576,11 @@ class Signal(Value, DUID):
defaults to 0) and ``max`` (exclusive, defaults to 2).
attrs : dict
Dictionary of synthesis attributes.
decoder : function
decoder : function or Enum
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
----------
@ -627,7 +630,15 @@ class Signal(Value, DUID):
self.reset_less = bool(reset_less)
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
def like(cls, other, name=None, name_suffix=None, src_loc_at=0, **kwargs):

View file

@ -1,3 +1,5 @@
from enum import Enum
from ..hdl.ast import *
from .tools import *
@ -486,6 +488,14 @@ class SignalTestCase(FHDLTestCase):
s8 = Signal.like(s1, name_suffix="_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):
def test_domain(self):