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()
 |