📄 project1.c
字号:
newState.IFID.regB = field1(state.instrMem[newState.pc]);
}else{
/* if there is a data hazard caused by one LW instruction */
newState.IFID.instr = state.IFID.instr;
newState.IFID.regA = state.IFID.regA;
newState.IFID.regB = state.IFID.regB;
newState.IFID.pcPlus1 = state.IFID.pcPlus1;
newState.IFID.predictedCond = state.IFID.predictedCond;
}
}
else{
countfetched++;
newState.pc = state.pc + 1;
newState.IFID.pcPlus1 = newState.pc + 1;
newState.IFID.instr = state.instrMem[state.pc+1];
newState.IFID.regA = field0(state.instrMem[state.pc+1]);
newState.IFID.regB = field1(state.instrMem[state.pc+1]);
}
if(opcode(state.IFID.instr) == BEQ)
{
/* to predict whether this branch is taken or not using the pht indexed by bhr and brancePC*/
index = bhr ^ (state.pc);
if((pht[index]>=0) && (pht[index]<=1)){
state.IDEX.predictedCond = 0;
} else {
state.IDEX.predictedCond=1;
/* to search in the BTB buffer to find if the branch PC entry exists */
for(i=0;i<4;i++)
{
if(btb[i][0]== state.pc) {
newState.pc = btb[i][1]%65536;
newState.IFID.pcPlus1 = btb[i][1]%65536 + 1;
newState.IFID.instr = state.instrMem[newState.pc];
newState.IFID.regA = field0(state.instrMem[newState.pc]);
newState.IFID.regB = field1(state.instrMem[newState.pc]);
}
}
}
}
if(opcode(state.MEMWB.instr) == HALT){
fetched = countfetched - 3;
}
/* --------------------- ID stage --------------------- */
if((state.EXMEM.controlHazard==HC_target) || (state.EXMEM.controlHazard==HC_pcPlus1)){
newState.IDEX.instr = NOOPINSTRUCTION;
newState.IDEX.readRegB = 0;
newState.IDEX.hazard_status = FWD;
newState.IDEX.hazard_positionA = -1;
newState.IDEX.hazard_positionB = -1;
newState.IDEX.readRegA = 0;
newState.IDEX.offset = 0;
newState.IDEX.destReg = 8;
newState.IDEX.regA = 0;
newState.IDEX.regB = 0;
newState.IDEX.predictedCond = 0;
}else{
if(state.IDEX.hazard_status == HLW){
newState.IDEX.pcPlus1 = state.IDEX.pcPlus1;
newState.IDEX.instr = state.IDEX.instr;
newState.IDEX.readRegA = state.IDEX.readRegA;
newState.IDEX.readRegB = state.IDEX.readRegB;
newState.IDEX.regA = state.IDEX.regA;
newState.IDEX.regB = state.IDEX.regB;
newState.IDEX.offset = state.IDEX.offset;
newState.IDEX.hazard_status = FWD;
newState.IDEX.hazard_positionA = state.IDEX.hazard_positionA;
newState.IDEX.hazard_positionB = state.IDEX.hazard_positionB;
newState.IDEX.predictedCond = state.IDEX.predictedCond;
}
else {
newState.IDEX.pcPlus1 = state.IFID.pcPlus1;
newState.IDEX.instr = state.IFID.instr;
newState.IDEX.readRegA = state.reg[field0(state.IFID.instr)];
newState.IDEX.readRegB = state.reg[field1(state.IFID.instr)];
newState.IDEX.offset = field2(state.IFID.instr);
newState.IDEX.regA = state.IFID.regA;
newState.IDEX.regB = state.IFID.regB;
newState.IDEX.predictedCond = state.IFID.predictedCond;
/* 8 here means that no pipeline register is needed to be written here. */
switch(opcode(state.IFID.instr))
{
case ADD :
case NAND :
case MULT : newState.IDEX.destReg = field2(state.IFID.instr);
break;
case LW : newState.IDEX.destReg = field1(state.IFID.instr);
break;
case BEQ :
case SW:
case HALT :
case NOOP : newState.IDEX.destReg = 8;
break;
}
/* By default, no hazards there. */
newState.IDEX.hazard_status = FWD;
newState.IDEX.hazard_positionA = -1;
newState.IDEX.hazard_positionB = -1;
switch(opcode(state.IFID.instr))
{
case ADD :
case NAND :
case SW :
case BEQ :
case MULT : for(i=0; i<3; i++)
if(state.IFID.regA==hd1.in[i])
{ newState.IDEX.hazard_positionA=i;
break;
}
for(i=0; i<3; i++)
if(state.IFID.regB==hd1.in[i])
{ newState.IDEX.hazard_positionB=i;
break;
}
if((newState.IDEX.hazard_positionA!=-1) && (newState.IDEX.hazard_positionB !=-1))
newState.IDEX.hazard_status = H12;
else if(newState.IDEX.hazard_positionA !=-1) newState.IDEX.hazard_status = H1;
else if(newState.IDEX.hazard_positionB !=-1) newState.IDEX.hazard_status = H2;
if(((opcode(state.IDEX.instr)==LW) && (newState.IDEX.hazard_positionA==0)) || ((opcode(state.IDEX.instr)== LW) && (newState.IDEX.hazard_positionB==0))) newState.IDEX.hazard_status=HLW;
break;
case LW : for(i=0;i<3;i++)
if(state.IFID.regA==hd1.in[i]){
newState.IDEX.hazard_positionA=i;
break;
}
if (newState.IDEX.hazard_positionA !=-1)newState.IDEX.hazard_status = H1;
if((opcode(state.IDEX.instr)==LW) && (newState.IDEX.hazard_positionA==0)) newState.IDEX.hazard_status=HLW;
break;
case NOOP :
case HALT : break;
}
}
}
/* --------------------- EX stage --------------------- */
if((state.IDEX.hazard_status==HLW) || (state.EXMEM.controlHazard==HC_target) || (state.EXMEM.controlHazard==HC_pcPlus1)){
newState.EXMEM.instr = NOOPINSTRUCTION;
newState.EXMEM.branchTarget = 0;
newState.EXMEM.aluResult = 0;
newState.EXMEM.readRegB = 0;
newState.EXMEM.hazard_status = FWD;
newState.EXMEM.destReg = 8;
newState.EXMEM.cond = 0;
newState.EXMEM.pcPlus1=0;
newState.EXMEM.controlHazard = 0;
newState.EXMEM.predictedCond = 0;
}
else {
newState.EXMEM.instr = state.IDEX.instr;
newState.EXMEM.hazard_status = state.IDEX.hazard_status;
newState.EXMEM.branchTarget = state.IDEX.pcPlus1 + state.IDEX.offset;
newState.EXMEM.predictedCond = state.IDEX.predictedCond;
newState.EXMEM.readRegB = state.IDEX.readRegB;
newState.EXMEM.destReg = state.IDEX.destReg;
newState.EXMEM.pcPlus1 = state.IDEX.pcPlus1;
switch(state.IDEX.hazard_status)
{
case FWD : if((state.IDEX.hazard_positionA>=0) && (state.IDEX.hazard_positionA<2))state.IDEX.readRegA = hd1.out[state.IDEX.hazard_positionA+1];
if(state.IDEX.hazard_positionA==2)state.IDEX.readRegA = state.reg[state.IDEX.regA];
if((state.IDEX.hazard_positionB>=0) && (state.IDEX.hazard_positionB<2))state.IDEX.readRegB = hd1.out[state.IDEX.hazard_positionB+1];
if(state.IDEX.hazard_positionB==2)state.IDEX.readRegB = state.reg[state.IDEX.regB];
break;
case H1 : if(state.IDEX.hazard_positionA==0) state.IDEX.readRegA = hd1.out[0];
else if(state.IDEX.hazard_positionA==1) state.IDEX.readRegA = hd1.out[1];
else state.IDEX.readRegA = hd1.out[2];
break;
case H2 : if(state.IDEX.hazard_positionB==0) state.IDEX.readRegB = hd1.out[0];
else if(state.IDEX.hazard_positionB==1) state.IDEX.readRegB = hd1.out[1] ;
else state.IDEX.readRegB = hd1.out[2];
break;
case H12 : if(state.IDEX.hazard_positionA==0) state.IDEX.readRegA = hd1.out[0];
else if(state.IDEX.hazard_positionA==1) state.IDEX.readRegA = hd1.out[1];
else state.IDEX.readRegA = hd1.out[2];
if(state.IDEX.hazard_positionB==0) state.IDEX.readRegB = hd1.out[0];
else if(state.IDEX.hazard_positionB==1) state.IDEX.readRegB = hd1.out[1] ;
else state.IDEX.readRegB = hd1.out[2];
break;
default : break;
}
switch(opcode(state.IDEX.instr))
{
case ADD : newState.EXMEM.aluResult = state.IDEX.readRegA + state.IDEX.readRegB;
newState.EXMEM.cond = 0;
break;
case NAND : newState.EXMEM.aluResult = ~(state.IDEX.readRegA & state.IDEX.readRegB);
newState.EXMEM.cond = 0;
break;
case MULT : newState.EXMEM.aluResult = state.IDEX.readRegA * state.IDEX.readRegB;
newState.EXMEM.cond = 0;
break;
case LW :
case SW : newState.EXMEM.aluResult = state.IDEX.readRegA + state.IDEX.offset;
newState.EXMEM.cond = 0;
break;
case BEQ : newState.EXMEM.aluResult = state.IDEX.pcPlus1 + state.IDEX.offset;
/* test for equality */
if(state.IDEX.readRegA == state.IDEX.readRegB)newState.EXMEM.cond=1;
else newState.EXMEM.cond=0;
break;
case HALT :
case NOOP : break;
}
/* to see if the predicted cond is correct or now */
if(opcode(state.EXMEM.instr)==BEQ){
/* if the branch is predicted to be not taken */
if(state.EXMEM.predictedCond==0){
if(state.EXMEM.predictedCond!= state.EXMEM.cond){
mispred++;
/* stop bad instructions before it */
newState.EXMEM.controlHazard = HC_target;
/* the branch will go to the target PC */
}
}
/* if the branch is predicted to be taken*/
if(state.EXMEM.predictedCond==1){
if(state.EXMEM.predictedCond!=state.EXMEM.cond){
mispred++;
if(state.EXMEM.branchTarget == state.IDEX.pcPlus1-1){
newState.EXMEM.controlHazard = HC_pcPlus1;
}
}
else{
if(state.EXMEM.branchTarget != state.IDEX.pcPlus1-1){
newState.EXMEM.controlHazard = HC_target;
}
}
}
}
}
/* update the histrory register, predicted history table and btb */
if(opcode(state.IDEX.instr)==BEQ){
index = bhr ^ (newState.EXMEM.pcPlus1-1);
if((newState.EXMEM.cond==0 && pht[index]==0) || (newState.EXMEM.cond==1 && pht[index]==3))pht[index]=pht[index];
else if(newState.EXMEM.cond==0) pht[index] = pht[index]-1;
else pht[index] = pht[index]+1;
bhr = ((bhr<<1)+newState.EXMEM.cond)&0x3F;
if(newState.EXMEM.cond==1)
{
/* to check see if the table is full */
insert=-1;
for(i=0;i<4;i++) if(btb[i][0]==-1) {insert=i; break;}
if(insert==-1){
for(i=0;i<3;i++)
for(k=0;k<2;k++)
btb[i][k]=btb[i+1][k];
btb[3][0]=newState.EXMEM.pcPlus1-1;
btb[3][1]=newState.EXMEM.branchTarget;
}
else{
btb[insert][0]= newState.EXMEM.pcPlus1-1;
btb[insert][1]= newState.EXMEM.branchTarget;
}
}
}
/* --------------------- MEM stage -------------------- */
countretired++;
if(opcode(state.EXMEM.instr)== HALT) retired=countretired-3;
if((state.EXMEM.controlHazard==HC_target) || (state.EXMEM.controlHazard==HC_pcPlus1)){
newState.MEMWB.instr = NOOPINSTRUCTION;
newState.MEMWB.pcPlus1 = 0;
newState.MEMWB.writeData = 0;
newState.MEMWB.destReg = 8;
newState.MEMWB.aluResult = 0;
}
else{
newState.MEMWB.instr = state.EXMEM.instr;
newState.MEMWB.pcPlus1=state.EXMEM.pcPlus1;
switch(opcode(state.EXMEM.instr))
{
case ADD :
case NAND :
case MULT : newState.MEMWB.writeData = state.EXMEM.aluResult;
break;
case LW : newState.MEMWB.writeData = state.dataMem[state.EXMEM.aluResult];
break;
case SW : newState.MEMWB.writeData = state.EXMEM.readRegB;
break;
case NOOP :
case BEQ : break;
default :break;
}
newState.MEMWB.destReg = state.EXMEM.destReg;
newState.MEMWB.aluResult = state.EXMEM.aluResult;
}
/* --------------------- WB stage --------------------- */
newState.WBEND.instr = state.MEMWB.instr;
newState.WBEND.writeData = state.MEMWB.writeData;
switch(opcode(state.MEMWB.instr))
{
case LW :
case ADD :
case NAND :
case MULT : newState.reg[state.MEMWB.destReg]= state.MEMWB.writeData;
break;
case SW : newState.dataMem[state.MEMWB.aluResult] = state.MEMWB.writeData;
break;
case NOOP :
case BEQ : break;
}
state = newState; /* This is the last statement before end of the loop.
It marks the end of the cycle and updates the
current state with the values calculated in this cycle. */
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -