back.rtlil: only emit each AnyConst/AnySeq cell once.
authorwhitequark <cz@m-labs.hk>
Fri, 18 Jan 2019 01:27:17 +0000 (01:27 +0000)
committerwhitequark <cz@m-labs.hk>
Fri, 18 Jan 2019 01:34:48 +0000 (01:34 +0000)
These are semantically like signals, not like constants.

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

index 5225cf975dc2a1aa23391264f4d3d5dc6726be09..7c0dda7c3d2f8e431b46f6f0412eb76980db563d 100644 (file)
@@ -227,6 +227,7 @@ class _ValueCompilerState:
         self.wires  = ast.SignalDict()
         self.driven = ast.SignalDict()
         self.ports  = ast.SignalDict()
+        self.anys   = ast.ValueDict()
 
         self.expansions = ast.ValueDict()
 
@@ -377,6 +378,9 @@ class _RHSValueCompiler(_ValueCompiler):
             return "{}'{:0{}b}".format(value.nbits, value_twos_compl, value.nbits)
 
     def on_AnyConst(self, value):
+        if value in self.s.anys:
+            return self.s.anys[value]
+
         res_bits, res_sign = value.shape()
         res = self.s.rtlil.wire(width=res_bits)
         self.s.rtlil.cell("$anyconst", ports={
@@ -384,9 +388,13 @@ class _RHSValueCompiler(_ValueCompiler):
         }, params={
             "WIDTH": res_bits,
         }, src=src(value.src_loc))
+        self.s.anys[value] = res
         return res
 
     def on_AnySeq(self, value):
+        if value in self.s.anys:
+            return self.s.anys[value]
+
         res_bits, res_sign = value.shape()
         res = self.s.rtlil.wire(width=res_bits)
         self.s.rtlil.cell("$anyseq", ports={
@@ -394,6 +402,7 @@ class _RHSValueCompiler(_ValueCompiler):
         }, params={
             "WIDTH": res_bits,
         }, src=src(value.src_loc))
+        self.s.anys[value] = res
         return res
 
     def on_Signal(self, value):
index 735f412b0ad0ec23bda0fcb9bb115b7757de04c7..3ae5370eadeb629ff8ccef29b652da6bb4be50b3 100644 (file)
@@ -255,7 +255,7 @@ class Const(Value):
 C = Const  # shorthand
 
 
-class AnyValue(Value):
+class AnyValue(Value, DUID):
     def __init__(self, shape):
         super().__init__(src_loc_at=0)
         if isinstance(shape, int):
@@ -1119,7 +1119,7 @@ class ValueKey:
     def __hash__(self):
         if isinstance(self.value, Const):
             return hash(self.value.value)
-        elif isinstance(self.value, Signal):
+        elif isinstance(self.value, (Signal, AnyValue)):
             return hash(self.value.duid)
         elif isinstance(self.value, (ClockSignal, ResetSignal)):
             return hash(self.value.domain)
@@ -1149,7 +1149,7 @@ class ValueKey:
 
         if isinstance(self.value, Const):
             return self.value.value == other.value.value
-        elif isinstance(self.value, Signal):
+        elif isinstance(self.value, (Signal, AnyValue)):
             return self.value is other.value
         elif isinstance(self.value, (ClockSignal, ResetSignal)):
             return self.value.domain == other.value.domain
@@ -1191,7 +1191,7 @@ class ValueKey:
 
         if isinstance(self.value, Const):
             return self.value < other.value
-        elif isinstance(self.value, Signal):
+        elif isinstance(self.value, (Signal, AnyValue)):
             return self.value.duid < other.value.duid
         elif isinstance(self.value, Slice):
             return (ValueKey(self.value.value) < ValueKey(other.value.value) and