Here is some help with implementing dynamic branch prediction. I will give you an outline of how I approached it. You can implement it differently if you like. First, to make things "do-able", I added some fields to the reorder buffer data structure, including saving the pc of the instruction in the reorder buffer and saving the prediction made for a branch or jump. Second, to make it easier to implement, I used a DIRECT-MAPPED scheme for the branch target buffer. This way, I need only check one location for a given PC to determine whether the branch prediction is in the BTB or not. /* * Branch outcomes */ #define NOTTAKEN 0 #define TAKEN 1 /* * Reorder Buffer Entries */ typedef struct _reorderEntry { int busy; /* reorder buffer is in use */ int instr; /* instruction being executed */ int execUnit; /* execution unit producing result */ int instrStatus; /* current status of instruction */ int valid; /* flat thag indicates that result value is valid */ int result; /* holds speculative result until commit */ int storeAddress; /* holds the memory address for a store word */ int pc; /* PC of this instruction */ int prediction; /* holds the prediction for branch accesses */ }reorderEntry; void printState(statePtr, memorySize) machineState *statePtr; int memorySize; { int i; printf("Cycles: %d\n", statePtr->cycles); printf("\t pc=%d\n",statePtr->pc); printf("\t Reservation stations:\n"); for (i=0; ireservation[i].busy == 1){ printf("\t \t Reservation station %d: ",i); if (statePtr->reservation[i].Rj) {printf("Vj = %d ", statePtr->reservation[i].Vj);} else {printf("Qj = %d ", statePtr->reservation[i].Qj);} if (statePtr->reservation[i].Rk) {printf("Vk = %d ", statePtr->reservation[i].Vk);} else {printf("Qk = %d ", statePtr->reservation[i].Qk);} printf(" ExTimeLeft = %d RBNum = %d\n", statePtr->reservation[i].exTimeLeft, statePtr->reservation[i].reorderNum); } } printf("\t Reorder buffers:\n"); for (i=0; ireorderBuf[i].busy == 1){ printf("\t \t Reorder buffer %d: ",i); printf("instr %d executionUnit %d state %d valid %d result %d storeAddress %d pc %d", statePtr->reorderBuf[i].instr, statePtr->reorderBuf[i].execUnit, statePtr->reorderBuf[i].instrStatus, statePtr->reorderBuf[i].valid, statePtr->reorderBuf[i].result, statePtr->reorderBuf[i].storeAddress, statePtr->reorderBuf[i].pc); if (statePtr->reorderBuf[i].prediction != -1){ printf("prediction %d", statePtr->reorderBuf[i].prediction); } printf("\n"); } } printf("\t Register result status:\n"); for (i=1; iregResult[i].valid){ printf("\t \t Register %d: ",i); printf("waiting for reorder buffer number %d\n", statePtr->regResult[i].reorderNum); } } printf("\t Branch target buffer:\n"); for (i=0; ibtBuf[i].valid){ printf("\t \t Entry %d: PC=%d, Target=%d, Pred=%d\n", i, statePtr->btBuf[i].branchPC, statePtr->btBuf[i].targetPC, statePtr->btBuf[i].prediction); } } printf("\t Memory:\n"); for (i=0; imemory[i]); } printf("\t Registers:\n"); for (i=0; iregFile[i]); } } int getPrediction(statePtr) machineState *statePtr; { /* * Given a PC, check branch target buffer * to see if the branch is currently in the table. * If so, return the prediction in the table. * Otherwise, return -1. */ } void updateBTB(statePtr, branchPC, targetPC, outcome) machineState *statePtr; int branchPC; int targetPC; int outcome; { /* * Decide whether Match in table * If so, update prediction using 2-bit predictor state machine * If not, use a DIRECT-MAPPED SCHEME to add the current branch * to the table. Set an initial prediction of STRONGTAKEN if * the current branch was taken. Set an initial prediction of * STRONGNOT if the current branch was not taken. */ } int getTarget(statePtr, reorderNum) machineState *statePtr; int reorderNum; { /* * Check whether branch is in BTB; * If not, return the incremented pc value. * This effectively means we are predicting the branch is not taken. * If the branch is in the BTB with a prediction of STRONGTAKEN or * WEAKTAKEN, return the target address of the branch. * If the branch is in the BTB with a prediction of STRONGNOT or * WEAKNOT, return the fall-through address (branchPC + 1) */ } main(argc,argv) int argc; char *argv[]; { /* * When committing, we know the outcome of a branch or jump instruction. * There are three possible cases: predict taken, predict not taken, or * no prediction (because branch did not appear in BTB). * If we Predicted taken: * If our prediction was correct, simply continue execution. * If our prediction was wrong and branch was not taken, must * Change PC to fall-through of the branch and flush * reorder buffer and reservation stations. * If we predicted not taken: * If prediction was correct, continue execution. * If prediction was wrong and branch was taken: * Change PC to branch target and flush reorder * buffer and reservation stations. * If we were not able to predict this branch: * Still need to flush if the branch is taken. * Change PC to branch target. * After any branch, update contents of Branch Target Buffer */ /* * When issuing a branch or jump instruction, change PC to correct * target (i.e., either fall-through or branch target). * When issuing other instructions, just increment PC. */ }