static void AddDependence(Instruction instrfrom, Instruction instrto, FromStage fromstage) { if (instrfrom.op == "LW" && fromstage == FromStage.RF) //LW dependence 1 cycle ahead, stall for 2 cycles { ctx.stallinstr = instrto; ctx.stallcnt = 2; ctx.cause = StallCause.Load; ClearDetected(); stall = true; } else if (instrfrom.op == "LW" && fromstage == FromStage.RF) //LW dependence 2 cycles ahead, stall for 1 cycle { ctx.stallinstr = instrto; ctx.stallcnt = 1; ctx.cause = StallCause.Load; ClearDetected(); stall = true; } else //Normal dependency { if (ctx.forwarded.From_Detected1.op == "NOP") //First detected is empty, add there { ctx.forwarded.From_Detected1 = instrfrom; ctx.forwarded.To_Detected1 = instrto; return; } //First isn't empty, add in second slot ctx.forwarded.From_Detected2 = instrfrom; ctx.forwarded.To_Detected2 = instrto; } }
static void AddExDependence(Instruction instrfrom, Instruction instrto, FromStage from, ToReg toreg, FromReg fromreg) { if (from == FromStage.DF) { ctx.forwarded.From_EXDF_RFEX = instrfrom; ctx.forwarded.To_EXDF_RFEX = instrto; ctx.forwards.EXDF_RFEX++; if (toreg == ToReg.RS || toreg == ToReg.BASEREG) //On the left of ALU { ctx.forwardvalues.DF_To_EX_Left_Value = ctx.DF_DS; ctx.forwardvalues.Use_DF_To_EX_Left = true; } else //toreg == ToReg.RT, on the right of ALU { ctx.forwardvalues.DF_To_EX_Right_Value = ctx.DF_DS; ctx.forwardvalues.Use_DF_To_EX_Right = true; } } else if (from == FromStage.DS) { ctx.forwarded.From_DFDS_RFEX = instrfrom; ctx.forwarded.To_DFDS_RFEX = instrto; ctx.forwards.DFDS_RFEX++; if (toreg == ToReg.RS || toreg == ToReg.BASEREG) //On the left of ALU { ctx.forwardvalues.DS_To_EX_Left_Value = ctx.pipelineregs.DS__WB_ALUout_LMD; ctx.forwardvalues.Use_DS_To_EX_Left = true; } else //toreg == ToReg.RT, on the right of ALU { ctx.forwardvalues.DS_To_EX_Right_Value = ctx.pipelineregs.DS__WB_ALUout_LMD; ctx.forwardvalues.Use_DS_To_EX_Right = true; } } else //from == FromStage.WB { ctx.forwarded.From_DSWB_RFEX = instrfrom; ctx.forwarded.To_DSWB_RFEX = instrto; ctx.forwards.DSWB_RFEX++; if (toreg == ToReg.RS || toreg == ToReg.BASEREG) //On the left of ALU { ctx.forwardvalues.WB_To_EX_Left_Value = fromreg == FromReg.RD ? ctx.registers[(int)instrfrom.rd] : ctx.registers[(int)instrfrom.rt]; ctx.forwardvalues.Use_WB_To_EX_Left = true; } else //toreg == ToReg.RT, on the right of ALU { ctx.forwardvalues.WB_To_EX_Right_Value = fromreg == FromReg.RD ? ctx.registers[(int)instrfrom.rd] : ctx.registers[(int)instrfrom.rt]; ctx.forwardvalues.Use_WB_To_EX_Right = true; } } }
static void AddDfDependence(Instruction instrfrom, Instruction instrto, FromStage from, FromReg fromreg) { if (from == FromStage.DS) { ctx.forwarded.From_DFDS_EXDF = instrfrom; ctx.forwarded.To_DFDS_EXDF = instrto; ctx.forwards.DFDS_EXDF++; ctx.forwardvalues.DS_To_DF_RT_Value = ctx.pipelineregs.DS__WB_ALUout_LMD; ctx.forwardvalues.Use_DS_To_DF_RT = true; } else //from == FromStage.WB { ctx.forwarded.From_DSWB_EXDF = instrfrom; ctx.forwarded.To_DSWB_EXDF = instrto; ctx.forwards.DSWB_EXDF++; ctx.forwardvalues.WB_To_DF_RT_Value = fromreg == FromReg.RD ? ctx.registers[(int)instrfrom.rd] : ctx.registers[(int)instrfrom.rt]; ctx.forwardvalues.Use_WB_To_DF_RT = true; } }
static bool CheckDependence(Instruction instrfrom, Instruction instrto, uint reg, FromStage fromstage) { //If writes to RD, want to check for dependence if (instrfrom.write == WriteTo.RD && instrfrom.rd == reg) { AddDependence(instrfrom, instrto, fromstage); return(true); } //Similarly check for dependence in RT else if (instrfrom.write == WriteTo.RT && instrfrom.rt == reg) { AddDependence(instrfrom, instrto, fromstage); return(true); } return(false); }