예제 #1
0
파일: tomasulo.c 프로젝트: vonZuben/ece552
//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;
}
예제 #2
0
파일: tomasulo.c 프로젝트: vonZuben/ece552
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
파일: tomasulo.c 프로젝트: vonZuben/ece552
/* 
 * 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 */

}
예제 #6
0
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;
}
예제 #7
0
/* 
 * 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 */
}
예제 #8
0
/* 
 * 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);

}