From 9f6d1626dd4ce767c18db2f9e986a7a53c77e260 Mon Sep 17 00:00:00 2001 From: Easton Man Date: Fri, 1 Sep 2023 20:20:27 +0800 Subject: [PATCH] FTB(timing): use last_stage_entry.carry in fallthrough address Mux() --- src/main/scala/xiangshan/frontend/FTB.scala | 19 +++++++++++++++---- .../xiangshan/frontend/FrontendBundle.scala | 11 ++++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/main/scala/xiangshan/frontend/FTB.scala b/src/main/scala/xiangshan/frontend/FTB.scala index ad691ea7a..b8718c420 100644 --- a/src/main/scala/xiangshan/frontend/FTB.scala +++ b/src/main/scala/xiangshan/frontend/FTB.scala @@ -176,7 +176,15 @@ class FTBEntry(implicit p: Parameters) extends XSBundle with FTBParams with BPUU def getOffsetVec = VecInit(brSlots.map(_.offset) :+ tailSlot.offset) def isJal = !isJalr - def getFallThrough(pc: UInt) = getFallThroughAddr(pc, carry, pftAddr) + def getFallThrough(pc: UInt, last_stage_entry: Option[Tuple2[FTBEntry, Bool]] = None) = { + if (last_stage_entry.isDefined) { + var stashed_carry = RegEnable(last_stage_entry.get._1.carry, last_stage_entry.get._2) + getFallThroughAddr(pc, stashed_carry, pftAddr) + } else { + getFallThroughAddr(pc, carry, pftAddr) + } + } + def hasBr(offset: UInt) = brSlots.map{ s => s.valid && s.offset <= offset}.reduce(_||_) || (tailSlot.valid && tailSlot.offset <= offset && tailSlot.sharing) @@ -432,13 +440,16 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU // io.out.bits.resp := RegEnable(io.in.bits.resp_in(0), 0.U.asTypeOf(new BranchPredictionResp), io.s1_fire) io.out := io.in.bits.resp_in(0) - val s1_latch_call_is_rvc = DontCare // TODO: modify when add RAS - io.out.s2.full_pred.zip(s2_hit_dup).map {case (fp, h) => fp.hit := h} io.out.s2.pc := s2_pc_dup for (full_pred & s2_ftb_entry & s2_pc & s1_pc & s1_fire <- io.out.s2.full_pred zip s2_ftb_entry_dup zip s2_pc_dup zip s1_pc_dup zip io.s1_fire) { - full_pred.fromFtbEntry(s2_ftb_entry, s2_pc, Some((s1_pc, s1_fire))) + full_pred.fromFtbEntry(s2_ftb_entry, + s2_pc, + // Previous stage meta for better timing + Some(s1_pc, s1_fire), + Some(ftbBank.io.read_resp, s1_fire) + ) } io.out.s3.full_pred.zip(s3_hit_dup).map {case (fp, h) => fp.hit := h} diff --git a/src/main/scala/xiangshan/frontend/FrontendBundle.scala b/src/main/scala/xiangshan/frontend/FrontendBundle.scala index f59471f25..c25970ff4 100644 --- a/src/main/scala/xiangshan/frontend/FrontendBundle.scala +++ b/src/main/scala/xiangshan/frontend/FrontendBundle.scala @@ -511,9 +511,14 @@ class FullBranchPrediction(implicit p: Parameters) extends XSBundle with HasBPUC def taken = br_taken_mask.reduce(_||_) || slot_valids.last // || (is_jal || is_jalr) - def fromFtbEntry(entry: FTBEntry, pc: UInt, last_stage: Option[Tuple2[UInt, Bool]] = None) = { + def fromFtbEntry( + entry: FTBEntry, + pc: UInt, + last_stage_pc: Option[Tuple2[UInt, Bool]] = None, + last_stage_entry: Option[Tuple2[FTBEntry, Bool]] = None + ) = { slot_valids := entry.brSlots.map(_.valid) :+ entry.tailSlot.valid - targets := entry.getTargetVec(pc, last_stage) // Use previous stage pc for better timing + targets := entry.getTargetVec(pc, last_stage_pc) // Use previous stage pc for better timing jalr_target := targets.last offsets := entry.getOffsetVec is_jal := entry.tailSlot.valid && entry.isJal @@ -526,7 +531,7 @@ class FullBranchPrediction(implicit p: Parameters) extends XSBundle with HasBPUC val startLower = Cat(0.U(1.W), pc(instOffsetBits+log2Ceil(PredictWidth)-1, instOffsetBits)) val endLowerwithCarry = Cat(entry.carry, entry.pftAddr) fallThroughErr := startLower >= endLowerwithCarry - fallThroughAddr := Mux(fallThroughErr, pc + (FetchWidth * 4).U, entry.getFallThrough(pc)) + fallThroughAddr := Mux(fallThroughErr, pc + (FetchWidth * 4).U, entry.getFallThrough(pc, last_stage_entry)) } def display(cond: Bool): Unit = { -- GitLab