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

bpu: improve CGE of bpu/predictors_io_update_* #3541

Closed
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
79 changes: 79 additions & 0 deletions src/main/scala/xiangshan/frontend/BPU.scala
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,85 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst with H

predictors.io.update.valid := RegNext(io.ftq_to_bpu.update.valid, init = false.B)
predictors.io.update.bits := RegEnable(io.ftq_to_bpu.update.bits, io.ftq_to_bpu.update.valid)
XSPerfAccumulate("predictors_io_update_valid", io.ftq_to_bpu.update.valid)

// ------- To optimize Clock Gate Efficiency of bpu/predictors_update* -------
// Update pc
predictors.io.update.bits.pc := SegmentedAddrNext(io.ftq_to_bpu.update.bits.pc, pcSegments, io.ftq_to_bpu.update.valid, Some("predictors.io.update.pc")).getAddr()

// Update ftb_entry
val FTBEntryUpdateValid = io.ftq_to_bpu.update.bits.ftb_entry.valid && io.ftq_to_bpu.update.valid
predictors.io.update.bits.ftb_entry := RegEnable(io.ftq_to_bpu.update.bits.ftb_entry, FTBEntryUpdateValid)
predictors.io.update.bits.ftb_entry.valid := RegEnable(FTBEntryUpdateValid, io.ftq_to_bpu.update.valid)

// Get UpdateMeta of each Predictor
// | <------- io.ftq_to_bpu.update.bits.meta -------> |
// |---- x -----| uftb | tage-sc | ftb | ittage | ras |
val metaSizeSeq = predictors.asInstanceOf[Composer].getEachMetaSize() // (ras, ittage, ftb, tage-sc, uftb)
val metaStartIdxWithSize = metaSizeSeq.foldLeft(Seq[(Int, Int)]()) { (acc, len) =>
val start = if (acc.isEmpty) 0 else acc.last._1 + acc.last._2
acc :+ (start, len)
}

val Seq(( ras_meta_sta, ras_meta_sz),
(ittage_meta_sta, ittage_meta_sz),
( ftb_meta_sta, ftb_meta_sz),
( tage_meta_sta, tage_meta_sz),
( uftb_meta_sta, uftb_meta_sz)) = metaStartIdxWithSize.take(5)

val u_uftb_meta = io.ftq_to_bpu.update.bits.meta( uftb_meta_sta + uftb_meta_sz - 1, uftb_meta_sta).asTypeOf(new FauFTBMeta)
val u_tage_meta = io.ftq_to_bpu.update.bits.meta( tage_meta_sta + tage_meta_sz - 1, tage_meta_sta).asTypeOf(new TageMeta)
val u_ftb_meta = io.ftq_to_bpu.update.bits.meta( ftb_meta_sta + ftb_meta_sz - 1, ftb_meta_sta).asTypeOf(new FTBMeta)
val u_ittage_meta = io.ftq_to_bpu.update.bits.meta(ittage_meta_sta + ittage_meta_sz - 1, ittage_meta_sta).asTypeOf(new ITTageMeta)
val u_ras_meta = io.ftq_to_bpu.update.bits.meta( ras_meta_sta + ras_meta_sz - 1, ras_meta_sta).asTypeOf(new RASMeta)

// Update Meta of each Predictor
val new_uftb_meta = RegEnable(u_uftb_meta, io.ftq_to_bpu.update.valid)
val new_ftb_meta = RegEnable(u_ftb_meta, io.ftq_to_bpu.update.valid && !io.ftq_to_bpu.update.bits.old_entry)
val new_ras_meta = RegEnable(u_ras_meta, io.ftq_to_bpu.update.valid && (io.ftq_to_bpu.update.bits.is_call || io.ftq_to_bpu.update.bits.is_ret))

val new_ittage_meta = WireInit(0.U.asTypeOf(new ITTageMeta))
new_ittage_meta := RegEnable(u_ittage_meta, io.ftq_to_bpu.update.valid)
new_ittage_meta.provider.bits := RegEnable(u_ittage_meta.provider.bits , io.ftq_to_bpu.update.valid && u_ittage_meta.provider.valid )
new_ittage_meta.providerTarget := RegEnable(u_ittage_meta.providerTarget , io.ftq_to_bpu.update.valid && u_ittage_meta.provider.valid )
new_ittage_meta.allocate.bits := RegEnable(u_ittage_meta.allocate.bits , io.ftq_to_bpu.update.valid && u_ittage_meta.allocate.valid )
new_ittage_meta.altProvider.bits := RegEnable(u_ittage_meta.altProvider.bits , io.ftq_to_bpu.update.valid && u_ittage_meta.altProvider.valid)
new_ittage_meta.altProviderTarget := RegEnable(u_ittage_meta.altProviderTarget, io.ftq_to_bpu.update.valid && u_ittage_meta.provider.valid &&
u_ittage_meta.altProvider.valid &&
u_ittage_meta.providerCtr === 0.U)

val new_tage_meta = WireInit(0.U.asTypeOf(new TageMeta))
new_tage_meta := RegEnable(u_tage_meta, io.ftq_to_bpu.update.valid)
val u_tage_valids = VecInit((0 until TageBanks).map(w => io.ftq_to_bpu.update.bits.ftb_entry.brValids(w) && io.ftq_to_bpu.update.valid)) // ftq_to_bpu.update.bits.ftb_entry.always_taken has timing issues(FTQEntryGen)
for(i <- 0 until numBr){
new_tage_meta.providers(i).bits := RegEnable(u_tage_meta.providers(i).bits, u_tage_meta.providers(i).valid && u_tage_valids(i))
new_tage_meta.providerResps(i) := RegEnable(u_tage_meta.providerResps(i), u_tage_meta.providers(i).valid && u_tage_valids(i))
new_tage_meta.altUsed(i) := RegEnable(u_tage_meta.altUsed(i), u_tage_valids(i))
new_tage_meta.allocates(i) := RegEnable(u_tage_meta.allocates(i), io.ftq_to_bpu.update.valid && io.ftq_to_bpu.update.bits.mispred_mask(i))
}
if(EnableSC){
for(w <- 0 until TageBanks){
new_tage_meta.scMeta.get.scPreds(w) := RegEnable(u_tage_meta.scMeta.get.scPreds(w), u_tage_valids(w) && u_tage_meta.providers(w).valid)
new_tage_meta.scMeta.get.ctrs(w) := RegEnable(u_tage_meta.scMeta.get.ctrs(w), u_tage_valids(w) && u_tage_meta.providers(w).valid)
}
}

predictors.io.update.bits.meta := Cat(0.U((MaxMetaLength - metaSizeSeq.foldLeft(0)(_ + _)).W),
new_uftb_meta.asUInt,
new_tage_meta.asUInt,
new_ftb_meta.asUInt,
new_ittage_meta.asUInt,
new_ras_meta.asUInt)

// Update full_target
predictors.io.update.bits.full_target := RegEnable(io.ftq_to_bpu.update.bits.full_target,
io.ftq_to_bpu.update.valid && (u_ittage_meta.provider.valid || io.ftq_to_bpu.update.bits.mispred_mask(numBr)))

// Update cfi_idx
predictors.io.update.bits.cfi_idx.bits := RegEnable(io.ftq_to_bpu.update.bits.cfi_idx.bits,
io.ftq_to_bpu.update.valid && io.ftq_to_bpu.update.bits.cfi_idx.valid)

// Update ghist
predictors.io.update.bits.ghist := RegEnable(
getHist(io.ftq_to_bpu.update.bits.spec_info.histPtr), io.ftq_to_bpu.update.valid)

Expand Down
8 changes: 8 additions & 0 deletions src/main/scala/xiangshan/frontend/Composer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ class Composer(implicit p: Parameters) extends BasePredictor with HasBPUConst wi
metas(idx)
}

def getEachMetaSize(): Seq[Int] = {
var meta_sz: Seq[Int] = Nil
for (c <- components.reverse) {
meta_sz = meta_sz :+ c.meta_size
}
meta_sz
}

override def getFoldedHistoryInfo = Some(components.map(_.getFoldedHistoryInfo.getOrElse(Set())).reduce(_++_))

override val perfEvents = components.map(_.getPerfEvents).reduce(_++_)
Expand Down
9 changes: 4 additions & 5 deletions src/main/scala/xiangshan/frontend/FauFTB.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,12 @@ class FauFTBWay(implicit p: Parameters) extends XSModule with FauFTBParams {
}
}

class FauFTBMeta(implicit p: Parameters) extends XSBundle with FauFTBParams {
val pred_way = if (!env.FPGAPlatform) Some(UInt(log2Ceil(numWays).W)) else None
val hit = Bool()
}

class FauFTB(implicit p: Parameters) extends BasePredictor with FauFTBParams {

class FauFTBMeta(implicit p: Parameters) extends XSBundle with FauFTBParams {
val pred_way = if (!env.FPGAPlatform) Some(UInt(log2Ceil(numWays).W)) else None
val hit = Bool()
}
val resp_meta = Wire(new FauFTBMeta)
override val meta_size = resp_meta.getWidth
override val is_fast_pred = true
Expand Down
Loading