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)
Example #2
0
    def set_alu_inputs(self):
        """
        Sets the values of the two data inputs into the ALU. alu_input_1 will always be the data read from the first
        register in the register file, and alu_input_2 will either be the data from the second register, or the
        immediate, depending on the value of ALUSrc.
        :return: None
        """
        if len(self.read_data1) != 32:
            raise Exception("(Execute): data from register 1 isn't 32 bits1")

        self.alu_input_1 = decode_signed_binary_number(self.read_data1, 32)  # expecting 32 bit values!

        if self.ALUSrc:
            self.alu_input_2 = decode_signed_binary_number(self.immediate, 32)

        else:
            self.alu_input_2 = decode_signed_binary_number(self.read_data2, 32)
Example #3
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
Example #4
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)
Example #5
0
    def process_memory_request(self):
        if self.MemRead:
            if decode_signed_binary_number(self.alu_result, 32) > 511:
                raise Exception("(Memory): Error! Trying to read data from memory with an invalid address! (%s)",
                                self.alu_result)
            else:
                self.read_data = self.memory[self.alu_result]

        elif self.MemWrite:
            if decode_signed_binary_number(self.alu_result, 32) > 511:
                raise Exception("(Memory): Error! Trying to write data from memory with an invalid address! (%s)",
                                self.alu_result)
            elif len(self.alu_result) != 32:
                raise Exception("(Memory): Error! attemping to write non-32 bit value to memory!")
            else:
                self.memory[self.alu_result] = self.write_data
        elif self.MemtoReg:
            raise Exception("(Memory): Error! MemtoReg is high, but memory isn't being read")
Example #6
0
 def update_program_counter(self, new_address):
     """
     Updates the program counter to the new address
     :param new_address: new value of the program counter (STRING)
     :return:
     """
     if isinstance(new_address, str):
         new_address = decode_signed_binary_number(new_address, 32)
     if new_address % 4 != 0:  # Have to use whole word addressing. Sorry
         raise Exception("Invalid Program Counter Value!")
     else:
         self.program_counter = new_address
Example #7
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.")
Example #8
0
    def process_alu_control(self):
        """
        Method to process the ALU control information and set the corresponding operation for the ALU to perform.
        :return: None
        """
        if self.ALUOp == 0b00:  # LW/SW
            self.operation = 0b0010  # add

        elif self.ALUOp == 0b01:  # branch
            self.operation = 0b0110  # subtract
            if decode_signed_binary_number(self.opcode, 6) == 4:  # branch if equal
                self.branch_equal = True
            elif decode_signed_binary_number(self.opcode, 6) == 5:  # branch if not equal
                self.branch_not_equal = True
            elif decode_signed_binary_number(self.opcode, 6) == 2: # jump
                self.branch_equal = False
                self.branch_not_equal = False
            else:
                raise Exception("(Execute): "
                                "Invalid ALUOp and opcode combination! (branching ALUOp, but opcode != beq or bne")

        elif self.ALUOp == 0b10:  # r-type instruction
            funct_int = decode_signed_binary_number(self.function_code, 6, True)
            if funct_int == 32:  # addition
                self.operation = 0b0010

            elif funct_int == 36:  # logical AND
                self.operation = 0b0000

            elif funct_int == 26:  # division
                self.operation = 0b0011

            elif funct_int == 37:  # logical OR
                self.operation = 0b0001

            elif funct_int == 24:  # multiplication
                self.operation = 0b0100

            elif funct_int == 42:  # set on less than
                self.operation = 0b0111

            elif funct_int == 34:  # subtraction
                self.operation = 0b0110

            elif funct_int == 38:  # exclusive OR
                self.operation = 0b1000
            else:
                raise Exception("(Execute): Invalid ALUOp and function field! "
                                "(Couldn't decode correct ALU function from funct field!)")

        elif self.ALUOp == 0b11:  # immediate function..
            if decode_signed_binary_number(self.opcode, 6, True) == 8:  # ADD Immediate
                self.operation = 0b0010
            elif decode_signed_binary_number(self.opcode, 6, True) == 12:  # AND Immediate
                self.operation = 0b0000
            else:
                raise Exception("(Execute): Error! Invalid immediate function and opcode combination!")

        else:
            raise Exception("(Execute): Invalid ALUOp!")
    def test_receive_values_and_update_add(self):
        execute = Execute()
        expected_result = create_sized_binary_num(
            decode_signed_binary_number(ExecuteStageTest.data1, 32) +
            decode_signed_binary_number(ExecuteStageTest.data2, 32), 32)[:32]

        ALUOp = 0b10
        function_field = '100000'
        opcode = None
        ALUSrc = False
        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)
Example #10
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))
Example #11
0
print(
    "-----------------------------------------------------------------------\n\n"
)

results = python_test_program()

print(
    "-----------------------------------------------------------------------")
print("Test completed, comparing values.\n")

current_reg_memory = interface.retrieve_register_list()
current_data_memory = interface.retrieve_data_memory()

print("-reg-|-Expected--|-----Actual--")
print(" v0  |-----" + str(results[1]) + "-----|-----" + str(
    decode_signed_binary_number(current_reg_memory[decode_asm_register('v0')],
                                32)))
print(" v1  |-----" + str(results[2]) + "--|-----" + str(
    decode_signed_binary_number(current_reg_memory[decode_asm_register('v1')],
                                32)))
print(" s2  |-----" + str(results[3]) + "---|-----" + str(
    decode_signed_binary_number(current_reg_memory[decode_asm_register('s2')],
                                32)))
print(" s3  |-----" + str(results[4]) + "--|-----" + str(
    decode_signed_binary_number(current_reg_memory[decode_asm_register('s3')],
                                32)))
print(" t0  |-----" + str(results[5]) + "---|-----" + str(
    decode_signed_binary_number(current_reg_memory[decode_asm_register('t0')],
                                32)))
print(" a0  |-----" + str(results[6]) + "----|-----" + str(
    decode_signed_binary_number(current_reg_memory[decode_asm_register('a0')],
                                32)))