예제 #1
0
    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)
예제 #4
0
 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
예제 #5
0
    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)
예제 #6
0
    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])
예제 #7
0
 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)
예제 #8
0
    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)])
예제 #9
0
    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')])
예제 #10
0
    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')])
예제 #11
0
    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')])
예제 #12
0
 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.")
예제 #13
0
 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)
예제 #14
0
    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)
예제 #16
0
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]
예제 #17
0
    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)
예제 #18
0
 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
예제 #19
0
    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())
예제 #20
0
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)
예제 #21
0
 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))
예제 #22
0
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')])
예제 #23
0
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:
예제 #24
0
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)