def test_branch_decision_expect_false(self): this_data_mem = MemoryStageTest.data_memory.copy() mem = Memory(this_data_mem, WriteBack()) branch = True alu_branch = False MemWrite = False MemRead = False MemtoReg = False jump = False pc = create_sized_binary_num(8, 32) ja = create_sized_binary_num(0, 32) alu_output = create_sized_binary_num(16, 32) branch_addr = create_sized_binary_num(4, 32) write_data = None mem.receive_control_information(branch, alu_branch, MemWrite, MemRead, MemtoReg, jump) with self.assertRaises(Exception) as cm: mem.receive_data(pc, ja, alu_output, branch_addr, write_data) self.assertTrue("(WriteBack): Error! No stages to write data back to." in str(cm.exception)) self.assertEqual(pc, mem.pc_address)
def test_branch_if_not_equal_true(self): execute = Execute() alu_branch_output = True branch_address = create_sized_binary_num( ExecuteStageTest.pc_value + (decode_signed_binary_number(ExecuteStageTest.immediate, 32) << 2), 32)[:32] ALUOp = 0b01 function_field = create_sized_binary_num(4, 6) opcode = '000101' ALUSrc = False MemWrite = False MemtoReg = False MemRead = False Branch = True jump = False jump_address = None execute.receive_data(ExecuteStageTest.data1, ExecuteStageTest.data2, ExecuteStageTest.immediate, ExecuteStageTest.pc_value, jump_address) execute.receive_control_information(ALUOp, function_field, opcode, ALUSrc, MemWrite, MemtoReg, MemRead, Branch, jump) self.assertEqual(alu_branch_output, execute.alu_branch) self.assertEqual(branch_address, execute.branch_address)
def test_receive_values_and_update_addi(self): execute = Execute() expected_result = create_sized_binary_num( decode_signed_binary_number(ExecuteStageTest.data1, 32) + decode_signed_binary_number(ExecuteStageTest.immediate, 32), 32)[:32] ALUOp = 0b11 function_field = '100000' opcode = create_sized_binary_num(8, 6) ALUSrc = True MemWrite = False MemtoReg = False MemRead = False Branch = False jump = False jump_address = None execute.receive_data(ExecuteStageTest.data1, ExecuteStageTest.data2, ExecuteStageTest.immediate, ExecuteStageTest.pc_value, jump_address) execute.receive_control_information(ALUOp, function_field, opcode, ALUSrc, MemWrite, MemtoReg, MemRead, Branch, jump) self.assertEqual(expected_result, execute.alu_output)
def calculate_jump_address(self): """ This happens in the decode stage, and is done by shifting the bottom 26 bits of the instruction (address) left 2 and then concatenating the top four bits of the program counter to this to create a 32 bit address to go to :return: None """ address = create_sized_binary_num(decode_signed_binary_number((self.instruction.binary_version()[6:]), 26) << 2, 28) # shift bottom 26 bits left by two self.jump_address = create_sized_binary_num(self._program_counter_value, 32)[0:4] + address # May not be right maths
def test_send_jump_address(self): wb = WriteBack() jump = True MemtoReg = False jump_address = create_sized_binary_num(23, 32) pc_address = create_sized_binary_num(48, 32) mem_data = create_sized_binary_num(64, 32) alu_data = create_sized_binary_num(128, 32) wb.receive_control_information(jump, MemtoReg, True) with self.assertRaises(Exception) as cm: wb.receive_data(jump_address, pc_address, mem_data, alu_data) self.assertTrue("(WriteBack): Error! No stages to write data back to." in str(cm.exception)) self.assertEqual(jump_address, wb.new_pc_address)
def test_execute_add_instruction(self): this_register_file = list(PipelineInterfaceTest.register_file) starting_address = 0 this_register_file[10] = create_sized_binary_num( 12, 32) # put something in register $t2 this_register_file[11] = create_sized_binary_num( 18, 32) # put something in register $t3 interface = PipelineInterface(PipelineInterfaceTest.Instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual(create_sized_binary_num(30, 32), interface.retrieve_register_list()[9])
def sign_extend_immediate_field(self): """ Sign extend the immediate field from 16 bits to 32 bits :return: """ if self.instruction.immediate: self.sign_extended_immediate = create_sized_binary_num( decode_signed_binary_number(self.instruction.immediate, 16), 32)
def test_execute_sw(self): # sw $t6, $a0, 0 (0 is the offset amount) this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[10:] this_memory_file = PipelineInterfaceTest.data_memory.copy() this_register_file[decode_asm_register( 'a0')] = create_sized_binary_num(4, 32) this_register_file[decode_asm_register( 't6')] = create_sized_binary_num(1995, 32) interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, this_memory_file) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(1995, 32), interface.retrieve_data_memory()[create_sized_binary_num(4, 32)])
def test_execute_slt_not_set(self): # slt $t1, $t0, $t4 this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[6:] this_memory_file = PipelineInterfaceTest.data_memory.copy() this_register_file[decode_asm_register( 't0')] = create_sized_binary_num(22, 32) this_register_file[decode_asm_register( 't4')] = create_sized_binary_num(4, 32) interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, this_memory_file) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(0, 32), interface.retrieve_register_list()[decode_asm_register('t1')])
def test_execute_sub(self): this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[4:] this_register_file[decode_asm_register( 'a1')] = create_sized_binary_num( 24, 32) # put something in register $t2 this_register_file[decode_asm_register( 't8')] = create_sized_binary_num( 18, 32) # put something in register $t3 interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(24 - 18, 32), interface.retrieve_register_list()[decode_asm_register('a1')])
def test_execute_mult(self): # mult $s2, $s1, $t3 this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[12:] this_register_file[decode_asm_register( 's1')] = create_sized_binary_num( 54, 32) # put something in register $t2 this_register_file[decode_asm_register( 't3')] = create_sized_binary_num( 2000, 32) # put something in register $t3 interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(54 * 2000, 32), interface.retrieve_register_list()[decode_asm_register('s2')])
def calculate_branch_address(self): """ Calculate the address the branch would take if we do branch :return: None """ if self.immediate: self.branch_address = create_sized_binary_num(self._program_counter_value + (decode_signed_binary_number(self.immediate, 32) << 2), 32) if len(self.branch_address) > 32: self.branch_address = self.branch_address[:32] elif self.branch_equal or self.branch_not_equal: raise Exception("(Execute): Attempted to branch without a value in the immediate field.")
def test_control_andi(self): control = Control() control.update(create_sized_binary_num(12, 6)) self.assertEqual(False, control.RegDst) self.assertEqual(True, control.ALUSrc) self.assertEqual(False, control.MemtoReg) self.assertEqual(True, control.RegWrite) self.assertEqual(False, control.MemRead) self.assertEqual(False, control.MemWrite) self.assertEqual(False, control.Branch) self.assertEqual(0b11, control.ALUOp) self.assertEqual(False, control.jump)
def test_execute_addi_instruction_2(self): this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[2:] interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(257, 32), interface.retrieve_register_list()[decode_asm_register('t4')])
def test_slt_set(self): execute = Execute() expected_result = create_sized_binary_num(1, 32)[:32] ALUOp = 0b10 function_field = create_sized_binary_num(42, 6) opcode = None ALUSrc = False MemWrite = False MemtoReg = False MemRead = False Branch = False jump = False jump_address = None execute.receive_data(ExecuteStageTest.data2, ExecuteStageTest.data1, ExecuteStageTest.immediate, ExecuteStageTest.pc_value, jump_address) execute.receive_control_information(ALUOp, function_field, opcode, ALUSrc, MemWrite, MemtoReg, MemRead, Branch, jump) self.assertEqual(expected_result, execute.alu_output)
def python_test_program(): """ Implements the test program that was provided in Python to view expected results. :return: array of values calculated. """ v0 = 0x0040 v1 = 0x1010 s2 = 0x000F s3 = 0x00F0 t0 = 0x0000 a0 = 0x0010 a1 = 0x0005 data_mem = {16: 0x0101, 20: 0x0110, 24: 0x0011, 28: 0x00F0, 32: 0x00FF} while a1 > 0: a1 = a1 - 1 t0 = data_mem[a0] if t0 > 0x0100: v0 = int(v0 / 8) v1 = v1 | v0 data_mem[a0] = create_sized_binary_num(0x7F00, 32) else: s2 = s2 * 4 s3 = s3 ^ s2 data_mem[a0] = create_sized_binary_num(0x00FF, 32) a0 = a0 + 4 """ print("data mem: ", data_mem) print("v0: ", v0) print("v1: ", v1) print("s2: ", s2) print("s3: ", s3) print("t0: ", t0) print("a0: ", a0) print("a1: ", a1) """ return [data_mem, v0, v1, s2, s3, t0, a0, a1]
def execute_alu_operation(self): """ Perform the specified ALU Operation and set alu_output, alu_branch accordingly :return: None """ if self.operation == 0b0000: # AND self.alu_output = self.alu_input_1 & self.alu_input_2 elif self.operation == 0b0001: # OR self.alu_output = self.alu_input_1 | self.alu_input_2 elif self.operation == 0b0010: # ADD self.alu_output = self.alu_input_1 + self.alu_input_2 elif self.operation == 0b0011: # DIV self.alu_output = self.alu_input_1 / self.alu_input_2 elif self.operation == 0b0100: # MULT self.alu_output = self.alu_input_1 * self.alu_input_2 elif self.operation == 0b0110: # SUB self.alu_output = self.alu_input_1 - self.alu_input_2 if self.branch_not_equal: if self.alu_output == 0: self.alu_branch = False else: self.alu_branch = True elif self.branch_equal: if self.alu_output == 0: self.alu_branch = True else: self.alu_branch = False elif self.operation == 0b0111: # set on less than if self.alu_input_1 < self.alu_input_2: # TODO: Is this necessary? self.alu_output = 1 else: self.alu_output = 0 elif self.operation == 0b1000: # XOR self.alu_output = self.alu_input_1 ^ self.alu_input_2 elif self.operation == 0b1100: # NOR self.alu_output = not (self.alu_input_1 | self.alu_input_2) # This probably actually doesn't work else: raise Exception("(Execute): Unsupported ALU operation!") # convert output to 32-bit binary number self.alu_output = create_sized_binary_num(self.alu_output, 32)
def __init__(self, register_file, next_stage=None): """ Initialized to none because this wouldn't be populated until the Fetch stage had fetched an instruction and sent it to the decode stage :param register_file: list representing the values in all of the registers. SHOULD BE 32 BIT VALUES """ self.instruction = None self.register_file = register_file self.register_file[0] = create_sized_binary_num(0, 32) self.read_reg_1 = None self.read_reg_2 = None self.write_register = None self.sign_extended_immediate = None self._control = Control() self.next_stage = next_stage self._program_counter_value = None self.jump_address = None
def test_execute_beq_do_branch(self): this_register_file = list(PipelineInterfaceTest.register_file) this_register_file[decode_asm_register( 'a1')] = create_sized_binary_num(0, 32) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[3:] interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() expected_address = int( PipelineInterfaceTest.var_exit ) * 4 + 4 # branch addresses are multiplied by 4 and relative to pc + 4 self.assertEqual(expected_address, interface.retrieve_current_pc_address())
class DecodeStageTest(unittest.TestCase): register_file = [create_sized_binary_num(65535, 32) for i in range(0, 32)] # empty register files def test_create_decode(self): decode = Decode(self.register_file) self.assertEqual(None, decode.read_reg_1) self.assertEqual(None, decode.read_reg_2) self.assertEqual(None, decode.write_register) def test_receive_instruction(self): decode = Decode(self.register_file) decode.receive_instruction(Instruction('Add', "$t1", "$t2", "t3"), 8) self.assertEqual("01001", decode.write_register) self.assertEqual("01010", decode.read_reg_1) self.assertEqual("01011", decode.read_reg_2) def test_write_to_write_reg(self): decode = Decode(self.register_file) decode.receive_instruction(Instruction('Add', "$t1", "$t2", "t3"), 8) decode.write_to_register("Test data.") self.assertEqual("Test data.", decode.register_file[9]) def test_correct_values_in_register_file(self): decode = Decode(self.register_file) decode.receive_instruction(Instruction('add', '$t1', '$t2', '$t3'), 8) for value in decode.register_file[1:]: self.assertEqual('00000000000000001111111111111111', value) def test_extend_immediate(self): decode = Decode(self.register_file) decode.receive_instruction(Instruction('addi', '$t8', '$zero', '1'), 8) self.assertEqual("00000000000000000000000000000001", decode.sign_extended_immediate) def test_extend_immediate_neg(self): decode = Decode(self.register_file) decode.receive_instruction(Instruction('addi', '$t8', '$zero', '-10'), 8) self.assertEqual("11111111111111111111111111110110", decode.sign_extended_immediate) def test_calculate_jump_address(self): decode = Decode(self.register_file) decode.receive_instruction(Instruction('j', '320'), 8) self.assertEqual("00000000000000000000010100000000", decode.jump_address)
def test_signed_binary_conversion(self): num1 = create_sized_binary_num(-12, 8) num2 = create_sized_binary_num(-24, 8) num3 = create_sized_binary_num(-1, 8) num4 = create_sized_binary_num(0, 8) num5 = create_sized_binary_num(-2, 8) num6 = create_sized_binary_num(4, 8) self.assertEqual('11110100', num1) self.assertEqual('11101000', num2) self.assertEqual('11111111', num3) self.assertEqual('00000000', num4) self.assertEqual('11111110', num5) self.assertEqual('00000100', num6) self.assertEqual(-12, decode_signed_binary_number(num1, 8)) self.assertEqual(-24, decode_signed_binary_number(num2, 8)) self.assertEqual(-1, decode_signed_binary_number(num3, 8)) self.assertEqual(0, decode_signed_binary_number(num4, 8)) self.assertEqual(-2, decode_signed_binary_number(num5, 8)) self.assertEqual(4, decode_signed_binary_number(num6, 8))
class PipelineInterfaceTest(unittest.TestCase): var_exit = '5' var_else = '7' var_end = '10' starting_address = 0 Instruction_list = [ Instruction('Add', "$t1", "$t2", "t3"), Instruction('addi', '$t8', '$zero', '1'), Instruction('addi', '$t4', '$zero', '257'), Instruction('beq', '$a1', '$zero', var_exit), Instruction('sub', '$a1', '$a1', '$t8'), Instruction('lw', '$t0', '$a0', '0'), Instruction('slt', '$t1', '$t0', '$t4'), Instruction('bne', '$t0', '$zero', var_else), Instruction('div', '$v0', '$v0', '$t7'), Instruction('or', '$s1', '$s1', '$v0'), Instruction('sw', '$t6', '$a0', '0'), Instruction('j', var_end), Instruction('mult', '$s2', '$s1', '$t3'), Instruction('xor', '$s3', '$s3', '$s2') ] register_file = [create_sized_binary_num(65535, 32) for i in range(0, 32)] # empty register files data_memory_addresses = [ create_sized_binary_num(i, 32) for i in range(0, 512) ] data_memory = {} for i in data_memory_addresses: data_memory[i] = create_sized_binary_num(0, 32) def test_execute_add_instruction(self): this_register_file = list(PipelineInterfaceTest.register_file) starting_address = 0 this_register_file[10] = create_sized_binary_num( 12, 32) # put something in register $t2 this_register_file[11] = create_sized_binary_num( 18, 32) # put something in register $t3 interface = PipelineInterface(PipelineInterfaceTest.Instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual(create_sized_binary_num(30, 32), interface.retrieve_register_list()[9]) def test_execute_addi_instruction(self): this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[1:] interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(1, 32), interface.retrieve_register_list()[decode_asm_register('t8')]) def test_execute_addi_instruction_2(self): this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[2:] interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(257, 32), interface.retrieve_register_list()[decode_asm_register('t4')]) def test_execute_beq_do_branch(self): this_register_file = list(PipelineInterfaceTest.register_file) this_register_file[decode_asm_register( 'a1')] = create_sized_binary_num(0, 32) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[3:] interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() expected_address = int( PipelineInterfaceTest.var_exit ) * 4 + 4 # branch addresses are multiplied by 4 and relative to pc + 4 self.assertEqual(expected_address, interface.retrieve_current_pc_address()) def test_execute_beq_not_taken(self): this_register_file = list(PipelineInterfaceTest.register_file) this_register_file[decode_asm_register( 'a1')] = create_sized_binary_num(20, 32) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[3:] interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() expected_address = int( PipelineInterfaceTest.starting_address ) + 4 # branch addresses are multiplied by 4 and relative to pc + 4 self.assertEqual(expected_address, interface.retrieve_current_pc_address()) def test_execute_sub(self): this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[4:] this_register_file[decode_asm_register( 'a1')] = create_sized_binary_num( 24, 32) # put something in register $t2 this_register_file[decode_asm_register( 't8')] = create_sized_binary_num( 18, 32) # put something in register $t3 interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(24 - 18, 32), interface.retrieve_register_list()[decode_asm_register('a1')]) def test_execute_lw(self): # lw $t0, $a0, 0 (0 is the offset amount) this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[5:] this_memory_file = PipelineInterfaceTest.data_memory.copy() this_memory_file[create_sized_binary_num( 4, 32)] = create_sized_binary_num(1995, 32) this_register_file[decode_asm_register( 'a0')] = create_sized_binary_num(4, 32) interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, this_memory_file) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(1995, 32), interface.retrieve_register_list()[decode_asm_register('t0')]) def test_execute_slt_is_set(self): # slt $t1, $t0, $t4 this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[6:] this_memory_file = PipelineInterfaceTest.data_memory.copy() this_register_file[decode_asm_register( 't0')] = create_sized_binary_num(4, 32) this_register_file[decode_asm_register( 't4')] = create_sized_binary_num(22, 32) interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, this_memory_file) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(1, 32), interface.retrieve_register_list()[decode_asm_register('t1')]) def test_execute_slt_not_set(self): # slt $t1, $t0, $t4 this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[6:] this_memory_file = PipelineInterfaceTest.data_memory.copy() this_register_file[decode_asm_register( 't0')] = create_sized_binary_num(22, 32) this_register_file[decode_asm_register( 't4')] = create_sized_binary_num(4, 32) interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, this_memory_file) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(0, 32), interface.retrieve_register_list()[decode_asm_register('t1')]) def test_execute_bne_no_branch(self): # bne $t0, $zero, var_else where var_else is an address this_register_file = list(PipelineInterfaceTest.register_file) this_register_file[decode_asm_register( 't0')] = create_sized_binary_num(0, 32) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[7:] interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() expected_address = int( PipelineInterfaceTest.starting_address ) + 4 # branch addresses are multiplied by 4 and relative to pc + 4 self.assertEqual(expected_address, interface.retrieve_current_pc_address()) def test_execute_bne_do_branch(self): # bne $t0, $zero, var_else where var_else is an address this_register_file = list(PipelineInterfaceTest.register_file) this_register_file[decode_asm_register( 't0')] = create_sized_binary_num(1984, 32) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[7:] interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() expected_address = int( PipelineInterfaceTest.var_else ) * 4 + 4 # branch addresses are multiplied by 4 and relative to pc + 4 self.assertEqual(expected_address, interface.retrieve_current_pc_address()) def test_execute_div(self): # div $v0, $v0, $t7 this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[8:] this_register_file[decode_asm_register( 'v0')] = create_sized_binary_num( 24, 32) # put something in register $t2 this_register_file[decode_asm_register( 't7')] = create_sized_binary_num( 18, 32) # put something in register $t3 interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(24 / 18, 32), interface.retrieve_register_list()[decode_asm_register('v0')]) def test_execute_or(self): # or $s1, $s1, $v0 this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[9:] this_register_file[decode_asm_register( 's1')] = create_sized_binary_num( 2000, 32) # put something in register $t2 this_register_file[decode_asm_register( 'v0')] = create_sized_binary_num( 2017, 32) # put something in register $t3 interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(2000 | 2017, 32), interface.retrieve_register_list()[decode_asm_register('s1')]) def test_execute_sw(self): # sw $t6, $a0, 0 (0 is the offset amount) this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[10:] this_memory_file = PipelineInterfaceTest.data_memory.copy() this_register_file[decode_asm_register( 'a0')] = create_sized_binary_num(4, 32) this_register_file[decode_asm_register( 't6')] = create_sized_binary_num(1995, 32) interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, this_memory_file) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(1995, 32), interface.retrieve_data_memory()[create_sized_binary_num(4, 32)]) def test_execute_j(self): # j var_end, where var_end is the address to jump to this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[11:] this_memory_file = PipelineInterfaceTest.data_memory.copy() interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, this_memory_file) expected_address = int(PipelineInterfaceTest.var_end) * 4 interface.trigger_clock_cycle() self.assertEqual(expected_address, interface.retrieve_current_pc_address()) def test_execute_mult(self): # mult $s2, $s1, $t3 this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[12:] this_register_file[decode_asm_register( 's1')] = create_sized_binary_num( 54, 32) # put something in register $t2 this_register_file[decode_asm_register( 't3')] = create_sized_binary_num( 2000, 32) # put something in register $t3 interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(54 * 2000, 32), interface.retrieve_register_list()[decode_asm_register('s2')]) def test_execute_xor(self): # xor $s3, $s3, $s2 this_register_file = list(PipelineInterfaceTest.register_file) this_instruction_list = list( PipelineInterfaceTest.Instruction_list)[13:] this_register_file[decode_asm_register( 's3')] = create_sized_binary_num( 24, 32) # put something in register $t2 this_register_file[decode_asm_register( 's2')] = create_sized_binary_num( 18, 32) # put something in register $t3 interface = PipelineInterface(this_instruction_list, PipelineInterfaceTest.starting_address, this_register_file, PipelineInterfaceTest.data_memory) interface.trigger_clock_cycle() self.assertEqual( create_sized_binary_num(24 ^ 18, 32), interface.retrieve_register_list()[decode_asm_register('s3')])
from Instruction import Instruction, create_sized_binary_num, decode_signed_binary_number, decode_asm_register from time import sleep print( "This program will execute the provided test program for my Pipeline Simulator." ) print( "Currently, the pipeline is single-cycle, with no hazard detection, forwaring, or pipelining" ) print("Created by Trey Franklin") print( "-----------------------------------------------------------------------") sleep(2) print("Creating register file..") register_file = [create_sized_binary_num(0, 32) for i in range(0, 32)] # initialize all registers to zero register_file[decode_asm_register('v0')] = create_sized_binary_num(0x0040, 32) register_file[decode_asm_register('v1')] = create_sized_binary_num(0x1010, 32) register_file[decode_asm_register('s2')] = create_sized_binary_num(0x000F, 32) register_file[decode_asm_register('s3')] = create_sized_binary_num(0x00F0, 32) register_file[decode_asm_register('t0')] = create_sized_binary_num(0x0000, 32) register_file[decode_asm_register('a0')] = create_sized_binary_num(0x0010, 32) register_file[decode_asm_register('a1')] = create_sized_binary_num(0x0005, 32) print("Creating data memory..") data_memory_addresses = [ create_sized_binary_num(i, 32) for i in range(0, 512, 4) ] # word addressing (increment by 4) data_memory = {} for i in data_memory_addresses:
class MemoryStageTest(unittest.TestCase): data_memory_addresses = [ create_sized_binary_num(i, 32) for i in range(0, 512) ] data_memory = {} for i in data_memory_addresses: data_memory[i] = create_sized_binary_num(0, 32) def test_create_memory(self): mem = Memory(MemoryStageTest.data_memory, WriteBack()) self.assertEqual(MemoryStageTest.data_memory, mem.memory) def test_read_memory(self): this_data_mem = MemoryStageTest.data_memory.copy() this_data_mem[create_sized_binary_num(16, 32)] = create_sized_binary_num( 22, 32) mem = Memory(this_data_mem, WriteBack()) branch = False alu_branch = False MemWrite = False MemRead = True MemtoReg = True jump = False pc = create_sized_binary_num(8, 32) ja = create_sized_binary_num(0, 32) alu_output = create_sized_binary_num(16, 32) branch_addr = create_sized_binary_num(4, 32) write_data = None mem.receive_control_information(branch, alu_branch, MemWrite, MemRead, MemtoReg, jump) with self.assertRaises(Exception) as cm: mem.receive_data(pc, ja, alu_output, branch_addr, write_data) self.assertTrue("(WriteBack): Error! No stages to write data back to." in str(cm.exception)) self.assertEqual(create_sized_binary_num(22, 32), mem.read_data) def test_write_memory(self): this_data_mem = MemoryStageTest.data_memory.copy() mem = Memory(this_data_mem, WriteBack()) branch = False alu_branch = False MemWrite = True MemRead = False MemtoReg = False jump = False pc = create_sized_binary_num(8, 32) ja = create_sized_binary_num(0, 32) alu_output = create_sized_binary_num(16, 32) branch_addr = create_sized_binary_num(4, 32) write_data = create_sized_binary_num(31, 32) mem.receive_control_information(branch, alu_branch, MemWrite, MemRead, MemtoReg, jump) with self.assertRaises(Exception) as cm: mem.receive_data(pc, ja, alu_output, branch_addr, write_data) self.assertTrue("(WriteBack): Error! No stages to write data back to." in str(cm.exception)) self.assertEqual(create_sized_binary_num(31, 32), mem.memory[alu_output]) def test_branch_decision_expect_false(self): this_data_mem = MemoryStageTest.data_memory.copy() mem = Memory(this_data_mem, WriteBack()) branch = True alu_branch = False MemWrite = False MemRead = False MemtoReg = False jump = False pc = create_sized_binary_num(8, 32) ja = create_sized_binary_num(0, 32) alu_output = create_sized_binary_num(16, 32) branch_addr = create_sized_binary_num(4, 32) write_data = None mem.receive_control_information(branch, alu_branch, MemWrite, MemRead, MemtoReg, jump) with self.assertRaises(Exception) as cm: mem.receive_data(pc, ja, alu_output, branch_addr, write_data) self.assertTrue("(WriteBack): Error! No stages to write data back to." in str(cm.exception)) self.assertEqual(pc, mem.pc_address) def test_branch_decision_expect_true(self): this_data_mem = MemoryStageTest.data_memory.copy() mem = Memory(this_data_mem, WriteBack()) branch = True alu_branch = True MemWrite = False MemRead = False MemtoReg = False jump = False pc = create_sized_binary_num(8, 32) ja = create_sized_binary_num(0, 32) alu_output = create_sized_binary_num(16, 32) branch_addr = create_sized_binary_num(4, 32) write_data = None mem.receive_control_information(branch, alu_branch, MemWrite, MemRead, MemtoReg, jump) with self.assertRaises(Exception) as cm: mem.receive_data(pc, ja, alu_output, branch_addr, write_data) self.assertTrue("(WriteBack): Error! No stages to write data back to." in str(cm.exception)) self.assertEqual(branch_addr, mem.pc_address) def test_jump_address(self): this_data_mem = MemoryStageTest.data_memory.copy() mem = Memory(this_data_mem, WriteBack()) branch = True alu_branch = False MemWrite = False MemRead = False MemtoReg = False jump = False pc = create_sized_binary_num(8, 32) ja = create_sized_binary_num(0, 32) alu_output = create_sized_binary_num(16, 32) branch_addr = create_sized_binary_num(4, 32) write_data = None mem.receive_control_information(branch, alu_branch, MemWrite, MemRead, MemtoReg, jump) with self.assertRaises(Exception) as cm: mem.receive_data(pc, ja, alu_output, branch_addr, write_data) self.assertTrue("(WriteBack): Error! No stages to write data back to." in str(cm.exception)) self.assertEqual(ja, mem.jump_address)