back.rtlil: avoid unsoundness for division by zero.
authorwhitequark <whitequark@whitequark.org>
Fri, 4 Oct 2019 07:56:06 +0000 (07:56 +0000)
committerwhitequark <whitequark@whitequark.org>
Fri, 4 Oct 2019 08:15:45 +0000 (08:15 +0000)
Fixes #238.

nmigen/back/rtlil.py

index eb26bf8935f370736ce86c3b2c5528b3d718b906..e96236680b3446fd278afe2a56996c2f9259490b 100644 (file)
@@ -505,6 +505,18 @@ class _RHSValueCompiler(_ValueCompiler):
             "B_WIDTH": rhs_bits,
             "Y_WIDTH": res_bits,
         }, src=src(value.src_loc))
+        if value.op in ("//", "%"):
+            # RTLIL leaves division by zero undefined, but we require it to return zero.
+            divmod_res = res
+            res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
+            self.s.rtlil.cell("$mux", ports={
+                "\\A": divmod_res,
+                "\\B": self(ast.Const(0, (res_bits, res_sign))),
+                "\\S": self(lhs == 0),
+                "\\Y": res,
+            }, params={
+                "WIDTH": res_bits
+            }, src=src(value.src_loc))
         return res
 
     def on_Operator_mux(self, value):