sim._pyrtl: sign extend RHS of assignment.
authorwhitequark <whitequark@whitequark.org>
Thu, 22 Oct 2020 16:08:38 +0000 (16:08 +0000)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 31 Dec 2021 15:15:27 +0000 (15:15 +0000)
Fixes #502.

nmigen/sim/_pyrtl.py
tests/test_sim.py

index d7b432606134b8ea21aca1b1c53636027a75d44d..f7abc3bb9df82a08280a53a7407c0b281c495e40 100644 (file)
@@ -337,7 +337,10 @@ class _StatementCompiler(StatementVisitor, _Compiler):
             self.emitter.append("pass")
 
     def on_Assign(self, stmt):
-        return self.lhs(stmt.lhs)(self.rhs(stmt.rhs))
+        gen_rhs = f"({(1 << len(stmt.rhs)) - 1} & {self.rhs(stmt.rhs)})"
+        if stmt.rhs.shape().signed:
+            gen_rhs = f"sign({gen_rhs}, {-1 << (len(stmt.rhs) - 1)})"
+        return self.lhs(stmt.lhs)(gen_rhs)
 
     def on_Switch(self, stmt):
         gen_test = self.emitter.def_var("test",
index bb806f26574fc9a21bcc12ac10a2533b461fba1d..d2d255f5e94853f1d5ba06154267746b60da2d3c 100644 (file)
@@ -67,6 +67,11 @@ class SimulatorUnitTestCase(FHDLTestCase):
         self.assertStatement(stmt, [C(0b01, unsigned(2)), C(0b0001, signed(4))], C(1))
         self.assertStatement(stmt, [C(0b11, unsigned(2)), C(0b1111, signed(4))], C(1))
 
+    def test_as_signed_issue_502(self):
+        stmt = lambda y, a: y.eq(a.as_signed())
+        self.assertStatement(stmt, [C(0b01, unsigned(2))], C(0b0001, signed(4)))
+        self.assertStatement(stmt, [C(0b11, unsigned(2))], C(0b1111, signed(4)))
+
     def test_any(self):
         stmt = lambda y, a: y.eq(a.any())
         self.assertStatement(stmt, [C(0b00, 2)], C(0))