Exemplo n.º 1
0
 def step(self):
     instr_addr = self.pc.get()
     instr_word = self.memory.get(instr_addr)
     instr = decode(instr_word)
     # Display the CPU state when we have decoded the instruction,
     # before we have executed it
     self.notify_all(CPUStep(self, instr_addr, instr_word, instr))
     compare = (instr.cond.value & self.condition.value)
     if compare > 0:
         left = self.registers[instr.reg_src1].get()
         right = self.registers[instr.reg_src2].get() + instr.offset
         resulting, cond_in = self.alu.exec(instr.op, left, right)
         self.pc.put(self.pc.get() + 1)
         if instr.op is OpCode.STORE:
             self.memory.put(resulting,
                             self.registers[instr.reg_target].get())
         elif instr.op is OpCode.LOAD:
             self.registers[instr.reg_target].put(
                 self.memory.get(resulting))
         elif instr.op is OpCode.HALT:
             self.halted = True
         else:
             self.registers[instr.reg_target].put(resulting)
             self.condition = cond_in
     else:
         self.pc.put(self.pc.get() + 1)
Exemplo n.º 2
0
 def test_encode_decode(self):
     """Binary encoding and decoding of an instruction"""
     instr = instr_format.instruction_from_string(
         "  ADD ALWAYS pc r3 r5 -12")
     as_word = instr.encode()
     as_instr = instr_format.decode(as_word)
     self.assertEqual(instr, as_instr)
Exemplo n.º 3
0
    def step(self):
        """Carries out one fetch/decode/execute cycle."""
        instr_addr = self.pc.get()
        instr_word = self.memory.get(instr_addr)
        # Decode
        instr = decode(instr_word)
        # Display the CPU state when we have decoded the instruction,
        # before we have executed it
        self.notify_all(CPUStep(self, instr_addr, instr_word, instr))

        result = self.condition & instr.cond
        if result != CondFlag.NEVER:
            left_operand = self.registers[instr.reg_src1].get()
            right_operand = instr.offset + self.registers[instr.reg_src2].get()
            self.pc.put(self.pc.get() + 1)
            result, cond_flag = self.alu.exec(instr.op, left_operand, right_operand)

            if instr.op == OpCode.STORE:
                self.memory.put(result, self.registers[instr.reg_target].get())

            elif instr.op == OpCode.LOAD:
                self.registers[instr.reg_target].put(self.memory.get(result))

            elif instr.op == OpCode.HALT:
                self.halted = True

            else:
                self.registers[instr.reg_target].put(result)
                self.condition = cond_flag
        else:
            self.pc.put(self.pc.get() + 1)
Exemplo n.º 4
0
    def step(self):
        log.debug("Step at PC={}".format(self.pc.get()))

        # Fetch
        instr_addr = self.pc.get()
        instr_word = self.memory.get(instr_addr)

        # Decode
        instr = decode(instr_word)
        log.debug("Instruction: {}".format(instr))
        # Display the CPU state when we have decoded the instruction,
        # before we have executed it
        self.notify_all(CPUStep(self, instr_addr, instr_word, instr))

        # Execute
        predicate = instr.cond
        if (self.cc & predicate) != CondFlag.NEVER:

            log.debug("Predicate passed")
            opcode = instr.op
            target = self.registers[instr.reg_target]
            left = self.registers[instr.reg_src1].get()
            right = self.registers[instr.reg_src2].get() + instr.offset
            # Step program counter after forming operands but before
            # storing execution result
            self.pc.put(self.pc.get() + 1)
            # Now a store into PC will overwrite the stepped value
            result, cc = self.alu.exec(opcode, left, right)
            self.cc = cc
            # Load and store are special
            if opcode == OpCode.LOAD:
                log.debug(
                    "Loading value from memory address {} to register {}".
                    format(result, instr.reg_target))
                memval = self.memory.get(result)
                target.put(memval)
            elif opcode == OpCode.STORE:
                log.debug("Storing register {} into memory address {}".format(
                    instr.reg_target, result))
                self.memory.put(result, target.get())
            elif opcode == OpCode.HALT:
                self.halted = True
            else:
                target.put(result)
        else:
            # The program counter still moves forward, with no
            # other computation
            log.debug("Predicated instruction will not execute")
            self.pc.put(self.pc.get() + 1)
Exemplo n.º 5
0
    def step(self) -> None:
        '''Fetches instructions in memory. Decodes instruction word. Determines if
        instruction should be executed or skipped. Executes if applicable.
        '''
        #fetch
        address = self.program_pointer.get()
        instruction_word = self.memory.get(address)

        #decode
        decoded_word = decode(instruction_word)

        self.notify_all(CPUStep(self, address, instruction_word, decoded_word))

        #execute
        predicate = self.cond_flag & decoded_word.cond

        if predicate:
            # get values for source registers
            val1 = self.registers[decoded_word.reg_src1].get()
            val2 = self.registers[decoded_word.reg_src2].get()

            # add offset to register
            val2 = val2 + decoded_word.offset

            #increment program counter
            self.program_pointer.put(self.program_pointer.get() + 1)

            #sending op code to ALU to execute with 2 values
            result, self.cond_flag = self.alu.exec(decoded_word.op, val1, val2)

            if decoded_word.op == OpCode.HALT:
                self.halted = True

            #load
            elif decoded_word.op == OpCode.LOAD:
                self.registers[decoded_word.reg_target].put(
                    self.memory.get(result))

            #store
            elif decoded_word.op == OpCode.STORE:
                self.memory.put(result,
                                self.registers[decoded_word.reg_target].get())

            else:
                self.registers[decoded_word.reg_target].put(result)
        else:
            self.program_pointer.put(self.program_pointer.get() + 1)
Exemplo n.º 6
0
def execute(words: List[int]):
    """In place of a full CPU model, execute the ALU on a
    sequence of instructions encoded as integers.
    """
    # We don't have the Register objects yet, so ...
    regs = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    alu = ALU()
    for word in words:
        log.debug("Decoding instruction word {}".format(word))
        instr = instr_format.decode(word)
        log.debug("Decoded to {}".format(instr))
        op = instr.op
        to_reg = instr.reg_target
        src_1 = instr.reg_src1
        src_2 = instr.reg_src2
        offset = instr.offset
        log.info("Executing {}".format(instr))
        result, condition = alu.exec(op, regs[src_1], regs[src_2] + offset)
        regs[to_reg] = result
        log.info("Computed value {}".format(result))
Exemplo n.º 7
0
 def step(self):
     instr_addr = self.registers[15].get()
     instr_word = self.memory.get(instr_addr)
     instr = decode(instr_word)
     # Display the CPU state when we have decoded the instruction,
     # before we have executed it
     self.notify_all(CPUStep(self, instr_addr, instr_word, instr))
     if instr.cond & self.condition:
         x = self.registers[instr.reg_src1].get()
         y = instr.offset + self.registers[instr.reg_src2].get()
         self.pc.put(self.pc.get() + 1)
         result, self.condition = self.alu.exec(instr.op, x, y)
         if instr.op == OpCode.STORE:  # If the operation was STORE
             self.memory.put(result, self.registers[instr.reg_target].get())
         elif instr.op == OpCode.LOAD:  # If operation was LOAD/GET
             target = self.memory.get(result)
             self.registers[instr.reg_target].put(target)
         elif instr.op == OpCode.HALT:  # If operation was HALT
             self.halted = True
         else:  # If operation was ADD/SUB/MUL/DIV
             self.registers[instr.reg_target].put(result)
     else:
         self.pc.put(self.pc.get() + 1)