📄 project2.c
字号:
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 + -