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