def fu_exe(fu, fu_results, ROB, time_fu, cycle, PC, Flags): if not len(fu) == 0: for element in fu: element.cycle += 1 # write starting cycle if fu[-1].cycle == 1: index = find_ROB_entry(ROB, fu[-1].dest_tag) ROB[index].exe.append(cycle) # finish cycle if fu[0].cycle == time_fu: index = find_ROB_entry(ROB, fu[0].dest_tag) ROB[index].exe.append(cycle) # calculation result fu_results.append(fu_result()) fu_results[-1].dest_tag = fu[0].dest_tag if (fu[0].op in ['Bne']): fu_results.pop() if fu[0].value1 == fu[0].value2: PC.PC += 1 PC.valid = 1 else: index = find_ROB_entry(ROB, fu[0].dest_tag) offset = ROB[index].dest_tag PC.PC = int(PC.PC + 1 + offset / 4) PC.valid = 1 else: fu_results[-1].value = ExecuteOperation( fu[0].op, fu[0].value1, fu[0].value2, Flags) # remove from fu fu.popleft()
def fu_exe(fu, fu_results, ROB, time_fu, cycle, PC): if len(fu) != 0: for element in fu: element.cycle += 1 # write starting cycle if fu[-1].cycle == 1: index = find_ROB_entry(ROB, fu[-1].dest_tag) ROB[index].exe.append(cycle) # finish cycle if fu[0].cycle == time_fu: index = find_ROB_entry(ROB, fu[0].dest_tag) ROB[index].exe.append(cycle) # calculation result fu_results.append(fu_result()) fu_results[-1].dest_tag = fu[0].dest_tag if (fu[0].op == 'Add') | (fu[0].op == 'Add.d') | (fu[0].op == 'Addi'): fu_results[-1].value = fu[0].value1 + fu[0].value2 elif (fu[0].op == 'Sub') | (fu[0].op == 'Sub.d'): fu_results[-1].value = fu[0].value1 - fu[0].value2 elif (fu[0].op == 'Mult.d'): fu_results[-1].value = fu[0].value1 * fu[0].value2 elif (fu[0].op == 'Bne'): fu_results.pop() if fu[0].value1 == fu[0].value2: PC.PC += 1 PC.valid = 1 else: index = find_ROB_entry(ROB, fu[0].dest_tag) offset = ROB[index].dest_tag PC.PC = int(PC.PC + 1 + offset / 4) PC.valid = 1 else: pass # remove from fu fu.popleft()
def mem(ld_sd_queue, ld_sd_mem, time_ld_sd_mem, results_buffer, memory, ROB, cycle): '''look forward check for all Ld instructions''' index = -1 remove_list = [] for element in ld_sd_queue: index += 1 if (index >= 1) & (element.op == 'Ld') & (element.ready == 1): data = forward_check_from_sd(ld_sd_queue, index) if len(data) > 0: # Ld gets data results_buffer.append(fu_result()) results_buffer[-1].value = data[0] results_buffer[-1].dest_tag = element.dest_tag # remove the Ld instruction remove_list.append(element) # write mem cylce in ROB index = find_ROB_entry(ROB, element.dest_tag) ROB[index].mem.append(cycle) # remove lookforwared Ld for element in remove_list: ld_sd_queue.remove(element) '''ld_sd_mem execution''' if ld_sd_mem.busy == 1: # write mem starting cycle if ld_sd_mem.cycle == 0: index = find_ROB_entry(ROB, ld_sd_mem.dest_tag) ROB[index].mem.extend([cycle, cycle + time_ld_sd_mem - 1]) # for Sd, write commit cycle if ld_sd_mem.op == 'Sd': ROB[index].commit.append(cycle) # cycle ++ ld_sd_mem.cycle += 1 # get the data for Ld or reach the memory for Sd if ld_sd_mem.cycle == time_ld_sd_mem: ld_sd_mem.busy = 0 if ld_sd_mem.op == 'Ld': # put Ld data into results_buffer address = ld_sd_mem.address data = memory[address] results_buffer.append(fu_result()) results_buffer[-1].value = data results_buffer[-1].dest_tag = ld_sd_mem.dest_tag # put data into memory for Sd else: memory[ld_sd_mem.address] = ld_sd_mem.data '''fetch new instruction into ld_sd_mem''' if (ld_sd_mem.busy == 0) & (len(ld_sd_queue) > 0): # flag_1st_ldsd flag_1st_ldsd_sent = False # fetch the ld_sd_queue header if it's Sd, ready and to be committed if (ld_sd_queue[0].op == 'Sd'): # check if this Sd is ready and to be commited if (ld_sd_queue[0].ready == 1): # check to be committed in next cycle if (check_if_sd_committable(ld_sd_queue, ROB)): # already have data in Sd if (type(ld_sd_queue[0].data) == int) | (type( ld_sd_queue[0].data) == float): # put the Sd entry into ld_sd_mem entry = ld_sd_queue.popleft() put_entry_into_ld_sd_mem(ld_sd_mem, entry) flag_1st_ldsd_sent = True ld_sd_mem.busy = 1 # if the 1st Sd is not sent to ld_sd_mem, or the 1st is not Sd if (flag_1st_ldsd_sent == False): for index in range(len(ld_sd_queue)): # ready Ld if (ld_sd_queue[index].op == 'Ld') & (ld_sd_queue[index].ready == 1): # haven't got data if (type(ld_sd_queue[0].data) != int) & (type( ld_sd_queue[0].data) != float): # all previous Sd instructions are ready but no address match if check_all_previous_Sd_no_match(ld_sd_queue, index): put_entry_into_ld_sd_mem(ld_sd_mem, ld_sd_queue[index]) ld_sd_queue.remove(ld_sd_queue[index]) ld_sd_mem.busy = 1 break