Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RAS: handle a case where a jalr instruction requires a pop followed by a push #3277

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions src/main/scala/xiangshan/frontend/FTB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ class FTBEntry_part(implicit p: Parameters) extends XSBundle with FTBParams with
val isRet = Bool()
val isJalr = Bool()

def isJal = !isJalr
def isJal = !isJalr
def onlyRet = isRet && !isCall
}

class FTBEntry_FtqMem(implicit p: Parameters) extends FTBEntry_part with FTBParams with BPUUtils {
Expand Down Expand Up @@ -737,7 +738,7 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
io.out.s1_ftbCloseReq := s1_close_ftb_req
io.out.s1_uftbHit := io.fauftb_entry_hit_in
val s1_uftbHasIndirect = io.fauftb_entry_in.jmpValid &&
io.fauftb_entry_in.isJalr && !io.fauftb_entry_in.isRet // uFTB determines that it's real JALR, RET and JAL are excluded
io.fauftb_entry_in.isJalr && !io.fauftb_entry_in.onlyRet // uFTB determines that it's real JALR, only RET and JAL are excluded
io.out.s1_uftbHasIndirect := s1_uftbHasIndirect

// always taken logic
Expand Down Expand Up @@ -813,4 +814,4 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
("ftb_commit_misses ", io.update.valid && !u_meta.hit),
)
generatePerfEvent()
}
}
11 changes: 6 additions & 5 deletions src/main/scala/xiangshan/frontend/FrontendBundle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ class FullBranchPrediction(implicit p: Parameters) extends XSBundle with HasBPUC
!real_slot_taken_mask().init.reduce(_||_) &&
real_slot_taken_mask().last && !is_br_sharing
def hit_taken_on_call = hit_taken_on_jmp && is_call
def hit_taken_on_ret = hit_taken_on_jmp && is_ret
def hit_taken_on_only_ret = hit_taken_on_jmp && is_ret && !is_call
def hit_taken_on_jalr = hit_taken_on_jmp && is_jalr

def cfiIndex = {
Expand Down Expand Up @@ -653,7 +653,7 @@ class BranchPredictionUpdate(implicit p: Parameters) extends XSBundle with HasBP
def is_ret = ftb_entry.tailSlot.valid && ftb_entry.isRet

def is_call_taken = is_call && jmp_taken && cfi_idx.valid && cfi_idx.bits === ftb_entry.tailSlot.offset
def is_ret_taken = is_ret && jmp_taken && cfi_idx.valid && cfi_idx.bits === ftb_entry.tailSlot.offset
def is_only_ret_taken = !is_call && is_ret && jmp_taken && cfi_idx.valid && cfi_idx.bits === ftb_entry.tailSlot.offset

def display(cond: Bool) = {
XSDebug(cond, p"-----------BranchPredictionUpdate-----------\n")
Expand Down Expand Up @@ -690,8 +690,9 @@ class BranchPredictionRedirect(implicit p: Parameters) extends Redirect with Has
def ControlBTBMissBubble = ControlRedirectBubble && !cfiUpdate.br_hit && !cfiUpdate.jr_hit
def TAGEMissBubble = ControlRedirectBubble && cfiUpdate.br_hit && !cfiUpdate.sc_hit
def SCMissBubble = ControlRedirectBubble && cfiUpdate.br_hit && cfiUpdate.sc_hit
def ITTAGEMissBubble = ControlRedirectBubble && cfiUpdate.jr_hit && !cfiUpdate.pd.isRet
def RASMissBubble = ControlRedirectBubble && cfiUpdate.jr_hit && cfiUpdate.pd.isRet
// ret-call instruction will jump in the same way as the call instruction
def ITTAGEMissBubble = ControlRedirectBubble && cfiUpdate.jr_hit && (!cfiUpdate.pd.isRet || cfiUpdate.pd.isCall)
def RASMissBubble = ControlRedirectBubble && cfiUpdate.jr_hit && (cfiUpdate.pd.isRet && !cfiUpdate.pd.isCall)
def MemVioRedirectBubble = debugIsMemVio
def OtherRedirectBubble = !debugIsCtrl && !debugIsMemVio

Expand Down Expand Up @@ -720,4 +721,4 @@ class BranchPredictionRedirect(implicit p: Parameters) extends Redirect with Has
XSDebug(cond, p"[stFtqOffset] ${stFtqOffset}\n")
XSDebug(cond, p"---------------------------------------------- \n")
}
}
}
2 changes: 1 addition & 1 deletion src/main/scala/xiangshan/frontend/IFU.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1077,4 +1077,4 @@ class NewIFU(implicit p: Parameters) extends XSModule
reset = reset
)

}
}
2 changes: 1 addition & 1 deletion src/main/scala/xiangshan/frontend/NewFtq.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1686,4 +1686,4 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
("ftb_hit ", PopCount(ftb_hit) ),
)
generatePerfEvent()
}
}
11 changes: 6 additions & 5 deletions src/main/scala/xiangshan/frontend/PreDecode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ trait HasPdConst extends HasXSParameter with HasICacheParameters with HasIFUCons
val brType::Nil = ListLookup(instr, List(BrType.notCFI), PreDecodeInst.brTable)
val rd = Mux(isRVC(instr), instr(12), instr(11,7))
val rs = Mux(isRVC(instr), Mux(brType === BrType.jal, 0.U, instr(11, 7)), instr(19, 15))
val isCall = (brType === BrType.jal && !isRVC(instr) || brType === BrType.jalr) && isLink(rd) // Only for RV64
val isRet = brType === BrType.jalr && isLink(rs) && !isCall
val isCall = (brType === BrType.jal && !isRVC(instr) || brType === BrType.jalr) && isLink(rd) // Only for RV64
val isRet = (brType === BrType.jalr && isLink(rs) && !isCall) || (brType === BrType.jalr && isLink(rs) && isLink(rd) && (rs =/= rd))
List(brType, isCall, isRet)
}
def jal_offset(inst: UInt, rvc: Bool): UInt = {
Expand Down Expand Up @@ -79,6 +79,7 @@ class PreDecodeInfo extends Bundle { // 8 bit
def isJal = brType === BrType.jal
def isJalr = brType === BrType.jalr
def notCFI = brType === BrType.notCFI
def onlyRet = isRet && !isCall
}

class PreDecodeResp(implicit p: Parameters) extends XSBundle with HasPdConst {
Expand Down Expand Up @@ -343,15 +344,15 @@ class PredChecker(implicit p: Parameters) extends XSModule with HasPdConst {
//Stage 1: detect remask fault
/** first check: remask Fault */
jalFaultVec := VecInit(pds.zipWithIndex.map{case(pd, i) => pd.isJal && instrRange(i) && instrValid(i) && (takenIdx > i.U && predTaken || !predTaken) })
retFaultVec := VecInit(pds.zipWithIndex.map{case(pd, i) => pd.isRet && instrRange(i) && instrValid(i) && (takenIdx > i.U && predTaken || !predTaken) })
retFaultVec := VecInit(pds.zipWithIndex.map{case(pd, i) => pd.onlyRet && instrRange(i) && instrValid(i) && (takenIdx > i.U && predTaken || !predTaken) })
val remaskFault = VecInit((0 until PredictWidth).map(i => jalFaultVec(i) || retFaultVec(i)))
val remaskIdx = ParallelPriorityEncoder(remaskFault.asUInt)
val needRemask = ParallelOR(remaskFault)
val fixedRange = instrRange.asUInt & (Fill(PredictWidth, !needRemask) | Fill(PredictWidth, 1.U(1.W)) >> ~remaskIdx)

io.out.stage1Out.fixedRange := fixedRange.asTypeOf((Vec(PredictWidth, Bool())))

io.out.stage1Out.fixedTaken := VecInit(pds.zipWithIndex.map{case(pd, i) => instrValid (i) && fixedRange(i) && (pd.isRet || pd.isJal || takenIdx === i.U && predTaken && !pd.notCFI) })
io.out.stage1Out.fixedTaken := VecInit(pds.zipWithIndex.map{case(pd, i) => instrValid (i) && fixedRange(i) && (pd.onlyRet || pd.isJal || takenIdx === i.U && predTaken && !pd.notCFI) })

/** second check: faulse prediction fault and target fault */
notCFITaken := VecInit(pds.zipWithIndex.map{case(pd, i) => fixedRange(i) && instrValid(i) && i.U === takenIdx && pd.notCFI && predTaken })
Expand Down Expand Up @@ -436,4 +437,4 @@ class FrontendTrigger(implicit p: Parameters) extends XSModule with SdtrigExt {
}
io.triggered.foreach(_.backendCanFire := VecInit(Seq.fill(TriggerNum)(false.B)))
io.triggered.foreach(_.backendHit := VecInit(Seq.fill(TriggerNum)(false.B)))
}
}
Loading
Loading