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

📄 project2.c

📁 computer Achitecture tomasulo simulator
💻 C
📖 第 1 页 / 共 3 页
字号:
    return (rStation.Vj + rStation.Vk);    break;    case NAND:    return (!(rStation.Vj & rStation.Vk));    break;  case MULT:    return (rStation.Vj * rStation.Vk);  case LW:    return (rStation.Vj + offset);        //!!! CAUTION: getResult only returns an address of the LW, SW instr    break;  case SW:    return (rStation.Vj + offset);    break;  case BEQ:    return (statePtr->pc +1 +offset);            break;  default:    break;  }}main(int argc, char *argv[])     {    FILE *filePtr;    int pc, done, instr, i;    char line[MAXLINELENGTH];    machineState *statePtr;    int memorySize;    int success, newBuf, op, halt, unit;    int headRB, tailRB;    int regA, regB, immed, address;    int flush;    int rbnum;    if (argc != 2) {      printf("error: usage: %s <machine-code file>\n", argv[0]);      exit(1);    }    filePtr = fopen(argv[1], "r");    if (filePtr == NULL) {      printf("error: can't open file %s", argv[1]);      perror("fopen");      exit(1);    }    /*     * Initialization, reading in program, etc.     *     */    /*     * Allocate machine state.     */    statePtr = (machineState *) malloc(sizeof(machineState));    /*      * Read in the entire machine-code file into memory     */    for (i=0; i<MEMSIZE; i++){      statePtr->memory[i] = 0;    }    pc = 0;    done = 0;    while (!done){      if (fgets(line, MAXLINELENGTH, filePtr) == NULL){	done = 1;      } else {	if (sscanf(line, "%d", &instr) != 1) {	    printf("error in reading address %d\n", pc);	    exit(1);	} 	statePtr->memory[pc] = instr;	statePtr->issue[pc] = -1;	statePtr->rs[pc] = -1;	statePtr->rega[pc] = -1;	statePtr->regb[pc] = -1;	statePtr->exe[pc] = -1;	statePtr->write[pc] = -1;	printInstruction(instr);	pc = pc + 1;      }    }    memorySize = pc;         /*     * Initialize state by giving state pc = 0, regFile[0:7] = 0, reservation.[0-11] = 0,       */    for (i=0; i<NUMREGS; i++){      statePtr->regFile[i] = 0;    }    for (i=0; i<NUMUNITS+1; i++){                /* reservation[0-11] = 0 */      statePtr->reservation[i].busy = 0;      statePtr->reservation[i].instr = -1;      statePtr->reservation[i].Vj = -1;      statePtr->reservation[i].Vk = -1;      statePtr->reservation[i].Qj = -1;      statePtr->reservation[i].Qk = -1;      statePtr->reservation[i].exTimeLeft = -1;      statePtr->reservation[i].reorderNum = -1;          }    for (i=0; i<RBSIZE; i++){                  /* reorderBuf[0-4].busy = 0, headRB = tailRB = -1; */      statePtr->reorderBuf[i].busy = 0;      statePtr->reorderBuf[i].instrStatus = -1;      statePtr->reorderBuf[i].instr = -1;      statePtr->reorderBuf[i].execUnit = -1;      statePtr->reorderBuf[i].valid = -1;      statePtr->reorderBuf[i].result = -1;      statePtr->reorderBuf[i].storeAddress = -1;    }    for (i=0; i<NUMREGS; i++){                 /* all regResult[0:8] are valid  */      statePtr->regResult[i].valid = 1;      statePtr->regResult[i].result = statePtr->regFile[i];    }        statePtr->pc = 0;    statePtr->cycles = 0;        /************ Process instructions ***************/        while (statePtr->cycles < 33) {      printState(statePtr, memorySize);                    /*	 * Decide whether to flush or commit instruction	 * at head of reorder buffer queue.	 * Check whether instruction at head queue can commit.	 * If not, flush reorder buffer, reservation stations	 * and register result status data structures.	 * Our default way of dealing with branches and jumps is	 * to predict not taken;  if our prediction was wrong,	 * we flush everything.  newPC = branch or jump target	 * If no flush, change state here:  	 * On a register access, change regFile	 * On a store, change memory	 * When done with flush or commit, don't forget to free up	 * the reorder buffer and update the head pointer for the queue.	       		 * Done with commit.  	 * Check all instructions in reservation stations.	 * Perform required actions for the following states:	 * For Writing Result State:	 * Be sure to update waiting reservation stations and	 * to put the result in temporary storage in the reorder buffer	 * At this point, free up the reservation station.	 * Change status to committing.	 */      for( i=0; i <RBSIZE; i++ ) {    	if( statePtr->reorderBuf[i].instrStatus == WRITINGRESULT ) { 	  if(opcode(statePtr->reorderBuf[i].instr) == HALT) {	    printf("machine halted after %d\n", statePtr->cycles);	    exit(0);	  }	  if(opcode(statePtr->reorderBuf[i].instr) == ADD || opcode(statePtr->reorderBuf[i].instr) == NAND || opcode(statePtr->reorderBuf[i].instr) == MULT) {	    	    statePtr->regResult[statePtr->reorderBuf[i].storeAddress].result = statePtr->reorderBuf[i].result;  	    statePtr->regFile[statePtr->reorderBuf[i].storeAddress] =  statePtr->regResult[statePtr->reorderBuf[i].storeAddress].result;	    statePtr->regResult[statePtr->reorderBuf[i].storeAddress].valid = 1;	    updateRes(i, statePtr, statePtr->reorderBuf[i].result);                                  //update all waitting reservation station 	   	  }		  if(opcode(statePtr->reorderBuf[i].instr) == LW ) {	    	    statePtr->regResult[statePtr->reorderBuf[i].storeAddress].result = statePtr->reorderBuf[i].result; 	    statePtr->regFile[statePtr->reorderBuf[i].storeAddress] =  statePtr->regResult[statePtr->reorderBuf[i].storeAddress].result;	    statePtr->regResult[statePtr->reorderBuf[i].storeAddress].valid = 1;	   	    updateRes(i, statePtr, statePtr->reorderBuf[i].result); 	   	    	  }	  if(opcode(statePtr->reorderBuf[i].instr) == SW ) {	  	    statePtr->memory[statePtr->reorderBuf[i].storeAddress] = statePtr->reorderBuf[i].result;	   	  }	  if(opcode(statePtr->reorderBuf[i].instr) == BEQ ) {	    	    	  }	    statePtr->reservation[statePtr->reorderBuf[i].execUnit].busy = 0;                                              //empty reservation station	    statePtr->reservation[statePtr->reorderBuf[i].execUnit].Vj = -1;	    statePtr->reservation[statePtr->reorderBuf[i].execUnit].Qj = -1;	    statePtr->reservation[statePtr->reorderBuf[i].execUnit].Vk = -1;	    statePtr->reservation[statePtr->reorderBuf[i].execUnit].Qk = -1;	    statePtr->reservation[statePtr->reorderBuf[i].execUnit].reorderNum = -1;	    statePtr->reorderBuf[i].busy = 0;	}      }	/*	 * For Executing State:	 * Decrement execution time.	 * When execution complete, change state to writingresult	 */      for( i=0; i <RBSIZE; i++ ) {		if( statePtr->reorderBuf[i].instrStatus == EXECUTING ) {	  	  if (opcode(statePtr->reorderBuf[i].instr) == NOOP || opcode(statePtr->reorderBuf[i].instr) == HALT )	    statePtr->reorderBuf[i].instrStatus = WRITINGRESULT;	  	  else {	    statePtr->reservation[statePtr->reorderBuf[i].execUnit].exTimeLeft = statePtr->reservation[statePtr->reorderBuf[i].execUnit].exTimeLeft - 1;	    if( statePtr->reservation[statePtr->reorderBuf[i].execUnit].exTimeLeft <= 0 ) {	    	      if(opcode(statePtr->reorderBuf[i].instr) == LW ) {	      //getResult() return the memory address for LW or SW		statePtr->reorderBuf[i].result = statePtr->memory[getResult(statePtr->reservation[statePtr->reorderBuf[i].execUnit], statePtr)];	     	      }	    	      if(opcode(statePtr->reorderBuf[i].instr) == SW ) {		//getResult() return the actual register/memory address for LW or SW		statePtr->reorderBuf[i].storeAddress = getResult(statePtr->reservation[statePtr->reorderBuf[i].execUnit], statePtr);		//store register result into memory		statePtr->reorderBuf[i].result = statePtr->regResult[field_rb(statePtr->reorderBuf[i].instr)].result;	      }	      if(opcode(statePtr->reorderBuf[i].instr) == BEQ ) { 		statePtr->reorderBuf[i].result = getResult(statePtr->reservation[statePtr->reorderBuf[i].execUnit], statePtr);		if( statePtr->reservation[statePtr->reorderBuf[i].execUnit].Vj == statePtr->reservation[statePtr->reorderBuf[i].execUnit].Vk )		  statePtr->pc = statePtr->reorderBuf[i].result;	      }	      if(opcode(statePtr->reorderBuf[i].instr) == ADD || opcode(statePtr->reorderBuf[i].instr) == NAND || opcode(statePtr->reorderBuf[i].instr) == MULT) { 		//getResult() return the actual value of ADD NAND or MULT		statePtr->reorderBuf[i].result = getResult(statePtr->reservation[statePtr->reorderBuf[i].execUnit], statePtr);			      }	      statePtr->reorderBuf[i].instrStatus = WRITINGRESULT;	    }	  }	}      }	/*	 * For Issuing State:	 * Check whether operands are available;  if so, change	 * status to executing.	 */	 for( i=0; i <RBSIZE; i++ ) {	   if( statePtr->reorderBuf[i].instrStatus == ISSUING ) {	     if( opcode(statePtr->reorderBuf[i].instr) == LW && statePtr->reservation[statePtr->reorderBuf[i].execUnit].Vj != -1 ) {	       //statePtr->reservation[statePtr->reorderBuf[i].execUnit].Qj = -1;	       statePtr->reorderBuf[i].instrStatus = EXECUTING;	     }	  	     else if(statePtr->reservation[statePtr->reorderBuf[i].execUnit].Vj != -1 &&     // here we only execute a instr when both Vj and Vk are available		     statePtr->reservation[statePtr->reorderBuf[i].execUnit].Vk != -1 ) {	       	       // statePtr->reservation[statePtr->reorderBuf[i].execUnit].Qj = -1;	       //statePtr->reservation[statePtr->reorderBuf[i].execUnit].Qk = -1;	       statePtr->reorderBuf[i].instrStatus = EXECUTING;		 	     }	     else if( opcode(statePtr->reorderBuf[i].instr) == NOOP || opcode(statePtr->reorderBuf[i].instr) == HALT )	       statePtr->reorderBuf[i].instrStatus = EXECUTING;	 	   } 	   	 }      	/*	 * Finally, when we have dealt with all instructions in the 	 * reservations stations, we check whether we can issue	 * a new instruction or not.	 * First check for free reservation station	 * If reservation station was found, then look for a free	 * reorder buffer.	 * If both available reservation station and reorder buffer,	 * issue instruction.	 *	 * Only 1 BEQ can be issued into queue 	 * 	 *	 */          int instruction;      instruction = statePtr->memory[statePtr->pc];      int unit;      int reorderNum;                if (opcode(instruction) == HALT) {		 	  issueInstr(instruction, 12, statePtr, 0);	  statePtr->rs[statePtr->pc] = unit;	  statePtr->issue[statePtr->pc] = statePtr->cycles;	  statePtr->pc = statePtr->pc +1;			          }            else  {	if(( -1 != (unit = checkReservation(statePtr,instruction))) &&  (-1 != (reorderNum = (checkReorder(statePtr, instruction)) )) ) {                      //reservation station is free	 	    	    issueInstr(instruction, unit, statePtr, reorderNum);	    statePtr->issue[statePtr->pc] = statePtr->cycles;	    statePtr->rs[statePtr->pc] = unit;	    statePtr->pc = statePtr->pc +1;	}      }	/*	 * Increment cycle counter	 */      statePtr->cycles = statePtr->cycles+ 1;             }   /* while (1) */	 printf("machine halted\n");	 printf("Total Cycles: %d\n", statePtr->cycles);	 printf("FETCHED:%d\n",pc);	 printf("RETIRED: %d\n",pc);     printf("BRANCHES:\n");     printf("MISPRED: \n");	  }

⌨️ 快捷键说明

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