//removes the instruction from the in reservation station //returns true if a removal occurred and was successful //returns false otherwise bool removeFromRS(instruction_t *instr){ if(!instr){ return false; } if(USES_INT_FU(instr->op) || instr->op == 0){ int i; for(i = 0; i < RESERV_INT_SIZE; i++){ if(instr == reservINT[i]){ reservINT[i] = NULL; return true; } } } else if(USES_FP_FU(instr->op)){ int i; for(i = 0; i < RESERV_FP_SIZE; i++){ if(instr == reservFP[i]){ reservFP[i] = NULL; return true; } } } return false; }
bool removeFromFU(instruction_t *instr){ if(!instr){ return false; } if(USES_INT_FU(instr->op) || instr->op == 0){ int i; for(i = 0; i < FU_INT_SIZE; i++){ if(instr == fuINT[i]){ fuINT[i] = NULL; return true; } } } else if(USES_FP_FU(instr->op)){ int i; for(i = 0; i < FU_FP_SIZE; i++){ if(instr == fuFP[i]){ fuFP[i] = NULL; return true; } } } return false; }
bool set_fu_available(enum md_opcode op, instruction_t* insn) { int i; if (USES_INT_FU(op)) { for (i = 0; i < FU_INT_SIZE; i++) { if (fuINT[i] == NULL) { fuINT[i] = insn; return true; } } } else if (USES_FP_FU(op)) { for (i = 0; i < FU_FP_SIZE; i++) { if (fuFP[i] == NULL) { fuFP[i] = insn; return true; } } } return false; }
insn_struct* set_rs_available(enum md_opcode op, instruction_t* insn) { if (USES_INT_FU(op)) { /* if head pointer */ if (reservINT == NULL) { reservINT = (insn_struct*)malloc(sizeof(insn_struct)); reservINT->insn = insn; reservINT->is_ready = false; reservINT->has_fu= false; reservINT->next = NULL; return reservINT; } else { return add(reservINT, insn); } } else if (USES_FP_FU(op)) { if (reservFP == NULL) { reservFP = (insn_struct*)malloc(sizeof(insn_struct)); reservFP->insn = insn; reservFP->is_ready = false; reservFP->has_fu = false; reservFP->next = NULL; return reservFP; } else { return add(reservFP, insn); } } return NULL; }
/* * Description: * Calls fetch and dispatches an instruction at the same cycle (if possible) * Inputs: * trace: instruction trace with all the instructions executed * current_cycle: the cycle we are at * Returns: * None */ void fetch_To_dispatch(instruction_trace_t* trace, int current_cycle) { /* ECE552: YOUR CODE GOES HERE */ /* ECE552 Assignment 3 - BEGIN CODE */ if(instr_queue_size < INSTR_QUEUE_SIZE && fetch_index <= sim_num_insn){ instruction_t *currInstr = get_instr(trace, fetch_index); while(currInstr && (IS_TRAP(currInstr->op))){ fetch_index++; currInstr = get_instr(trace, fetch_index); } if(currInstr){ currInstr->tom_dispatch_cycle = current_cycle; fetch(trace); } } //Resolve target and source operand dependence //Set map table of r_out to tag which reservation //station will produce the result if(instr_front() && USES_FP_FU(instr_front()->op)){ int i; for(i = 0; i < RESERV_FP_SIZE; i++){ if(!reservFP[i]){ reservFP[i] = instr_front(); //Make sure we mark the existing raw dependences //BEFORE updating the map table with my target regs markRAWDependence(reservFP[i]); updateMapTable(reservFP[i]); instr_pop(); break; } } } else if(instr_front() && (USES_INT_FU(instr_front()->op) || instr_front()->op == 0)){ int i; for(i = 0; i < RESERV_INT_SIZE; i++){ if(!reservINT[i]){ reservINT[i] = instr_front(); markRAWDependence(reservINT[i]); updateMapTable(reservINT[i]); instr_pop(); break; } } } else if(instr_front() && (IS_COND_CTRL(instr_front()->op) || IS_UNCOND_CTRL(instr_front()->op))) { instr_pop(); } return; /* ECE552 Assignment 3 - END CODE */ }
bool is_rs_available(enum md_opcode op) { if (USES_INT_FU(op)) { return !check_if_list_full(reservINT, RESERV_INT_SIZE); } else if (USES_FP_FU(op)) { return !check_if_list_full(reservFP, RESERV_FP_SIZE); } return false; }
/* * Description: * Moves instruction(s) from the dispatch stage to the issue stage * Inputs: * current_cycle: the cycle we are at * Returns: * None */ void dispatch_To_issue(int current_cycle) { /* ECE552 Assignment 4 - BEGIN CODE */ instruction_t* head = instr_queue[0]; if (head != NULL && head->tom_dispatch_cycle < current_cycle && head->tom_issue_cycle == 0) { if (IS_COND_CTRL(head->op) || IS_UNCOND_CTRL(head->op)) { head = NULL; remove_head(); /* decrement the instr_queue_size as first instruction is dispatched*/ instr_queue_size = instr_queue_size - 1; } else if (USES_INT_FU(head->op) || USES_FP_FU(head->op)) { /* check if there is a reservation station available */ if (!is_rs_available(head->op)) { return; } insn_struct* temp = set_rs_available(head->op, head); temp->insn->tom_issue_cycle = current_cycle; set_dependent_insn(temp); /* Set the r_out mapping in the maptable */ int i; for (i =0; i < 2; i++) { if (head->r_out[i] != DNA) { map_table[head->r_out[i]] = head; } } temp = NULL; head = NULL; remove_head(); instr_queue_size = instr_queue_size - 1; } } /* ECE552 Assignment 4 - END CODE */ }
/* * Description: * Moves instruction(s) from the dispatch stage to the issue stage * Inputs: * current_cycle: the cycle we are at * Returns: * None */ void dispatch_To_issue(int current_cycle) { /* ECE552: YOUR CODE GOES HERE */ if (instr_queue[0] == NULL) { return; } instruction_t* insn = instr_queue[0]; if (IS_UNCOND_CTRL(insn->op) || IS_COND_CTRL(insn->op)) { dequeue(); return; } instruction_t** rs; int free_idx = -1; int rs_size; if (USES_INT_FU(insn->op)) { rs = reservINT; rs_size = RESERV_INT_SIZE; } else if (USES_FP_FU(insn->op)) { rs = reservFP; rs_size = RESERV_FP_SIZE; } else { assert(false); } int i; for (i = 0; i < rs_size; i++) { if (rs[i] == NULL) { free_idx = i; } } if (free_idx == -1) { return; } rs[free_idx] = insn; insn->tom_issue_cycle = current_cycle; dequeue(); // Check dependencies on the map table. int rin; for (i = 0; i < 3; i++) { rin = insn->r_in[i]; if (rin < 0 || rin == DNA) { continue; } assert(rin < MD_TOTAL_REGS); if (map_table[rin] != NULL) { insn->Q[i] = map_table[rin]; } } // Update the dependencies on the map table. int rout; for (i = 0; i < 2; i++) { rout = insn->r_out[i]; if (rout < 0 || rout == DNA) { continue; } assert(rout < MD_TOTAL_REGS); map_table[rout] = insn; } assert(rs[free_idx] == insn); }