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)
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)
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)
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)
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)
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))
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)