back.rtlil: use a dummy wire, not 'x, when assigning to shorter LHS.
authorwhitequark <whitequark@whitequark.org>
Sat, 3 Aug 2019 23:57:50 +0000 (23:57 +0000)
committerwhitequark <whitequark@whitequark.org>
Sun, 4 Aug 2019 00:12:08 +0000 (00:12 +0000)
Using 'x is legal RTLIL, in theory, but in practice it crashes Yosys
and when it doesn't, it causes Yosys to produce invalid Verilog.
Using a dummy wire is always safe and is not a major readability
issue as this is a rare corner case.

(It is not trivial to shorten the RHS in this case, because during
expansion of an ArrayProxy, match_shape() could be called in
a context far from the RHS handling logic.)

nmigen/back/rtlil.py

index 6ef0d8691561b4cda7a6a6daabff675fe35e804e..ac2b99fc0d9dc4d0c08fcdcc4b60bd730695fe26 100644 (file)
@@ -578,9 +578,9 @@ class _LHSValueCompiler(_ValueCompiler):
         elif new_bits < value_bits:
             return self(ast.Slice(value, 0, new_bits))
         else: # new_bits > value_bits
-            # It is legal to assign to constants on LHS in RTLIL; such assignments are ignored.
             dummy_bits = new_bits - value_bits
-            return "{{ {}'{} {} }}".format(dummy_bits, "x" * dummy_bits, self(value))
+            dummy_wire = self.s.rtlil.wire(dummy_bits)
+            return "{{ {} {} }}".format(dummy_wire, self(value))
 
     def on_Signal(self, value):
         if value not in self.s.driven: