back.pysim: implement modulus operator.
authorStuart Olsen <stuart@sj-olsen.com>
Sun, 15 Mar 2020 05:22:03 +0000 (22:22 -0700)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Fri, 31 Dec 2021 13:18:38 +0000 (13:18 +0000)
nmigen/back/pysim.py
nmigen/test/test_sim.py

index 5d599a3cb60261a7d4b283f2490d130c8d935d5a..96e98e7fca55d33fc3305a000151d5c3cdef27cb 100644 (file)
@@ -363,6 +363,7 @@ class _ValueCompiler(ValueVisitor, _Compiler):
     helpers = {
         "sign": lambda value, sign: value | sign if value & sign else value,
         "zdiv": lambda lhs, rhs: 0 if rhs == 0 else lhs // rhs,
+        "zmod": lambda lhs, rhs: 0 if rhs == 0 else lhs % rhs,
     }
 
     def on_ClockSignal(self, value):
@@ -448,6 +449,8 @@ class _RHSValueCompiler(_ValueCompiler):
                 return f"({sign(lhs)} * {sign(rhs)})"
             if value.operator == "//":
                 return f"zdiv({sign(lhs)}, {sign(rhs)})"
+            if value.operator == "%":
+                return f"zmod({sign(lhs)}, {sign(rhs)})"
             if value.operator == "&":
                 return f"({self(lhs)} & {self(rhs)})"
             if value.operator == "|":
index d3585a49668e13fcb4b9e7c4a88738155816b7f9..677f2570ca9f54a5306609f177ce118394db5719 100644 (file)
@@ -110,6 +110,13 @@ class SimulatorUnitTestCase(FHDLTestCase):
         self.assertStatement(stmt, [C(2,  4), C(2,  4)], C(1,   8))
         self.assertStatement(stmt, [C(7,  4), C(2,  4)], C(3,   8))
 
+    def test_mod(self):
+        stmt = lambda y, a, b: y.eq(a % b)
+        self.assertStatement(stmt, [C(2,  4), C(0,  4)], C(0,   8))
+        self.assertStatement(stmt, [C(2,  4), C(1,  4)], C(0,   8))
+        self.assertStatement(stmt, [C(2,  4), C(2,  4)], C(0,   8))
+        self.assertStatement(stmt, [C(7,  4), C(2,  4)], C(1,   8))
+
     def test_and(self):
         stmt = lambda y, a, b: y.eq(a & b)
         self.assertStatement(stmt, [C(0b1100, 4), C(0b1010, 4)], C(0b1000, 4))