⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 project2.c

📁 computer Achitecture tomasulo simulator
💻 C
📖 第 1 页 / 共 3 页
字号:
  int i;   for( i=0; i < NUMUNITS; i++ ) {    if( statePtr->reservation[i].Qj == statePtr->reorderBuf[reorderNum].storeAddress )  {                statePtr->reservation[i].Vj = result;      statePtr->reservation[i].Qj = -1;    }    if( statePtr->reservation[i].Qk == statePtr->reorderBuf[reorderNum].storeAddress )  {      statePtr->reservation[i].Vk = result;      statePtr->reservation[i].Qk = -1;    }      }    // BEQ should not be in here because branch takes 1 cycle to execute, in orther words branch does not execute in parallel  }voidissueInstr(instr, unit, statePtr, reorderNum)     int instr;     int unit;     machineState *statePtr;     int reorderNum;{    /*   * Fill in the reservation station and reorder buffer   * for the instruction being issued.   * Be sure to put safe values in all fields.  Initialize   * unused Qj, Qk fields to -1.   * Check register result data structure to decide whether   * to put values into Vj, Vk or set Qj, Qk.   * CHANGE here:  For ADDI, ANDI and LW instructions, set Rk=1 and Vk=0.   * For SW, put the base register of the memory address   * into Vj if the value is available.   * For BEQZ and J, save the currentPC+1 in the Vk field.   * CHANGE here:  Update result register data structure with the number   * of the reorder buffer that contains the instruction that will update   * the register when it commits   */    // unit(0-11):  LOAD1, LOAD2, LOAD3, STORE1, STORE2, STORE3, ADD1, ADD2, ADD3, MULT1, MULT2, MULT3  statePtr->reservation[unit].busy = 1;                          //this reservation unit is busy  statePtr->reservation[unit].instr = instr;  statePtr->reservation[unit].Qj = -1;                           //initialize it to -1  statePtr->reservation[unit].Qk = -1;  statePtr->reservation[unit].Vj = -1;  statePtr->reservation[unit].Vk = -1;  statePtr->reservation[unit].reorderNum = reorderNum;           //this reservation unit links to reorderBuff[reorderNum]    statePtr->reorderBuf[reorderNum].busy = 1;                     //reorderBuf unit is busy  statePtr->reorderBuf[reorderNum].instr = instr;  statePtr->reorderBuf[reorderNum].execUnit = unit;  statePtr->reorderBuf[reorderNum].instrStatus = ISSUING;  statePtr->reorderBuf[reorderNum].valid = -1;  statePtr->reorderBuf[reorderNum].result = -1;  statePtr->reorderBuf[reorderNum].storeAddress = -1;  /*   #define MULTEXEC             4   #define BRANCHEXEC	        1   #define LDEXEC		1   #define STEXEC		1  */  if( opcode(instr) == LW ) {                                    //Issue LW    statePtr->reorderBuf[reorderNum].storeAddress = field_rb(instr);    if( statePtr->regResult[field_ra(instr)].valid != 1 ) {      //Data Hazard: RegA is not available      statePtr->reservation[unit].Vj = -1;                       //address is not available at the time      statePtr->reservation[unit].Qj = field_ra(instr);       statePtr->reservation[unit].Vk = -1;      statePtr->reservation[unit].Qk = -1;      statePtr->reservation[unit].exTimeLeft = LDEXEC;                  statePtr->regResult[field_rb(instr)].valid = 0;                      //result is not final      statePtr->regResult[field_rb(instr)].unit = unit;                    //name of reservation station that holds the value of this instr    }    else {                 statePtr->reservation[unit].Vj = statePtr->regResult[field_ra(instr)].result;          //RegA is available      statePtr->reservation[unit].Qj = -1;      statePtr->reservation[unit].Vk = -1;      statePtr->reservation[unit].Qk = -1;      statePtr->reservation[unit].exTimeLeft = LDEXEC;      statePtr->regResult[field_rb(instr)].valid = 0;                      //result is not final      statePtr->regResult[field_rb(instr)].unit = unit;                   //name of reservation station that holds the value of this instr    }  }    else if( opcode(instr) == SW ) {                                     //Issue SW        if( statePtr->regResult[field_ra(instr)].valid != 1 ) {      //Data Hazard: RegA is not available      statePtr->reservation[unit].Vj = -1;                       //address is not available at the time      statePtr->reservation[unit].Qj = field_ra(instr);       statePtr->reservation[unit].Vk = -1;      statePtr->reservation[unit].Qk = -1;      statePtr->reservation[unit].exTimeLeft = -1;            statePtr->regResult[field_rb(instr)].valid = 0;                      //result is not final      statePtr->regResult[field_rb(instr)].unit = unit;     }    else {                       statePtr->reservation[unit].Vj = statePtr->regResult[field_ra(instr)].result;          //RegA is available      statePtr->reservation[unit].Qj = -1;      statePtr->reservation[unit].Vk = -1;      statePtr->reservation[unit].Qk = -1;      statePtr->reservation[unit].exTimeLeft = LDEXEC;            statePtr->regResult[field_rb(instr)].valid = 0;                      //result is not final      statePtr->regResult[field_rb(instr)].unit = unit;                   //name of reservation station that holds the value of this instr    }  }  else if( opcode(instr) == BEQ ) {    if( statePtr->regResult[field_ra(instr)].valid != 1 ) {      //RegA is not available       statePtr->reservation[unit].Qj = field_ra(instr);      statePtr->reservation[unit].Vj = -1;    }    else {                                                       //RegA is available      statePtr->reservation[unit].Vj = statePtr->regResult[field_ra(instr)].result;                 statePtr->reservation[unit].Qj = -1;    }    if( statePtr->regResult[field_rb(instr)].valid != 1 ) {      //RegB is not available      statePtr->reservation[unit].Qk = field_rb(instr);      statePtr->reservation[unit].Vk = -1;    }    else {                                                       //RegB is available      statePtr->reservation[unit].Vk = statePtr->regResult[field_rb(instr)].result;      statePtr->reservation[unit].Qk = -1;    }        statePtr->reservation[unit].exTimeLeft = BRANCHEXEC;  }                                                                 // ADD, NAND or MULT Rservation unit  else if( opcode(instr) == ADD || opcode(instr) == NAND ||opcode(instr) == MULT) {     statePtr->reorderBuf[reorderNum].storeAddress = destReg(instr);    if( statePtr->regResult[field_ra(instr)].valid != 1 )  {     //Data Hazard: RegA is waiting result from other instr      statePtr->reservation[unit].Qj = field_ra(instr);      statePtr->reservation[unit].Vj = -1;            statePtr->regResult[destReg(instr)].valid = 0;                      //result is not final      statePtr->regResult[destReg(instr)].unit  = unit;                   //name of reservation station that holds the value of this instr    }    else {                 statePtr->reservation[unit].Vj = statePtr->regResult[field_ra(instr)].result;          //RegA is available        statePtr->reservation[unit].Qj = -1;      statePtr->regResult[destReg(instr)].valid = 0;                      //result is not final      statePtr->regResult[destReg(instr)].unit  = unit;                   //name of reservation station that holds the value of this instr    }    if( statePtr->regResult[field_rb(instr)].valid != 1 )  {     //Data Hazard: RegB is waiting result from other instr      statePtr->reservation[unit].Qk = field_rb(instr);      statePtr->reservation[unit].Vk = -1;      statePtr->regResult[destReg(instr)].valid = 0;                      //result is not final      statePtr->regResult[destReg(instr)].unit =  unit;                   //name of reservation station that holds the value of this instr    }    else {                                                                //RegB is available      statePtr->reservation[unit].Vk = statePtr->regResult[field_rb(instr)].result;      statePtr->reservation[unit].Qk = -1;      statePtr->regResult[destReg(instr)].valid = 0;                      //result is not final      statePtr->regResult[destReg(instr)].unit  = unit;                   //name of reservation station that holds the value of this instr    }    if( opcode(instr) == MULT )      statePtr->reservation[unit].exTimeLeft = MULTEXEC;    else      statePtr->reservation[unit].exTimeLeft = 1;  }}int checkReservation(statePtr, instr)     machineState *statePtr;     int instr;{  int i;  int empty;  empty = 0;  if( opcode(instr) == LW ) {    for(i=0; i< 3; i++) {      if(statePtr->reservation[i].busy == 0) { 	return i;	break;      }      else return -1;    }  }  else if( opcode(instr) == SW ) {    for(i=3; i< 6; i++) {      if(statePtr->reservation[i].busy == 0) {       	return i;	break;      }      else return -1;    }  }  else if( opcode(instr) == ADD ) {    for(i=6; i< 9; i++) {      if(statePtr->reservation[i].busy == 0) {       	return i;	break;      }      else return -1;    }  }    else if( opcode(instr) == NAND ) {   for(i=6; i< 9; i++) {      if(statePtr->reservation[i].busy == 0) {       	return i;	break;      }      else return -1;    }  }    else if( instr == MULT ) {    for(i=9; i< 12; i++) {      if(statePtr->reservation[i].busy == 0) {       	return i;	break;      }      else return -1;    }  }  else if( instr == HALT ) {    return 12;	      }  else if( opcode(instr) == BEQ) {    for(i=0; i<12; i++) {      if(statePtr->reservation[i].busy == 0)	empty = empty +1;    }    if (empty == 12)      return 0;    else return -1;  }  else    return -1;}intcheckReorder(statePtr, instr)     machineState *statePtr;     int instr;{  /*   * Checks reorder buffer to see if there are any free   * entries.  If so, returns the reorder buffer number   * of the entry at the tail of the queue.   *   * Remember that we implement the reorder   * buffer as a circular queue with RBSIZE entries.     * We add new instructions to the tail of the queue   * and commit instructions from the head of the queue.   * When a head or tail pointer advances from the last   * entry in the array that represents the queue, it   * rotates to the first entry in the array.   */  int i;  int j;  int count;  for( i = 0; i < RBSIZE; i++) {    if( statePtr->reorderBuf[i].busy == 1 )      count++;  }  if ( count >= RBSIZE )    return -1;                                      //return -1 if its full  else {    for( i = 0; i <NUMUNITS+1 ; i++ ) {      if( statePtr->reservation[i].busy == 1 )	statePtr->reservation[i].reorderNum = statePtr->reservation[i].reorderNum - 1;       }        int notbusy;    for( i = 0 ; i < 5; i++ ) {      if ( statePtr->reorderBuf[i].busy == 0 ) {        // find an entry that is not busy 	notbusy = i;      }    }              for( j =notbusy; j < RBSIZE-1; j++ ) {               // shift every items in the queue left to empty a spot at the tail end of the queue      statePtr->reorderBuf[j].busy = statePtr->reorderBuf[j+1].busy;      statePtr->reorderBuf[j].instr = statePtr->reorderBuf[j+1].instr;       statePtr->reorderBuf[j].execUnit = statePtr->reorderBuf[j+1].execUnit;       statePtr->reorderBuf[j].instrStatus = statePtr->reorderBuf[j+1].instrStatus;       statePtr->reorderBuf[j].valid = statePtr->reorderBuf[j+1].valid;       statePtr->reorderBuf[j].result = statePtr->reorderBuf[j+1].result;       statePtr->reorderBuf[j].storeAddress = statePtr->reorderBuf[j+1].storeAddress; 	      }    statePtr->reorderBuf[4].busy = 0;    statePtr->reorderBuf[4].instr = -1;    statePtr->reorderBuf[j].execUnit = -1;    statePtr->reorderBuf[j].instrStatus = -1;    statePtr->reorderBuf[j].valid = -1;    statePtr->reorderBuf[j].result = -1;    statePtr->reorderBuf[j].storeAddress = -1;            return 4;                                    //return head of the queue if it's not empty, not full  }}// must check to make sure Vj and Vk are available to do this!!!int getResult(rStation, statePtr)     resStation rStation;     machineState *statePtr;{  int op, immed, function, address, offset;  /*   * This function calculates the results for any instructions   * that produce output.     */  /* Caution: Vj, Vk, immd all available at this point */  op = opcode(rStation.instr);  immed = field_imm(rStation.instr);  offset = immed;  switch (op){  case ADD:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -