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

View file

@ -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):