def nandmultiply(): '''Generates a NAND program. Outputs the string representation of a NAND program that takes in inputs x_0, ..., x_{127} and multiplies it with C mod 2^n. The output of the NAND program should be stored in variables y_0, ..., y_{127}. The first digit will be the least significant digit (ex: 110001 --> 35). Good luck!''' # creates a blank NAND program with n inputs and n outputs. prog = NANDProgram(PSET_DIM, PSET_DIM) # now add lines to your NAND program by calling python functions like # prog.NAND() or prog.OR() or other helper functions. For an example, take # a look at the stuff after if __name__ == '__main__': or the nand adder # function that we implemented. C_bin = util.int2bin(C, PSET_DIM) prog.ZERO("0") prog.ONE("1") # Need to allocate a variable to store the carry digits from previous # additions. zero_lst = [] for i in range(0, PSET_DIM): zero_lst.append(prog.ZERO("0")) acc_lst = [] for x in range(0, PSET_DIM): output = prog.CREATE(x, C_bin, PSET_DIM) if x == 0: acc_lst = prog.ADDER(zero_lst, output, PSET_DIM - 1) if x != 0: acc_lst = prog.ADDER(acc_lst, output, PSET_DIM - 1) for j in range(0, len(acc_lst)): prog.OR(prog.output_var(j), acc_lst[j], "0") # prog.OR(prog.output_var(PSET_DIM - 1), prog.ZERO("0"), prog.ONE("1")) # "compiles" your completed program as a NAND program string. # print(prog) return str(prog)
def nandsquare(n): '''Takes in an integer n. Outputs the string representation of a NAND prog that takes in inputs x_0, ..., x_{n-1} and squares it mod 2^n. The output will be y_0, ..., y_{n-1}. The first digit will be the least significant digit (ex: 110001 --> 35)''' # creates a blank NAND program with n inputs and n outputs. prog = NANDProgram(n, n) # now add lines to your NAND program by calling python functions like # prog.NAND() or prog.OR() or other helper functions. For an example, take # a look at the stuff after if __name__ == '__main__': # "compiles" your completed program as a NAND program string. return str(prog)
def nandmultiply(): '''Generates a NAND program. Outputs the string representation of a NAND program that takes in inputs x_0, ..., x_{127} and multiplies it with C mod 2^n. The output of the NAND program should be stored in variables y_0, ..., y_{127}. The first digit will be the least significant digit (ex: 110001 --> 35). Good luck!''' # creates a blank NAND program with n inputs and n outputs. prog = NANDProgram(PSET_DIM, PSET_DIM) # now add lines to your NAND program by calling python functions like # prog.NAND() or prog.OR() or other helper functions. For an example, take # a look at the stuff after if __name__ == '__main__': or the nand adder # function that we implemented. # Store C as binary C_bin = format(C, '128b')[::-1] # Store C in binary as C0-C127 for idx in range(len(C_bin)): if C_bin[idx] == "1": prog.ONE("C" + str(idx)) else: prog.ZERO("C" + str(idx)) # Store the 128 lines of multiplication. These only need to be 128 bits long due to the mod for row in range(128): for col in range(128): if row == 0: prog.AND("Y[" + str(col) + "]", "C" + str(row), "X[" + str(col) + "]") else: if col >= row: prog.AND("l" + str(row) + "-" + str(col), "C" + str(row),"X[" + str(col - row) + "]") else: prog.ZERO("l" + str(row) + "-" + str(col)) # Add the 128 lines of multiplication for row in range(1, 128): prog.ZERO("C") for j in range(128): prog.ADD_3("Y[" + str(j) + "]", "C", "C", "Y[" + str(j) + "]", "l" + str(row) + "-" + str(j)) # "compiles" your completed program as a NAND program string. return str(prog)
def nandadder(N): '''Creates a NAND adder that takes in two n-digit binary numbers and gets the sum, returning a n+1-digit binary number. Returns the string repr. of the NAND program created.''' nand = NANDProgram(2 * N, N + 1) nand.ONE("ONE") carry = nand.allocate() nand.ADD_3(nand.output_var(0), carry, nand.input_var(0), nand.input_var(N), nand.NAND("ZERO", "ONE", "ONE")) last_carry = "" for i in range(1, N - 1): last_carry = carry carry = nand.allocate() nand.ADD_3(nand.output_var(i), carry, nand.input_var(i), nand.input_var(N + i), last_carry) nand.ADD_3(nand.output_var(N - 1), nand.output_var(N), nand.input_var(N - 1), nand.input_var(2 * N - 1), carry) return str(nand)
def nandmultiply(): '''Generates a NAND program. Outputs the string representation of a NAND program that takes in inputs x_0, ..., x_{127} and multiplies it with C mod 2^n. The output of the NAND program should be stored in variables y_0, ..., y_{127}. The first digit will be the least significant digit (ex: 110001 --> 35). Good luck!''' # creates a blank NAND program with n inputs and n outputs. prog = NANDProgram(PSET_DIM, PSET_DIM) # now add lines to your NAND program by calling python functions like # prog.NAND() or prog.OR() or other helper functions. For an example, take # a look at the stuff after if __name__ == '__main__': or the nand adder # function that we implemented. C_bin = util.int2bin(C, PSET_DIM) #column_carry = "" #for i in range(0, PSET_DIM): #column_sum = nand.allocate() #for j in range(0, i): #column_value = nand.allocate() #input_index = j #c_index = i - j #nand.AND(column_value, prog.input_var(input_index), C_bin[c_index]) #nand.ADD_3(column_sum, column_sum, column_value, "0") prog.ONE("ONE") prog.ZERO("ZERO") prog.ONE("1") prog.ZERO("0") sum = ["ZERO"] * PSET_DIM for i in range(0, PSET_DIM): row = ["ZERO"] * i for j in range(0, PSET_DIM): elem = prog.allocate() prog.AND(elem, prog.input_var(i), C_bin[j]) row.append(elem) row = row[:PSET_DIM] new_sum = mynandadder(PSET_DIM, prog, sum + row) for i in range(0, PSET_DIM): sum[i] = new_sum[i] for k in range(0, PSET_DIM): prog.OR(prog.output_var(k), "ZERO", sum[k]) print(sum) # "compiles" your completed program as a NAND program string. return str(prog)