shrink signal widths
authorJacob Lifshay <programmerjake@gmail.com>
Thu, 5 May 2022 06:23:21 +0000 (23:23 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Thu, 5 May 2022 06:23:21 +0000 (23:23 -0700)
src/nmigen_gf/hdl/cldivrem.py

index 897ced521446fbc66ee00cc0c5f7541921e820b2..02ce034dcfb92aec4f6d2aa0eb0406e9c5358d94 100644 (file)
@@ -120,18 +120,27 @@ def cldivrem_shifting(n, d, width):
     assert isinstance(n, int) and 0 <= n < 1 << width
     assert isinstance(d, int) and 0 <= d < 1 << width
     assert d != 0, "TODO: decide what happens on division by zero"
-    shift = clz(d, width)
+
+    shift_wid = (width - 1).bit_length()
+
+    # `clz(d, width)`, but maxes out at `width - 1` instead of `width` in
+    # order to both fit in `shift_wid` bits and not shift by more than needed.
+    shift = clz(d >> 1, width - 1)
+    assert shift < 1 << shift_wid, f"shift overflows a {shift_wid}-bit signal"
     d <<= shift
+    assert d < 1 << width, f"d overflows a {width}-bit signal"
     n <<= shift
+    assert n < 1 << (width * 2), f"n overflows a {width * 2}-bit signal"
     r = n
     q = 0
-    d <<= width
     for _ in range(width):
         q <<= 1
         r <<= 1
         if r >> (width * 2 - 1) != 0:
-            r ^= d
+            r ^= d << width
             q |= 1
+        assert q < 1 << width, f"q overflows a {width}-bit signal"
+        assert r < 1 << (width * 2), f"r overflows a {width * 2}-bit signal"
     r >>= width
     r >>= shift
     return q, r