2024-04-06 16:48:27 -05:00
#!/usr/bin/env python3
2024-04-06 18:03:56 -05:00
from tabulate import tabulate
2024-04-06 16:48:27 -05:00
with open ( ' input.txt ' ) as f :
input_string = f . read ( ) . split ( ' \n ' )
def twos_comp ( num , length ) :
if num == 0 :
return 0
2024-04-06 18:03:56 -05:00
return abs ( ( num ^ ( ( 1 << length ) - 1 ) ) + 1 )
2024-04-06 16:48:27 -05:00
def logical_shiftr ( num , length , times ) :
2024-04-06 20:32:45 -05:00
#print("SHIFT START___")
#print(bin(num))
2024-04-06 16:48:27 -05:00
for t in range ( times ) :
num = ( num >> 1 ) | ( ( 1 << length ) & num )
2024-04-06 20:32:45 -05:00
#print(bin(num))
#print("SHIFT END___")
2024-04-06 16:48:27 -05:00
return num
def convert_if_twoscomp ( num , length ) :
if num & ( 1 << length - 1 ) :
return ( - 1 * twos_comp ( num , length ) )
return num & ( 1 << length ) - 1
2024-04-06 18:03:56 -05:00
def debug ( results ) :
headers = [ ' multiplicand bin ' , ' multiplier bin ' , ' multiplicand dec ' , ' multiplier dec ' , ' expected bin ' , ' expected dec ' , ' booth if correct ' , ' booth mod if correct ' ]
table = [ ]
for [ multiplicand_bin , multiplier_bin , result_booth , result_booth_mod , length ] in results :
multiplicand = convert_if_twoscomp ( multiplicand_bin , length )
multiplier = convert_if_twoscomp ( multiplier_bin , length )
expected = multiplicand * multiplier
expected_bin = ( twos_comp ( expected , length * 2 ) , expected ) [ expected > 0 ]
success_b = [ bin ( result_booth ) , " PASS " ] [ result_booth == expected_bin ]
success_bm = [ bin ( result_booth_mod ) , " PASS " ] [ result_booth_mod == expected_bin ]
table . append ( [ bin ( multiplicand_bin ) , bin ( multiplier_bin ) , multiplicand , multiplier , bin ( expected_bin ) , expected , success_b , success_bm ] )
2024-04-06 20:32:45 -05:00
print ( " \n CHECKS: \n " , tabulate ( table , headers ) , " \n " )
2024-04-06 16:48:27 -05:00
def booth ( multiplier , multiplicand , length ) :
2024-04-06 20:32:45 -05:00
print ( " \n \n " )
2024-04-06 16:48:27 -05:00
multiplicand_twos_comp = twos_comp ( multiplicand , length )
2024-04-06 20:32:45 -05:00
print ( multiplicand_twos_comp )
2024-04-06 16:48:27 -05:00
result = multiplier << 1 # extended bit
for i in range ( length ) :
op = result & 0b11
if op == 0b01 :
2024-04-06 20:32:45 -05:00
print ( bin ( result ) )
2024-04-06 16:48:27 -05:00
result + = multiplicand << ( length + 1 )
2024-04-06 20:32:45 -05:00
print ( bin ( multiplicand << ( length + 1 ) ) )
2024-04-06 16:48:27 -05:00
if op == 0b10 :
result + = multiplicand_twos_comp << ( length + 1 )
result & = ( 1 << ( length * 2 ) + 1 ) - 1 # get rid of any overflows
result = logical_shiftr ( result , length * 2 , 1 )
result = result >> 1
return result
def booth_mod ( multiplier , multiplicand , length ) :
multiplicand_twos_comp = twos_comp ( multiplicand , length )
result = multiplier << 1 # extended bit
for i in range ( int ( length / 2 ) ) :
2024-04-06 20:32:45 -05:00
print ( " before op " , bin ( result ) )
2024-04-06 16:48:27 -05:00
match result & 0b111 :
case 0b010 | 0b001 : # add
2024-04-06 20:32:45 -05:00
print ( " add " )
2024-04-06 16:48:27 -05:00
result + = multiplicand << ( length + 1 )
case 0b011 : # add * 2
2024-04-06 20:32:45 -05:00
print ( " add x2 " )
2024-04-06 16:48:27 -05:00
result + = multiplicand << ( length + 2 ) # extra shift is multiplying multiplicand by 2
2024-04-06 20:32:45 -05:00
print ( bin ( multiplicand << ( length + 2 ) ) )
print ( bin ( result ) )
2024-04-06 16:48:27 -05:00
case 0b100 : # sub * 2
2024-04-06 20:32:45 -05:00
print ( " sub x2 " )
2024-04-06 16:48:27 -05:00
result + = multiplicand_twos_comp << ( length + 2 )
case 0b101 | 0b110 : # sub
2024-04-06 20:32:45 -05:00
print ( " sub " )
2024-04-06 16:48:27 -05:00
result + = multiplicand_twos_comp << ( length + 1 )
2024-04-06 20:32:45 -05:00
result & = ( 1 << ( ( length * 2 ) + 1 ) ) - 1 # get rid of any overflows
2024-04-06 16:48:27 -05:00
result = logical_shiftr ( result , length * 2 , 2 )
2024-04-06 20:32:45 -05:00
print ( " after op " , bin ( result ) )
2024-04-06 16:48:27 -05:00
result = result >> 1
return result
2024-04-06 18:03:56 -05:00
if __name__ == " __main__ " :
headers = [ ' multiplicand ' , ' multiplier ' , ' result (bin) ' , ' result (hex) ' ]
table = [ ]
debug_results = [ ]
for operation in input_string :
if operation == ' ' or operation [ 0 ] == ' # ' :
continue
length = len ( operation . split ( " " ) [ 0 ] )
multiplicand = int ( operation . split ( " " ) [ 0 ] , 2 )
multiplier = int ( operation . split ( " " ) [ 1 ] , 2 )
result_booth = booth ( multiplier , multiplicand , length )
2024-04-06 20:32:45 -05:00
result_mod_booth = booth_mod ( multiplier , multiplicand , length + 1 )
2024-04-06 18:03:56 -05:00
table . append ( [ bin ( multiplicand ) , bin ( multiplier ) , bin ( result_booth ) , hex ( result_booth ) ] )
debug_results . append ( [ multiplicand , multiplier , result_booth , result_mod_booth , length ] )
debug ( debug_results )
print ( tabulate ( table , headers ) )
2024-04-06 16:48:27 -05:00
2024-04-06 18:03:56 -05:00
#generate table
2024-04-06 16:48:27 -05:00