back.rtlil: translate enum decoders to Yosys enum attributes.
authorwhitequark <whitequark@whitequark.org>
Wed, 15 Apr 2020 14:42:46 +0000 (14:42 +0000)
committerwhitequark <whitequark@whitequark.org>
Wed, 15 Apr 2020 14:45:59 +0000 (14:45 +0000)
Fixes #254.

nmigen/back/rtlil.py
nmigen/hdl/ast.py

index 90c5ed9a1c7db8a0b0e483d8a2616b8f03834501..120a354ee21332f30a706ebf979136d06eddfce4 100644 (file)
@@ -306,10 +306,15 @@ class _ValueCompilerState:
         else:
             wire_name = signal.name
 
+        attrs = dict(signal.attrs)
+        if signal._enum_class is not None:
+            attrs["enum_base_type"] = signal._enum_class.__name__
+            for value in signal._enum_class:
+                attrs["enum_value_{:0{}b}".format(value.value, signal.width)] = value.name
+
         wire_curr = self.rtlil.wire(width=signal.width, name=wire_name,
                                     port_id=port_id, port_kind=port_kind,
-                                    attrs=signal.attrs,
-                                    src=src(signal.src_loc))
+                                    attrs=attrs, src=src(signal.src_loc))
         if signal in self.driven and self.driven[signal]:
             wire_next = self.rtlil.wire(width=signal.width, name=wire_curr + "$next",
                                         src=src(signal.src_loc))
index 7e42c2a81c740dc5e55eafcf5c3692e6227b1a46..45dab3d06dd8337bff8cf2c1dbef0e0659d97153 100644 (file)
@@ -425,7 +425,7 @@ class Value(metaclass=ABCMeta):
 
     def rotate_left(self, offset):
         """Rotate left by constant modulo 2**len(self).
-        
+
         Parameters
         ----------
         offset : int
@@ -443,7 +443,7 @@ class Value(metaclass=ABCMeta):
 
     def rotate_right(self, offset):
         """Rotate right by constant modulo 2**len(self).
-        
+
         Parameters
         ----------
         offset : int
@@ -922,8 +922,10 @@ class Signal(Value, DUID):
                 except ValueError:
                     return str(value)
             self.decoder = enum_decoder
+            self._enum_class = decoder
         else:
             self.decoder = decoder
+            self._enum_class = None
 
     # Not a @classmethod because nmigen.compat requires it.
     @staticmethod