def test_do_operand_forwarding(self): self.processor.decoder_buffer = DecoderBuffer({'rs': [2, None]}) self.processor.executer_buffer = ExecuterBuffer({'rt': [2, 7]}) self.processor.do_operand_forwarding() self.assertEqual(self.processor.decoder_buffer.rs, [2, 7]) self.processor.decoder_buffer = DecoderBuffer({'rs': [2, None]}) self.processor.executer_buffer = ExecuterBuffer() self.processor.memory_buffer = MemoryBuffer({'rd': [2, 9]}) self.processor.do_operand_forwarding() self.assertEqual(self.processor.decoder_buffer.rs, [2, 9])
def __init__(self, memory, start_address): self.memory = memory self.start_address = start_address self.register_file = RegisterFile() self.data_memory_key_fn = lambda: -777 self.data_memory = defaultdict(self.data_memory_key_fn) self.cycle_count = 0 self.instr_count = 0 self.PC = 0 self.fetch_input_buffer = FetchInputBuffer({ 'PC': self.start_address, 'instr_count': self.instr_count, }) self.fetcher_buffer = FetcherBuffer() self.fetch_stage = FetchStage(self.memory, self.fetch_input_buffer, self.fetcher_buffer) self.decoder_buffer = DecoderBuffer() self.decode_stage = DecodeStage(self.fetcher_buffer, self.decoder_buffer, self.register_file) self.executer_buffer = ExecuterBuffer() self.execute_stage = ExecuteStage(self.decoder_buffer, self.executer_buffer) self.memory_buffer = MemoryBuffer() self.memory_stage = MemoryStage(self.executer_buffer, self.memory_buffer, self.data_memory) self.write_back_stage = WriteBackStage(self.memory_buffer, self.register_file)
def test_execute_I_instruction_BEQ_true(self): self.register_file[2] = 8 self.register_file[5] = 8 self.set_up_execute_stage('I BEQ R2 R5 4') expected_branch_PC = self.decoder_buffer.npc + 4 * 4 self.execute_stage.execute_I_instruction() self.assertFalse(self.execute_stage.is_stalled) self.assertEqual(self.execute_stage.branch_pc, expected_branch_PC) self.assertEqual(self.execute_stage.executer_buffer, ExecuterBuffer()) self.assertEqual(self.execute_stage.decoder_buffer, DecoderBuffer())
def test_execute_I_instruction_LW(self): self.register_file[2] = 8 self.set_up_execute_stage('I LW R2 R5 4') executer_buffer = ExecuterBuffer({ 'instr': self.instr, 'npc': self.decoder_buffer.npc, 'rt': [5, None], 'memaddr': 12, }) self.execute_stage.execute_I_instruction() self.assertFalse(self.execute_stage.is_stalled) self.assertEqual(self.execute_stage.executer_buffer, executer_buffer) self.assertEqual(self.execute_stage.decoder_buffer, DecoderBuffer())
def test_execute_I_instruction_ADDI(self): self.register_file[1] = 3 self.set_up_execute_stage('I ADDI R1 R1 1') executer_buffer = ExecuterBuffer({ 'instr': self.instr, 'npc': self.decoder_buffer.npc, 'rt': [self.instr.rt, self.register_file[1] + 1], }) self.execute_stage.execute_I_instruction() self.assertFalse(self.execute_stage.is_stalled) self.assertEqual(self.execute_stage.executer_buffer, executer_buffer) self.assertEqual(self.execute_stage.decoder_buffer, DecoderBuffer())
def get_stage_output(memory, register_file, pc, instr_count, stage_name): """Return the output buffer of stage given the initial conditions. All the stages before stage_name will be executed. Arguments: - `memory`: - `register_file`: - `pc`: - `stage_name`: TODO: Maybe just take the stages as input later. """ fetch_input_buffer = FetchInputBuffer({ 'PC': pc, 'instr_count': instr_count, }) fetcher_buffer = FetcherBuffer() fetch_stage = FetchStage(memory, fetch_input_buffer, fetcher_buffer) fetch_stage.fetch_instruction() if stage_name == 'fetch': return fetch_stage.fetcher_buffer decode_stage = DecodeStage(fetch_stage.fetcher_buffer, DecoderBuffer(), register_file) decode_stage.decode_instruction() if stage_name == 'decode': return decode_stage.decoder_buffer execute_stage = ExecuteStage(decode_stage.decoder_buffer, ExecuterBuffer()) execute_stage.execute() if stage_name == 'execute': return execute_stage.executer_buffer data_memory_key_fn = lambda: -1 data_memory = defaultdict(data_memory_key_fn) memory_stage = MemoryStage(execute_stage.executer_buffer, MemoryBuffer(), data_memory) memory_stage.do_memory_operation() if stage_name == 'memory': return memory_stage.memory_buffer
def test_execute_R_instruction(self): self.register_file[1] = 3 self.register_file[2] = 7 self.set_up_execute_stage('R ADD R1 R2 R3') executer_buffer = ExecuterBuffer({ 'instr': self.instr, 'npc': self.decoder_buffer.npc, 'rd': [self.instr.rd, self.register_file[1] + self.register_file[2]], }) self.execute_stage.execute_R_instruction() self.assertFalse(self.execute_stage.is_stalled) self.assertEqual(self.execute_stage.executer_buffer, executer_buffer) self.assertEqual(self.execute_stage.decoder_buffer, DecoderBuffer())
def test_execute_I_instruction_BEQ_false(self): self.register_file[2] = 8 self.register_file[5] = 7 self.set_up_execute_stage('I BEQ R2 R5 4') expected_branch_PC = self.decoder_buffer.npc self.execute_stage.executer_buffer = ExecuterBuffer({'foo': 123}) self.execute_stage.execute_I_instruction() self.assertFalse(self.execute_stage.is_stalled) print 'self.decoder_buffer: ', self.decoder_buffer self.assertEqual(self.execute_stage.branch_pc, expected_branch_PC) # NOTE: You need different instances of ExecuterBuffers, else, # just one instance gets modified and the two references will # turn out to be equal. self.assertEqual( self.execute_stage.executer_buffer, ExecuterBuffer({'foo': 123}), "execute_stage shouldn't modify its executer_buffer after a BEQ") self.assertEqual(self.execute_stage.decoder_buffer, DecoderBuffer())
def test_execute_cycles_BEQ_true(self): instruction_list = [ 'I BEQ R2 R5 4', 'R ADD R1 R2 R3', 'R ADD R1 R2 R3', 'R ADD R2 R0 R1', 'R ADD R3 R0 R2', 'J J 3', 'I ADDI R9 R9 999', ] instruction_list = [ instruction_string.split() for instruction_string in instruction_list ] memory = Memory.Memory(instruction_list) processor = Processor.Processor(memory, 0) processor.execute_cycles(3) self.assertEqual(processor.execute_stage.branch_pc, 20) self.assertEqual(processor.fetch_stage.fetch_input_buffer.PC, 20) self.assertEqual(processor.executer_buffer, ExecuterBuffer()) self.assertEqual(processor.decoder_buffer, DecoderBuffer()) self.assertEqual(processor.fetcher_buffer, FetcherBuffer())