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

📄 project1.c

📁 Computer Architecture pipelined implementation simulator
💻 C
📖 第 1 页 / 共 2 页
字号:
             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 + -