66 lines
1.8 KiB
Python
Executable File
66 lines
1.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Quick reference model for sequential unsigned multiply/divide/modulo
|
|
|
|
def div_step(w, accum, divisor):
|
|
sub_tmp = accum - (divisor << (w - 1))
|
|
underflow = sub_tmp < 0
|
|
if not underflow:
|
|
accum = sub_tmp
|
|
accum = (accum << 1) | (not underflow)
|
|
return accum
|
|
|
|
def divmod(w, dividend, divisor, debug=True):
|
|
accum = dividend
|
|
for i in range(w):
|
|
accum_prev = accum
|
|
accum = div_step(w, accum, divisor)
|
|
if debug:
|
|
print("Step {:02d}: accum {:0{}x} -> {:0{}x}".format(
|
|
i, accum_prev, int(w / 2), accum, int(w / 2)))
|
|
return (accum >> w, accum & ((1 << w) - 1))
|
|
|
|
def mul_step(w, accum, multiplicand):
|
|
add_en = accum & 1
|
|
accum = accum >> 1
|
|
if add_en:
|
|
accum += (multiplicand << (w - 1))
|
|
return accum
|
|
|
|
def mul(w, multiplicand, multiplier, debug=True):
|
|
accum = multiplier
|
|
for i in range(w):
|
|
accum_prev = accum
|
|
accum = mul_step(w, accum, multiplicand)
|
|
if debug:
|
|
print("Step {:02d}: accum {:0{}x} -> {:0{}x}".format(
|
|
i, accum_prev, int(w / 2), accum, int(w / 2)))
|
|
return (accum >> w, accum & ((1 << w) - 1))
|
|
|
|
def divtest(w=4):
|
|
for i in range(2 ** w):
|
|
for j in range(1, 2 ** w):
|
|
gatemod, gatediv = divmod(w, i, j, debug=False)
|
|
goldmod, golddiv = (i % j, i // j)
|
|
print("{:02d} % {:02d} = {:02d} (gold {:02d}); ./. = {:02d} (gold {:02d})"
|
|
.format(i, j, gatemod, goldmod, gatediv, golddiv))
|
|
assert(gatemod == goldmod)
|
|
assert(gatediv == golddiv)
|
|
|
|
def multest(w=4):
|
|
for i in range(2 ** w):
|
|
for j in range(2 ** w):
|
|
gateh, gatel = mul(w, i, j, debug=False)
|
|
gold = i * j
|
|
goldl, goldh = (gold & ((1 << w) - 1), gold >> w)
|
|
print("{:02d} * {:02d} = ({:02d} (gold {:02d}), {:02d} (gold {:02d})"
|
|
.format(i, j, gateh, goldh, gatel, goldl))
|
|
assert(gatel == goldl)
|
|
assert(gateh == goldh)
|
|
|
|
if __name__ == "__main__":
|
|
print("Test division:")
|
|
divtest()
|
|
print("Test multiplication:")
|
|
multest()
|