Fix this code. It gives the following output whereas it should be adding 1 ten times.

class Control_Signals():
    def __init__(self):
       self.RegDst = 0
       self.RegWrite = 0
       self.ALUsrc = 0
       self.MemWrite = 0
       self.MemRead = 0
       self.MemtoReg = 0
       self.Branch = 0
       self.Jump = 0
       self.ALUOp = "00"  # Add ALUOp for more complex ALU control

class Program_Counter():
    def __init__(self):
        self.count = 0
    
    def __next__(self):
        self.count += 1

    def __jump__(self, jump_address):
        self.count = jump_address

    def next_instruction(self, control_signal, jump_address):
        if control_signal == 0:
            self.__next__()
        else:
            self.__jump__(jump_address)

class Instruction_Memory():
    def __init__(self, machine_code):
        self.instructions = list(machine_code)

    def read_instruction(self, address):
        return self.instructions[address]

class Data_Memory():
    def __init__(self):
        self.data = [0] * 1024

    def data_read(self, address):
        return self.data[address]

    def data_write(self, address, data_val):
        self.data[address] = data_val

class Registers():
    def __init__(self):
        self.registers = [0] * 32

    def read_register(self, reg_num):
        return self.registers[reg_num]

    def write_register(self, reg_num, data):
        if reg_num != 0:  # Prevent writing to $zero
            self.registers[reg_num] = data

class ALU():
    def execute(self, op1, op2, alu_control):
        if alu_control == "add":
            return op1 + op2
        elif alu_control == "sub":
            return op1 - op2
        elif alu_control == "and":
            return op1 & op2
        elif alu_control == "or":
            return op1 | op2
        elif alu_control == "slt":
            return 1 if op1 < op2 else 0

class Processor():
    def __init__(self, instructions):
        self.control_unit = Control_Signals()
        self.program_counter = Program_Counter()
        self.instruction_memory = Instruction_Memory(instructions)
        self.data_memory = Data_Memory()
        self.registers = Registers()
        self.alu = ALU()

    def instruction_fetch(self):
        pc_value = self.program_counter.count
        if pc_value >= len(self.instruction_memory.instructions):
            return None  # No more instructions
        instruction = self.instruction_memory.read_instruction(pc_value)
        return instruction

    def instruction_decode(self, instruction):
        opcode = instruction[:6]
        rs = int(instruction[6:11], 2)
        rt = int(instruction[11:16], 2)
        rd = int(instruction[16:21], 2)
        imm = int(instruction[16:], 2) if instruction[16] == '0' else int(instruction[16:], 2) - (1 << 16)
        
        # Reset control signals
        self.control_unit = Control_Signals()
        
        # Set control signals based on opcode
        if opcode == "000000":  # R-type
            self.control_unit.RegDst = 1
            self.control_unit.RegWrite = 1
            self.control_unit.ALUOp = "10"
        elif opcode == "100011":  # lw
            self.control_unit.ALUsrc = 1
            self.control_unit.MemRead = 1
            self.control_unit.RegWrite = 1
            self.control_unit.MemtoReg = 1
        elif opcode == "101011":  # sw
            self.control_unit.ALUsrc = 1
            self.control_unit.MemWrite = 1
        elif opcode == "000100":  # beq
            self.control_unit.Branch = 1
            self.control_unit.ALUOp = "01"
        elif opcode == "000101":  # bne
            self.control_unit.Branch = 1
            self.control_unit.ALUOp = "01"
        elif opcode == "001000":  # addi
            self.control_unit.ALUsrc = 1
            self.control_unit.RegWrite = 1
        elif opcode == "001010":  # slti
            self.control_unit.ALUsrc = 1
            self.control_unit.RegWrite = 1
            self.control_unit.ALUOp = "11"
        elif opcode == "000010":  # j
            self.control_unit.Jump = 1
        elif opcode == "001101":  # ori
            self.control_unit.ALUsrc = 1
            self.control_unit.RegWrite = 1
            self.control_unit.ALUOp = "11"

        return opcode, rs, rt, rd, imm

    def execution(self, rs_val, rt_val, imm, alu_control):
        if self.control_unit.ALUsrc == 1:
            alu_result = self.alu.execute(rs_val, imm, alu_control)
        else:
            alu_result = self.alu.execute(rs_val, rt_val, alu_control)
        return alu_result

    def memory_access(self, alu_result, rt_val):
        if self.control_unit.MemWrite:
            self.data_memory.data_write(alu_result, rt_val)
        elif self.control_unit.MemRead:
            return self.data_memory.data_read(alu_result)
        return None

    def write_back(self, alu_result, mem_data, rd, rt):
        if self.control_unit.RegWrite:
            write_data = mem_data if self.control_unit.MemtoReg else alu_result
            write_reg = rd if self.control_unit.RegDst else rt
            self.registers.write_register(write_reg, write_data)

    def run(self):
        while True:
            instruction = self.instruction_fetch()
            if instruction is None:
                break  # Stop execution when no more instructions
            
            opcode, rs, rt, rd, imm = self.instruction_decode(instruction)
            rs_val = self.registers.read_register(rs)
            rt_val = self.registers.read_register(rt)
            
            alu_control = "add"  # Default ALU operation
            if self.control_unit.ALUOp == "01":
                alu_control = "sub"
            elif self.control_unit.ALUOp == "11":
                alu_control = "slt" if opcode == "001010" else "or"
            
            alu_result = self.execution(rs_val, rt_val, imm, alu_control)
            mem_data = self.memory_access(alu_result, rt_val)
            self.write_back(alu_result, mem_data, rd, rt)
            
            # Handle branching and jumping
            if self.control_unit.Branch:
                if (opcode == "000100" and alu_result == 0) or (opcode == "000101" and alu_result != 0):
                    self.program_counter.count += imm
                else:
                    self.program_counter.__next__()
            elif self.control_unit.Jump:
                self.program_counter.count = int(instruction[6:], 2)
            else:
                self.program_counter.__next__()
            
            self.debug()
            
    def debug(self):
        print(f"PC: {self.program_counter.count}, Registers: {self.registers.registers}")

# def main():
#     # Example machine code (list of binary instructions as strings)
#     instructions = [
#         # Case 2: Complex Instructions
#         "10001101001010000000000000000100",  # lw $t0, 4($t1)
#         "00010001000010010000000000000010",  # beq $t0, $t1, 2
#         "00000001000010010101000000100010",  # sub $t2, $t0, $t1
#         "00101001001010000000000000000101",  # slti $t0, $t1, 5
#         "00001000000000000000000000010000",  # j 16
#         "00000001000010010101000000100100",  # and $t2, $t0, $t1
#         "00110101001010000000000000000001",  # ori $t0, $t1, 0x0001
#     ]
#     processor = Processor(instructions)
#     processor.run()
#     print(processor.data_memory.data[:20])

# main()

# def main():
#     # Example machine code (list of binary instructions as strings)
#     instructions = [
#         "00100000000010000000000000001010",  # addi $t0, $zero, 10 (Add immediate: $t0 = 0 + 10)
#         "00100000000010010000000000000101",  # addi $t1, $zero, 5  (Add immediate: $t1 = 0 + 5)
#         "00000001000010010101000000100000",  # add $t2, $t0, $t1   (Add: $t2 = $t0 + $t1)
#         "00000001010010010101100000100010",  # sub $t3, $t2, $t1   (Subtract: $t3 = $t2 - $t1)
#     ]
#     processor = Processor(instructions)
#     processor.run()

# main()

def main():
    instructions = [
        "10001100000010000000000000000000",  # lw $t0, 0($zero)   ; Load initial value (0) into $t0
        "10001100000010010000000000000100",  # lw $t1, 4($zero)   ; Load loop counter (10) into $t1
        "10001100000010100000000000001000",  # lw $t2, 8($zero)   ; Load increment value (1) into $t2
        "00000001000010100100000000100000",  # add $t0, $t0, $t2  ; Add 1 to $t0
        "00100001001010011111111111111111",  # addi $t1, $t1, -1  ; Decrement loop counter
        "00010101001000000000000000000010",  # bne $t1, $zero, -2 ; Branch to add instruction if counter != 0
        "10101100000010000000000000000000",  # sw $t0, 0($zero)   ; Store final result back to memory
    ]
    processor = Processor(instructions)
    
    # Initialize memory
    processor.data_memory.data_write(0, 0)  # Initial value
    processor.data_memory.data_write(4, 10)  # Loop counter
    processor.data_memory.data_write(8, 1)  # Increment value
    
    processor.run()
    
    # Print the final result from memory
    print(f"Final result in memory: {processor.data_memory.data_read(0)}")

main()


PS C:\Users\SQREAM\Desktop\semester_five\computer_architecture\lab5> python c.py
PC: 1, Registers: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
PC: 2, Registers: [0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
PC: 3, Registers: [0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
PC: 4, Registers: [0, 0, 0, 0, 0, 0, 0, 0, 1, 10, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
PC: 5, Registers: [0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
PC: 7, Registers: [0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Final result in memory: 0