提交 dd6c0695 编写于 作者: L Lingrui98

bpu: bring folded history into use, and use previous ghr to do difftest; move...

bpu: bring folded history into use, and use previous ghr to do difftest; move tage and ittage config to top
上级 c2ad24eb
......@@ -24,7 +24,7 @@ import xiangshan.backend.decode.{ImmUnion, XDecode}
import xiangshan.mem.{LqPtr, SqPtr}
import xiangshan.frontend.PreDecodeInfo
import xiangshan.frontend.HasBPUParameter
import xiangshan.frontend.{GlobalHistory, ShiftingGlobalHistory, CircularGlobalHistory}
import xiangshan.frontend.{GlobalHistory, ShiftingGlobalHistory, CircularGlobalHistory, AllFoldedHistories}
import xiangshan.frontend.RASEntry
import xiangshan.frontend.BPUCtrl
import xiangshan.frontend.FtqPtr
......@@ -39,6 +39,7 @@ import chipsalliance.rocketchip.config.Parameters
import chisel3.util.BitPat.bitPatToUInt
import xiangshan.backend.fu.PMPEntry
import xiangshan.frontend.Ftq_Redirect_SRAMEntry
import xiangshan.frontend.AllFoldedHistories
class ValidUndirectioned[T <: Data](gen: T) extends Bundle {
val valid = Bool()
......@@ -77,6 +78,7 @@ class CfiUpdateInfo(implicit p: Parameters) extends XSBundle with HasBPUParamete
val rasSp = UInt(log2Up(RasSize).W)
val rasEntry = new RASEntry
// val hist = new ShiftingGlobalHistory
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val histPtr = new CGHPtr
val phist = UInt(PathHistoryLength.W)
val specCnt = Vec(numBr, UInt(10.W))
......@@ -92,6 +94,7 @@ class CfiUpdateInfo(implicit p: Parameters) extends XSBundle with HasBPUParamete
def fromFtqRedirectSram(entry: Ftq_Redirect_SRAMEntry) = {
// this.hist := entry.ghist
this.folded_hist := entry.folded_hist
this.histPtr := entry.histPtr
this.phist := entry.phist
this.phNewBit := entry.phNewBit
......
......@@ -28,6 +28,7 @@ import xiangshan.frontend.{BIM, BasePredictor, BranchPredictionResp, FTB, FakePr
import xiangshan.cache.mmu.{TLBParameters, L2TLBParameters}
import freechips.rocketchip.diplomacy.AddressSet
import system.SoCParamsKey
import scala.math.min
case object XSTileKey extends Field[Seq[XSCoreParameters]]
......@@ -67,6 +68,27 @@ case class XSCoreParameters
CacheLineSize: Int = 512,
UBtbWays: Int = 16,
BtbWays: Int = 2,
TageTableInfos: Seq[Tuple3[Int,Int,Int]] =
// Sets Hist Tag
Seq(( 128*8, 2, 7),
( 128*8, 4, 7),
( 256*8, 8, 8),
( 256*8, 16, 8),
( 128*8, 32, 9),
( 128*8, 64, 9)),
ITTageTableInfos: Seq[Tuple3[Int,Int,Int]] =
// Sets Hist Tag
Seq(( 512, 0, 0),
( 512, 2, 7),
( 512, 4, 7),
( 512, 8, 8),
( 512, 16, 8),
( 512, 32, 9),
( 512, 64, 9)),
SCNRows: Int = 1024,
SCNTables: Int = 6,
SCCtrBits: Int = 6,
numBr: Int = 2,
branchPredictor: Function2[BranchPredictionResp, Parameters, Tuple2[Seq[BasePredictor], BranchPredictionResp]] =
((resp_in: BranchPredictionResp, p: Parameters) => {
// val loop = Module(new LoopPredictor)
......@@ -282,6 +304,43 @@ trait HasXSParameter {
def getBPDComponents(resp_in: BranchPredictionResp, p: Parameters) = {
coreParams.branchPredictor(resp_in, p)
}
val numBr = coreParams.numBr
val TageTableInfos = coreParams.TageTableInfos
val BankTageTableInfos = (0 until numBr).map(i =>
TageTableInfos.map{ case (s, h, t) => (s/(1 << i), h, t) }
)
val SCNRows = coreParams.SCNRows
val SCCtrBits = coreParams.SCCtrBits
val BankSCHistLens = BankTageTableInfos.map(info => 0 :: info.map{ case (_,h,_) => h}.toList)
val BankSCNTables = Seq.fill(numBr)(coreParams.SCNTables)
val BankSCTableInfos = (BankSCNTables zip BankSCHistLens).map {
case (ntable, histlens) =>
Seq.fill(ntable)((SCNRows, SCCtrBits)) zip histlens map {case ((n, cb), h) => (n, cb, h)}
}
val ITTageTableInfos = coreParams.ITTageTableInfos
type FoldedHistoryInfo = Tuple2[Int, Int]
val foldedGHistInfos =
(BankTageTableInfos.flatMap(_.map{ case (nRows, h, t) =>
if (h > 0)
Set((h, min(log2Ceil(nRows), h)), (h, min(h, t)), (h, min(h, t-1)))
else
Set[FoldedHistoryInfo]()
}.reduce(_++_)).toSet ++
BankSCTableInfos.flatMap(_.map{ case (nRows, _, h) =>
if (h > 0)
Set((h, min(log2Ceil(nRows), h)))
else
Set[FoldedHistoryInfo]()
}.reduce(_++_)).toSet ++
ITTageTableInfos.map{ case (nRows, h, t) =>
if (h > 0)
Set((h, min(log2Ceil(nRows), h)), (h, min(h, t)), (h, min(h, t-1)))
else
Set[FoldedHistoryInfo]()
}.reduce(_++_)).toList
val CacheLineSize = coreParams.CacheLineSize
val CacheLineHalfWord = CacheLineSize / 16
......
......@@ -25,17 +25,17 @@ import utils._
import scala.math.min
trait HasBPUConst extends HasXSParameter with HasIFUConst {
trait HasBPUConst extends HasXSParameter {
val MaxMetaLength = 1024 // TODO: Reduce meta length
val MaxBasicBlockSize = 32
val LHistoryLength = 32
val numBr = 2
// val numBr = 2
val useBPD = true
val useLHist = true
val shareTailSlot = true
val numBrSlot = if (shareTailSlot) numBr-1 else numBr
val totalSlot = numBrSlot + 1
def BP_STAGES = (0 until 3).map(_.U(2.W))
def BP_S1 = BP_STAGES(0)
def BP_S2 = BP_STAGES(1)
......@@ -140,15 +140,64 @@ trait BPUUtils extends HasXSParameter {
// def taken = cfi_idx.valid
// }
class AllFoldedHistories(val gen: Seq[Tuple2[Int, Int]])(implicit p: Parameters) extends XSBundle with HasBPUConst {
val hist = MixedVec(gen.map{case (l, cl) => new FoldedHistory(l, cl, numBr)})
// println(gen.mkString)
require(gen.toSet.toList.equals(gen))
def getHistWithInfo(info: Tuple2[Int, Int]) = {
val selected = hist.filter(_.info.equals(info))
require(selected.length == 1)
selected(0)
}
def autoConnectFrom(that: AllFoldedHistories) = {
require(this.hist.length <= that.hist.length)
for (h <- this.hist) {
h := that.getHistWithInfo(h.info)
}
}
def update(ghr: Vec[Bool], ptr: CGHPtr, shift: UInt, taken: Bool): AllFoldedHistories = {
val res = WireInit(this)
for (i <- 0 until this.hist.length) {
res.hist(i) := this.hist(i).update(ghr, ptr, shift, taken)
}
res
}
def update(ghr: Vec[Bool], ptr: CGHPtr, br_valids: Vec[Bool], br_takens: Vec[Bool]): AllFoldedHistories = {
val last_valid_idx = PriorityMux(
br_valids.reverse :+ true.B,
(numBr to 0 by -1).map(_.U(log2Ceil(numBr+1).W))
)
val first_taken_idx = PriorityEncoder(false.B +: br_takens)
val smaller = Mux(last_valid_idx < first_taken_idx,
last_valid_idx,
first_taken_idx
)
val shift = smaller
val taken = br_takens.reduce(_||_)
update(ghr, ptr, shift, taken)
}
def update(ghr: Vec[Bool], ptr: CGHPtr, resp: BranchPredictionBundle): AllFoldedHistories = {
update(ghr, ptr, resp.preds.br_valids, resp.real_br_taken_mask)
}
def display(cond: Bool) = {
for (h <- hist) {
XSDebug(cond, p"hist len ${h.len}, folded len ${h.compLen}, value ${Binary(h.folded_hist)}\n")
}
}
}
class BasePredictorInput (implicit p: Parameters) extends XSBundle with HasBPUConst {
def nInputs = 1
val s0_pc = UInt(VAddrBits.W)
val ghist = UInt(HistoryLength.W)
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val phist = UInt(PathHistoryLength.W)
val resp_in = Vec(nInputs, new BranchPredictionResp)
// val final_preds = Vec(numBpStages, new)
// val toFtq_fire = Bool()
// val s0_all_ready = Bool()
......@@ -188,7 +237,6 @@ class BasePredictorIO (implicit p: Parameters) extends XSBundle with HasBPUConst
abstract class BasePredictor(implicit p: Parameters) extends XSModule with HasBPUConst with BPUUtils {
val meta_size = 0
val spec_meta_size = 0
val io = IO(new BasePredictorIO())
io.out.resp := io.in.bits.resp_in(0)
......@@ -205,6 +253,9 @@ abstract class BasePredictor(implicit p: Parameters) extends XSModule with HasBP
val s1_pc = RegEnable(s0_pc, resetVector.U, io.s0_fire)
val s2_pc = RegEnable(s1_pc, io.s1_fire)
val s3_pc = RegEnable(s2_pc, io.s2_fire)
def getFoldedHistoryInfo: Option[Set[FoldedHistoryInfo]] = None
}
class FakePredictor(implicit p: Parameters) extends BasePredictor {
......@@ -250,6 +301,11 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
val predictors = Module(if (useBPD) new Composer else new FakePredictor)
val folded_hist_infos = predictors.getFoldedHistoryInfo.getOrElse(Set()).toList
for ((len, compLen) <- folded_hist_infos) {
println(f"folded hist info: len $len, compLen $compLen")
}
val s0_fire, s1_fire, s2_fire, s3_fire = Wire(Bool())
val s1_valid, s2_valid, s3_valid = RegInit(false.B)
val s1_ready, s2_ready, s3_ready = Wire(Bool())
......@@ -267,6 +323,11 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
// val s2_ghist = RegEnable(s1_ghist, 0.U.asTypeOf(new ShiftingGlobalHistory), s1_fire)
// val s3_ghist = RegEnable(s2_ghist, 0.U.asTypeOf(new ShiftingGlobalHistory), s2_fire)
val s0_folded_gh = Wire(new AllFoldedHistories(foldedGHistInfos))
val s0_folded_gh_reg = RegNext(s0_folded_gh, init=0.U.asTypeOf(s0_folded_gh))
val s1_folded_gh = RegEnable(s0_folded_gh, 0.U.asTypeOf(s0_folded_gh), s0_fire)
val s2_folded_gh = RegEnable(s1_folded_gh, 0.U.asTypeOf(s0_folded_gh), s1_fire)
val s3_folded_gh = RegEnable(s2_folded_gh, 0.U.asTypeOf(s0_folded_gh), s2_fire)
val ghr = RegInit(0.U.asTypeOf(Vec(HistoryLength, Bool())))
val ghr_wire = WireInit(ghr)
......@@ -325,6 +386,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
when(RegNext(reset.asBool) && !reset.asBool) {
// s0_ghist := 0.U.asTypeOf(new ShiftingGlobalHistory)
s0_folded_gh := 0.U.asTypeOf(s0_folded_gh)
s0_ghist_ptr := 0.U.asTypeOf(new CGHPtr)
s0_phist := 0.U
s0_pc := resetVector.U
......@@ -347,6 +409,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
predictors.io.in.valid := s0_fire
predictors.io.in.bits.s0_pc := s0_pc
predictors.io.in.bits.ghist := s0_ghist
predictors.io.in.bits.folded_hist := s0_folded_gh
predictors.io.in.bits.phist := s0_phist
predictors.io.in.bits.resp_in(0) := (0.U).asTypeOf(new BranchPredictionResp)
// predictors.io.in.bits.resp_in(0).s1.pc := s0_pc
......@@ -403,11 +466,13 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
io.bpu_to_ftq.resp.bits := BpuToFtqBundle(predictors.io.out.resp)
io.bpu_to_ftq.resp.bits.meta := predictors.io.out.s3_meta
// io.bpu_to_ftq.resp.bits.s3.ghist := s3_ghist
io.bpu_to_ftq.resp.bits.s3.folded_hist := s3_folded_gh
io.bpu_to_ftq.resp.bits.s3.histPtr := s3_ghist_ptr
io.bpu_to_ftq.resp.bits.s3.phist := s3_phist
s0_pc := s0_pc_reg
// s0_ghist := s0_ghist_reg
s0_folded_gh := s0_folded_gh_reg
s0_ghist_ptr := s0_ghist_ptr_reg
s0_phist := s0_phist_reg
s0_last_pred := s0_last_pred_reg
......@@ -421,6 +486,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
s1_predicted_ghist(i) := resp.s1.real_br_taken_mask.reduce(_||_) && (i==0).B
}
}
val s1_predicted_fh = s1_folded_gh.update(ghr, s1_ghist_ptr, resp.s1)
// XSDebug(p"[hit] ${resp.s1.preds.hit} [s1_real_br_taken_mask] ${Binary(resp.s1.real_br_taken_mask.asUInt)}\n")
......@@ -429,6 +495,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
when(s1_valid) {
s0_pc := resp.s1.target
s0_ghist := s1_predicted_ghist.asUInt
s0_folded_gh := s1_predicted_fh
ghist_update(s1_ghist_ptr, resp.s1)
s0_ghist_ptr := s1_predicted_ghist_ptr
s0_phist := (s1_phist << 1) | s1_pc(instOffsetBits)
......@@ -448,6 +515,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
s2_predicted_ghist(i) := resp.s2.real_br_taken_mask.reduce(_||_) && (i==0).B
}
}
val s2_predicted_fh = s2_folded_gh.update(ghr, s2_ghist_ptr, resp.s2)
val previous_s1_pred = RegEnable(resp.s1, init=0.U.asTypeOf(resp.s1), s1_fire)
val s2_redirect_s1_last_pred = preds_needs_redirect(s1_last_pred, resp.s2)
......@@ -457,6 +525,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
when((s1_valid && (s1_pc =/= resp.s2.target || s2_redirect_s1_last_pred)) ||
!s1_valid && (s0_pc_reg =/= resp.s2.target || s2_redirect_s0_last_pred)) {
s0_ghist := s2_predicted_ghist.asUInt
s0_folded_gh := s2_predicted_fh
s0_ghist_ptr := s2_predicted_ghist_ptr
ghist_update(s2_ghist_ptr, resp.s2)
s2_redirect := true.B
......@@ -492,6 +561,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
s3_predicted_ghist(i) := resp.s3.real_br_taken_mask.reduce(_||_) && (i==0).B
}
}
val s3_predicted_fh = s3_folded_gh.update(ghr, s3_ghist_ptr, resp.s3)
val s3_redirect_s2_last_pred = preds_needs_redirect(s2_last_pred, resp.s3)
val s3_redirect_s1_last_pred = preds_needs_redirect(s1_last_pred, resp.s3)
val s3_redirect_s0_last_pred = preds_needs_redirect(s0_last_pred_reg, resp.s3)
......@@ -502,6 +572,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
(!s2_valid && !s1_valid && (s0_pc_reg =/= resp.s3.target || s3_redirect_s0_last_pred))) {
s0_ghist := s3_predicted_ghist.asUInt
s0_folded_gh := s3_predicted_fh
s0_ghist_ptr := s3_predicted_ghist_ptr
ghist_update(s3_ghist_ptr, resp.s3)
s3_redirect := true.B
......@@ -540,15 +611,18 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
val taken = redirect.cfiUpdate.taken
val oldPtr = redirect.cfiUpdate.histPtr
val oldFh = redirect.cfiUpdate.folded_hist
val updated_ptr = oldPtr - shift
val updated_ghist = WireInit(getHist(updated_ptr).asTypeOf(Vec(HistoryLength, Bool())))
val updated_fh = oldFh.update(ghr, oldPtr, shift, taken && addIntoHist)
for (i <- 0 until numBr) {
when (shift > 0.U) {
updated_ghist(i) := taken && (i==0).B
when (shift >= (i+1).U) {
updated_ghist(i) := taken && addIntoHist && (i==0).B
}
}
// val updatedGh = oldGh.update(shift, taken && addIntoHist)
s0_ghist := updated_ghist.asUInt // TODO: History fix logic
s0_folded_gh := updated_fh
ghist_update(oldPtr, shift, taken && addIntoHist)
s0_ghist_ptr := updated_ptr
s0_pc := redirect.cfiUpdate.target
......@@ -588,7 +662,10 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst {
// XSDebug("s3_predicted_ghist: %b\n", s3_predicted_ghist.predHist)
// XSDebug("s3_correct_s2_ghist: %b, s3_correct_s1_ghist: %b, s2_correct_s1_ghist: %b\n",
// s3_correct_s2_ghist, s3_correct_s1_ghist, s2_correct_s1_ghist)
XSDebug(p"s0_ghist_ptr: $s0_ghist_ptr\n")
XSDebug(p"s1_ghist_ptr: $s1_ghist_ptr\n")
XSDebug(p"s2_ghist_ptr: $s2_ghist_ptr\n")
XSDebug(p"s3_ghist_ptr: $s3_ghist_ptr\n")
io.ftq_to_bpu.update.bits.display(io.ftq_to_bpu.update.valid)
io.ftq_to_bpu.redirect.bits.display(io.ftq_to_bpu.redirect.valid)
......
......@@ -31,10 +31,11 @@ class Composer(implicit p: Parameters) extends BasePredictor with HasBPUConst {
var metas = 0.U(1.W)
var meta_sz = 0
for (c <- components) {
c.io.in.valid := io.in.valid
c.io.in.bits.s0_pc := io.in.bits.s0_pc
c.io.in.bits.ghist := io.in.bits.ghist
c.io.in.bits.phist := io.in.bits.phist
c.io.in.valid := io.in.valid
c.io.in.bits.s0_pc := io.in.bits.s0_pc
c.io.in.bits.ghist := io.in.bits.ghist
c.io.in.bits.folded_hist := io.in.bits.folded_hist
c.io.in.bits.phist := io.in.bits.phist
c.io.s0_fire := io.s0_fire
c.io.s1_fire := io.s1_fire
......@@ -75,6 +76,8 @@ class Composer(implicit p: Parameters) extends BasePredictor with HasBPUConst {
metas(idx)
}
override def getFoldedHistoryInfo = Some(components.map(_.getFoldedHistoryInfo.getOrElse(Set())).reduce(_++_))
val comp_1_perf = components(1).asInstanceOf[MicroBTB].perfEvents.map(_._1).zip(components(1).asInstanceOf[MicroBTB].perfinfo.perfEvents.perf_events)
val comp_2_perf = components(2).asInstanceOf[Tage_SC].perfEvents.map(_._1).zip(components(2).asInstanceOf[Tage_SC].perfinfo.perfEvents.perf_events)
val comp_3_perf = components(3).asInstanceOf[FTB].perfEvents.map(_._1).zip(components(3).asInstanceOf[FTB].perfinfo.perfEvents.perf_events)
......
......@@ -155,23 +155,23 @@ class CircularGlobalHistory(implicit p: Parameters) extends GlobalHistory {
}
}
class FoldedHistory(val len: Int, val folded_len: Int, val max_update_num: Int)(implicit p: Parameters)
class FoldedHistory(val len: Int, val compLen: Int, val max_update_num: Int)(implicit p: Parameters)
extends XSBundle with HasBPUConst {
require(folded_len >= 1)
require(compLen >= 1)
require(len > 0)
// require(folded_len <= len)
require(folded_len >= max_update_num)
def compLen = len.min(folded_len)
require(max_update_num <= compLen)
val folded_hist = UInt(compLen.W) // TODO: min(len, folded_len)
require(compLen >= max_update_num)
val folded_hist = UInt(compLen.W)
def info = (len, compLen)
def oldest_bit_to_get_from_ghr = (0 until max_update_num).map(len - _ - 1)
def oldest_bit_pos_in_folded = oldest_bit_to_get_from_ghr map (_ % compLen)
def oldest_bit_wrap_around = oldest_bit_to_get_from_ghr map (_ / compLen > 0)
def oldest_bit_start = oldest_bit_pos_in_folded.head
def get_oldest_bits_from_ghr(ghr: UInt, histPtr: UInt) = {
def get_oldest_bits_from_ghr(ghr: Vec[Bool], histPtr: CGHPtr) = {
// TODO: wrap inc for histPtr value
oldest_bit_to_get_from_ghr.map(i => ghr(histPtr + i.U))
oldest_bit_to_get_from_ghr.map(i => ghr((histPtr + (i+1).U).value))
}
def circular_shift_left(max_shift_value: Int)(src: UInt, shamt: UInt) = {
......@@ -184,7 +184,7 @@ class FoldedHistory(val len: Int, val folded_len: Int, val max_update_num: Int)(
}
def update_folded_hist(num: UInt, taken: Bool, oldest_bits: Seq[Bool]): FoldedHistory = {
def update(ghr: Vec[Bool], histPtr: CGHPtr, num: UInt, taken: Bool): FoldedHistory = {
// do xors for several bitsets at specified bits
def bitsets_xor(len: Int, bitsets: Seq[Seq[Tuple2[Int, Bool]]]) = {
val res = Wire(Vec(len, Bool()))
......@@ -202,16 +202,16 @@ class FoldedHistory(val len: Int, val folded_len: Int, val max_update_num: Int)(
// println(f"bit[$i], ${resArr(i).mkString}")
if (resArr(i).length > 2) {
println(f"[warning] update logic of foldest history has two or more levels of xor gates! " +
f"histlen:${this.len}, foldedLen:$folded_len")
f"histlen:${this.len}, compLen:$compLen")
}
if (resArr(i).length == 0) {
println(f"[error] bits $i is not assigned in folded hist update logic! histlen:${this.len}, foldedLen:$folded_len")
println(f"[error] bits $i is not assigned in folded hist update logic! histlen:${this.len}, compLen:$compLen")
}
res(i) := resArr(i).foldLeft(false.B)(_^_)
}
res.asUInt
}
val oldest_bits = get_oldest_bits_from_ghr(ghr, histPtr)
// mask off bits that do not update
val oldest_bits_masked = oldest_bits.zipWithIndex.map{
......@@ -237,8 +237,8 @@ class FoldedHistory(val len: Int, val folded_len: Int, val max_update_num: Int)(
// histLen too short to wrap around
val new_folded_hist =
if (len <= folded_len) {
(Cat(folded_hist, newest_bits_masked) << num)(compLen-1,0)
if (len <= compLen) {
((folded_hist << num) | taken)(compLen-1,0)
// circular_shift_left(max_update_num)(Cat(Reverse(newest_bits_masked), folded_hist(compLen-max_update_num-1,0)), num)
} else {
// do xor then shift
......@@ -250,23 +250,22 @@ class FoldedHistory(val len: Int, val folded_len: Int, val max_update_num: Int)(
fh
}
def update(valids: Vec[Bool], takens: Vec[Bool], ghr: UInt, histPtr: UInt): FoldedHistory = {
val fh = WireInit(this)
require(valids.length == max_update_num)
require(takens.length == max_update_num)
val last_valid_idx = PriorityMux(
valids.reverse :+ true.B,
(max_update_num to 0 by -1).map(_.U(log2Ceil(max_update_num+1).W))
)
val first_taken_idx = PriorityEncoder(false.B +: takens)
val smaller = Mux(last_valid_idx < first_taken_idx,
last_valid_idx,
first_taken_idx
)
val oldest_bits = get_oldest_bits_from_ghr(ghr, histPtr)
// update folded_hist
fh.update_folded_hist(smaller, takens.reduce(_||_), oldest_bits)
}
// def update(ghr: Vec[Bool], histPtr: CGHPtr, valids: Vec[Bool], takens: Vec[Bool]): FoldedHistory = {
// val fh = WireInit(this)
// require(valids.length == max_update_num)
// require(takens.length == max_update_num)
// val last_valid_idx = PriorityMux(
// valids.reverse :+ true.B,
// (max_update_num to 0 by -1).map(_.U(log2Ceil(max_update_num+1).W))
// )
// val first_taken_idx = PriorityEncoder(false.B +: takens)
// val smaller = Mux(last_valid_idx < first_taken_idx,
// last_valid_idx,
// first_taken_idx
// )
// // update folded_hist
// fh.update(ghr, histPtr, smaller, takens.reduce(_||_))
// }
// println(f"folded hist original length: ${len}, folded len: ${folded_len} " +
// f"oldest bits' pos in folded: ${oldest_bit_pos_in_folded}")
......@@ -365,6 +364,7 @@ class BranchPredictionBundle(implicit p: Parameters) extends XSBundle with HasBP
val preds = new BranchPrediction
// val ghist = new ShiftingGlobalHistory()
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val histPtr = new CGHPtr
val phist = UInt(PathHistoryLength.W)
val rasSp = UInt(log2Ceil(RasSize).W)
......@@ -437,6 +437,7 @@ class BranchPredictionBundle(implicit p: Parameters) extends XSBundle with HasBP
def display(cond: Bool): Unit = {
XSDebug(cond, p"[pc] ${Hexadecimal(pc)}\n")
// XSDebug(cond, p"[ghist] ${Binary(ghist.predHist)}\n")
folded_hist.display(cond)
preds.display(cond)
ftb_entry.display(cond)
}
......@@ -491,6 +492,7 @@ class BranchPredictionUpdate(implicit p: Parameters) extends BranchPredictionBun
def fromFtqRedirectSram(entry: Ftq_Redirect_SRAMEntry) = {
// ghist := entry.ghist
folded_hist := entry.folded_hist
histPtr := entry.histPtr
phist := entry.phist
rasSp := entry.rasSp
......
......@@ -32,21 +32,8 @@ import scala.util.matching.Regex
import firrtl.passes.wiring.Wiring
trait ITTageParams extends HasXSParameter with HasBPUParameter {
// Sets Hist Tag
val TableInfo = Seq(( 512, 0, 0),
( 512, 2, 7),
( 512, 4, 7),
( 512, 8, 8),
( 512, 16, 8),
( 512, 32, 9),
( 512, 64, 9))
// ( 64, 64, 11),
// ( 64, 101, 12),
// ( 64, 160, 12),
// ( 64, 254, 13),
// ( 32, 403, 14),
// ( 32, 640, 15))
val ITTageNTables = TableInfo.size // Number of tage tables
val ITTageNTables = ITTageTableInfos.size // Number of tage tables
val UBitPeriod = 2048
val ITTageCtrBits = 2
def ctr_null(ctr: UInt, ctrBits: Int = ITTageCtrBits) = {
......@@ -57,7 +44,7 @@ trait ITTageParams extends HasXSParameter with HasBPUParameter {
}
val UAONA_bits = 4
val TotalBits = TableInfo.map {
val TotalBits = ITTageTableInfos.map {
case (s, h, t) => {
s * (1+t+ITTageCtrBits+VAddrBits)
}
......@@ -92,6 +79,7 @@ abstract class ITTageModule(implicit p: Parameters)
class ITTageReq(implicit p: Parameters) extends ITTageBundle {
val pc = UInt(VAddrBits.W)
val hist = UInt(HistoryLength.W)
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val phist = UInt(PathHistoryLength.W)
}
......@@ -104,6 +92,7 @@ class ITTageResp(implicit p: Parameters) extends ITTageBundle {
class ITTageUpdate(implicit p: Parameters) extends ITTageBundle {
val pc = UInt(VAddrBits.W)
val hist = UInt(HistoryLength.W)
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val phist = UInt(PathHistoryLength.W)
// update tag and ctr
val valid = Bool()
......@@ -169,19 +158,43 @@ class ITTageTable
val wrBypassEntries = 4
val phistLen = if (PathHistoryLength > histLen) histLen else PathHistoryLength
def compute_tag_and_hash(unhashed_idx: UInt, hist: UInt, phist: UInt) = {
val idx_history = compute_folded_ghist(hist, log2Ceil(nRows))
// val idx = (unhashed_idx ^ (unhashed_idx >> (log2Ceil(nRows)-tableIdx+1)) ^ idx_history ^ idx_phist)(log2Ceil(nRows) - 1, 0)
val idx = (unhashed_idx ^ idx_history)(log2Ceil(nRows) - 1, 0)
val tag_history = compute_folded_ghist(hist, tagLen)
val alt_tag_history = compute_folded_ghist(hist, tagLen-1)
// Use another part of pc to make tags
val tag = (
if (tagLen > 1)
((unhashed_idx >> log2Ceil(nRows)) ^ tag_history ^ (alt_tag_history << 1)) (tagLen - 1, 0)
else 0.U
)
(idx, tag)
// def compute_tag_and_hash(unhashed_idx: UInt, hist: UInt, phist: UInt) = {
// val idx_history = compute_folded_ghist(hist, log2Ceil(nRows))
// // val idx = (unhashed_idx ^ (unhashed_idx >> (log2Ceil(nRows)-tableIdx+1)) ^ idx_history ^ idx_phist)(log2Ceil(nRows) - 1, 0)
// val idx = (unhashed_idx ^ idx_history)(log2Ceil(nRows) - 1, 0)
// val tag_history = compute_folded_ghist(hist, tagLen)
// val alt_tag_history = compute_folded_ghist(hist, tagLen-1)
// // Use another part of pc to make tags
// val tag = (
// if (tagLen > 1)
// ((unhashed_idx >> log2Ceil(nRows)) ^ tag_history ^ (alt_tag_history << 1)) (tagLen - 1, 0)
// else 0.U
// )
// (idx, tag)
// }
require(histLen == 0 && tagLen == 0 || histLen != 0 && tagLen != 0)
val idxFhInfo = (histLen, min(log2Ceil(nRows), histLen))
val tagFhInfo = (histLen, min(histLen, tagLen))
val altTagFhInfo = (histLen, min(histLen, tagLen-1))
val allFhInfos = Seq(idxFhInfo, tagFhInfo, altTagFhInfo)
def getFoldedHistoryInfo = allFhInfos.filter(_._1 >0).toSet
def compute_tag_and_hash(unhashed_idx: UInt, allFh: AllFoldedHistories) = {
if (histLen > 0) {
val idx_fh = allFh.getHistWithInfo(idxFhInfo).folded_hist
val tag_fh = allFh.getHistWithInfo(tagFhInfo).folded_hist
val alt_tag_fh = allFh.getHistWithInfo(altTagFhInfo).folded_hist
// require(idx_fh.getWidth == log2Ceil(nRows))
val idx = (unhashed_idx ^ idx_fh)(log2Ceil(nRows)-1, 0)
val tag = ((unhashed_idx >> log2Ceil(nRows)) ^ tag_fh ^ (alt_tag_fh << 1)) (tagLen - 1, 0)
(idx, tag)
}
else {
require(tagLen == 0)
(unhashed_idx(log2Ceil(nRows)-1, 0), 0.U)
}
}
def inc_ctr(ctr: UInt, taken: Bool): UInt = satUpdate(ctr, ITTageCtrBits, taken)
......@@ -203,7 +216,8 @@ class ITTageTable
val s0_pc = io.req.bits.pc
val s0_unhashed_idx = getUnhashedIdx(io.req.bits.pc)
val (s0_idx, s0_tag) = compute_tag_and_hash(s0_unhashed_idx, io.req.bits.hist, io.req.bits.phist)
// val (s0_idx, s0_tag) = compute_tag_and_hash(s0_unhashed_idx, io.req.bits.hist, io.req.bits.phist)
val (s0_idx, s0_tag) = compute_tag_and_hash(s0_unhashed_idx, io.req.bits.folded_hist)
val (s1_idx, s1_tag) = (RegEnable(s0_idx, io.req.valid), RegEnable(s0_tag, io.req.valid))
val hi_us = Module(new Folded1WDataModuleTemplate(Bool(), nRows, numRead=1, isSync=true, width=8))
......@@ -243,7 +257,8 @@ class ITTageTable
val clear_u_idx = clear_u_ctr >> log2Ceil(uBitPeriod)
// Use fetchpc to compute hash
val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.hist, io.update.phist)
// val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.hist, io.update.phist)
val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.folded_hist)
val update_target = io.update.target
val update_wdata = Wire(new ITTageEntry)
......@@ -415,7 +430,7 @@ class FakeITTage(implicit p: Parameters) extends BaseITTage {
class ITTage(implicit p: Parameters) extends BaseITTage {
override val meta_size = 0.U.asTypeOf(new ITTageMeta).getWidth
val tables = TableInfo.zipWithIndex.map {
val tables = ITTageTableInfos.zipWithIndex.map {
case ((nRows, histLen, tagLen), i) =>
// val t = if(EnableBPD) Module(new TageTable(nRows, histLen, tagLen, UBitPeriod)) else Module(new FakeTageTable)
val t = Module(new ITTageTable(nRows, histLen, tagLen, UBitPeriod, i))
......@@ -427,9 +442,11 @@ class ITTage(implicit p: Parameters) extends BaseITTage {
t.io.req.valid := io.s0_fire
t.io.req.bits.pc := s0_pc
t.io.req.bits.hist := io.in.bits.ghist
t.io.req.bits.folded_hist := io.in.bits.folded_hist
t.io.req.bits.phist := io.in.bits.phist
t
}
override def getFoldedHistoryInfo = Some(tables.map(_.getFoldedHistoryInfo).reduce(_++_))
val useAltOnNa = RegInit((1 << (UAONA_bits-1)).U(UAONA_bits.W))
......@@ -496,6 +513,7 @@ class ITTage(implicit p: Parameters) extends BaseITTage {
!(update.real_br_taken_mask().reduce(_||_))
val updateHist = update.ghist
val updatePhist = update.phist
val updateFhist = update.folded_hist
// meta is splited by composer
val updateMeta = update.meta.asTypeOf(new ITTageMeta)
......@@ -692,6 +710,7 @@ class ITTage(implicit p: Parameters) extends BaseITTage {
// use fetch pc instead of instruction pc
tables(i).io.update.hist := RegNext(updateHist.predHist)
tables(i).io.update.phist := RegNext(updatePhist)
tables(i).io.update.folded_hist := RegNext(updateFhist)
}
// Debug and perf info
......
......@@ -146,6 +146,7 @@ class Ftq_Redirect_SRAMEntry(implicit p: Parameters) extends XSBundle with HasBP
val rasEntry = new RASEntry
val specCnt = Vec(numBr, UInt(10.W))
// val ghist = new ShiftingGlobalHistory
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val histPtr = new CGHPtr
val phist = UInt(PathHistoryLength.W)
val phNewBit = UInt(1.W)
......@@ -155,6 +156,7 @@ class Ftq_Redirect_SRAMEntry(implicit p: Parameters) extends XSBundle with HasBP
this.rasEntry := resp.rasTop
this.specCnt := resp.specCnt
// this.ghist := resp.ghist
this.folded_hist := resp.folded_hist
this.histPtr := resp.histPtr
this.phist := resp.phist
this.phNewBit := resp.pc(instOffsetBits)
......
......@@ -26,14 +26,6 @@ import chisel3.experimental.chiselName
import scala.math.min
trait HasSCParameter extends TageParams {
val BankSCHistLens = BankTableInfos.map(info => 0 :: info.map{ case (_,h,_) => h}.toList)
val BankSCNTables = List(6, 6)
val SCCtrBits = 6
val SCNRows = 1024
val BankSCTableInfos = (BankSCNTables zip BankSCHistLens).map {
case (ntable, histlens) =>
Seq.fill(ntable)((SCNRows, SCCtrBits)) zip histlens map {case ((n, cb), h) => (n, cb, h)}
}
}
class SCReq(implicit p: Parameters) extends TageReq
......@@ -58,6 +50,7 @@ class SCResp(val ctrBits: Int = 6)(implicit p: Parameters) extends SCBundle {
class SCUpdate(val ctrBits: Int = 6)(implicit p: Parameters) extends SCBundle {
val pc = UInt(VAddrBits.W)
val hist = UInt(HistoryLength.W)
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val mask = Bool()
val oldCtr = SInt(ctrBits.W)
val tagePred = Bool()
......@@ -79,13 +72,29 @@ class SCTable(val nRows: Int, val ctrBits: Int, val histLen: Int)(implicit p: Pa
val table = Module(new SRAMTemplate(SInt(ctrBits.W), set=nRows, way=2, shouldReset=true, holdRead=true, singlePort=false))
val phistLen = PathHistoryLength
def getIdx(hist: UInt, pc: UInt) = {
(compute_folded_ghist(hist, log2Ceil(nRows)) ^ (pc >> instOffsetBits))(log2Ceil(nRows)-1,0)
// def getIdx(hist: UInt, pc: UInt) = {
// (compute_folded_ghist(hist, log2Ceil(nRows)) ^ (pc >> instOffsetBits))(log2Ceil(nRows)-1,0)
// }
val idxFhInfo = (histLen, min(log2Ceil(nRows), histLen))
def getFoldedHistoryInfo = Set(idxFhInfo).filter(_._1 > 0)
def getIdx(pc: UInt, allFh: AllFoldedHistories) = {
if (histLen > 0) {
val idx_fh = allFh.getHistWithInfo(idxFhInfo).folded_hist
// require(idx_fh.getWidth == log2Ceil(nRows))
((pc >> instOffsetBits) ^ idx_fh)(log2Ceil(nRows)-1,0)
}
else {
pc(log2Ceil(nRows)-1,0)
}
}
def ctrUpdate(ctr: SInt, cond: Bool): SInt = signedSatUpdate(ctr, ctrBits, cond)
val s0_idx = getIdx(io.req.bits.hist, io.req.bits.pc)
val s0_idx = getIdx(io.req.bits.pc, io.req.bits.folded_hist)
val s1_idx = RegEnable(s0_idx, enable=io.req.valid)
table.io.r.req.valid := io.req.valid
......@@ -97,7 +106,7 @@ class SCTable(val nRows: Int, val ctrBits: Int, val histLen: Int)(implicit p: Pa
val updateWayMask =
VecInit((0 to 1).map(io.update.mask && _.U === io.update.tagePred.asUInt)).asUInt
val update_idx = getIdx(io.update.hist, io.update.pc)
val update_idx = getIdx(io.update.pc, io.update.folded_hist)
table.io.w.apply(
valid = io.update.mask,
......@@ -170,23 +179,21 @@ class SCTable(val nRows: Int, val ctrBits: Int, val histLen: Int)(implicit p: Pa
wrbypass.io.update_ctrPos := ctrPos
wrbypass.io.update_altPos := altPos
if (BPUDebug && debug) {
val u = io.update
XSDebug(io.req.valid,
p"scTableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, " +
p"s0_idx=${s0_idx}, hist=${Hexadecimal(io.req.bits.hist)}\n")
XSDebug(RegNext(io.req.valid),
p"scTableResp: s1_idx=${s1_idx}," +
p"ctr:${io.resp.ctr}\n")
XSDebug(io.update.mask,
p"update Table: pc:${Hexadecimal(u.pc)}, hist:${Hexadecimal(u.hist)}, " +
p"tageTaken:${u.tagePred}, taken:${u.taken}, oldCtr:${u.oldCtr}\n")
val ctrPos = io.update.tagePred
val hitCtr = wrbypass.io.ctrs(ctrPos).bits
XSDebug(wrbypass.io.hit && wrbypass.io.ctrs(ctrPos).valid && io.update.mask,
p"wrbypass hit idx:$update_idx, ctr:$hitCtr, " +
p"taken:${io.update.taken} newCtr:${update_wdata}\n")
}
val u = io.update
XSDebug(io.req.valid,
p"scTableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, " +
p"s0_idx=${s0_idx}, hist=${Hexadecimal(io.req.bits.hist)}\n")
XSDebug(RegNext(io.req.valid),
p"scTableResp: s1_idx=${s1_idx}," +
p"ctr:${io.resp.ctr}\n")
XSDebug(io.update.mask,
p"update Table: pc:${Hexadecimal(u.pc)}, hist:${Hexadecimal(u.hist)}, " +
p"tageTaken:${u.tagePred}, taken:${u.taken}, oldCtr:${u.oldCtr}\n")
val updateCtrPos = io.update.tagePred
val hitCtr = wrbypass.io.ctrs(updateCtrPos).bits
XSDebug(wrbypass.io.hit && wrbypass.io.ctrs(updateCtrPos).valid && io.update.mask,
p"wrbypass hit idx:$update_idx, ctr:$hitCtr, " +
p"taken:${io.update.taken} newCtr:${update_wdata}\n")
}
......@@ -224,6 +231,7 @@ object SCThreshold {
trait HasSC extends HasSCParameter { this: Tage =>
val update_on_mispred, update_on_unconf = WireInit(0.U.asTypeOf(Vec(TageBanks, Bool())))
var sc_fh_info = Set[FoldedHistoryInfo]()
if (EnableSC) {
val bank_scTables = BankSCTableInfos.zipWithIndex.map {
case (info, b) =>
......@@ -233,7 +241,8 @@ trait HasSC extends HasSCParameter { this: Tage =>
val req = t.io.req
req.valid := io.s0_fire
req.bits.pc := s0_pc
req.bits.hist := io.in.bits.ghist << b
req.bits.hist := io.in.bits.ghist
req.bits.folded_hist := io.in.bits.folded_hist
req.bits.phist := DontCare
if (!EnableSC) {t.io.update := DontCare}
t
......@@ -241,6 +250,7 @@ trait HasSC extends HasSCParameter { this: Tage =>
}
tables
}
sc_fh_info = bank_scTables.flatMap(_.map(_.getFoldedHistoryInfo).reduce(_++_)).toSet
val scThresholds = List.fill(TageBanks)(RegInit(SCThreshold(5)))
val useThresholds = VecInit(scThresholds map (_.thres))
......@@ -371,7 +381,8 @@ trait HasSC extends HasSCParameter { this: Tage =>
bank_scTables(b)(i).io.update.taken := RegNext(scUpdateTakens(b))
bank_scTables(b)(i).io.update.oldCtr := RegNext(scUpdateOldCtrs(b)(i))
bank_scTables(b)(i).io.update.pc := RegNext(update.pc)
bank_scTables(b)(i).io.update.hist := RegNext(updateHist.predHist << b)
bank_scTables(b)(i).io.update.hist := RegNext(updateHist.predHist)
bank_scTables(b)(i).io.update.folded_hist := RegNext(updateFHist)
}
}
......@@ -387,6 +398,9 @@ trait HasSC extends HasSCParameter { this: Tage =>
}
override def getFoldedHistoryInfo = Some(tage_fh_info ++ sc_fh_info)
val perfinfo = IO(new Bundle(){
val perfEvents = Output(new PerfEventsBundle(3))
})
......
......@@ -29,33 +29,16 @@ import freechips.rocketchip.transforms.naming.RenameDesiredNames
import scala.math.min
import scala.util.matching.Regex
import os.followLink
trait TageParams extends HasXSParameter with HasBPUParameter {
// Sets Hist Tag
val TableInfo = Seq(( 128*8, 2, 7),
( 128*8, 4, 7),
( 256*8, 8, 8),
( 256*8, 16, 8),
( 128*8, 32, 9),
( 128*8, 64, 9))
// ( 64, 64, 11),
// ( 64, 101, 12),
// ( 64, 160, 12),
// ( 64, 254, 13),
// ( 32, 403, 14),
// ( 32, 640, 15))
// Sets Hist Tag
val BankTableInfos = (0 until numBr).map(i =>
TableInfo.map{ case (s, h, t) => (s/(1 << i), h, t) }
)
// println(BankTableInfos)
val BankTageNTables = BankTableInfos.map(_.size) // Number of tage tables
val UBitPeriod = 256
trait TageParams extends HasBPUConst with HasXSParameter {
// println(BankTageTableInfos)
val BankTageNTables = BankTageTableInfos.map(_.size) // Number of tage tables
val TageBanks = numBr
val UBitPeriod = 256
val TageCtrBits = 3
val TotalBits = BankTableInfos.map { info =>
val TotalBits = BankTageTableInfos.map { info =>
info.map{
case (s, h, t) => {
s * (1+t+TageCtrBits)
......@@ -92,6 +75,7 @@ abstract class TageModule(implicit p: Parameters)
class TageReq(implicit p: Parameters) extends TageBundle {
val pc = UInt(VAddrBits.W)
val hist = UInt(HistoryLength.W)
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val phist = UInt(PathHistoryLength.W)
}
......@@ -103,6 +87,7 @@ class TageResp(implicit p: Parameters) extends TageBundle {
class TageUpdate(implicit p: Parameters) extends TageBundle {
val pc = UInt(VAddrBits.W)
val hist = UInt(HistoryLength.W)
val folded_hist = new AllFoldedHistories(foldedGHistInfos)
val phist = UInt(PathHistoryLength.W)
// update tag and ctr
val mask = Bool()
......@@ -115,7 +100,7 @@ class TageUpdate(implicit p: Parameters) extends TageBundle {
}
class TageMeta(val bank: Int)(implicit p: Parameters)
extends XSBundle with TageParams with HasSCParameter
extends TageBundle with HasSCParameter
{
val provider = ValidUndirectioned(UInt(log2Ceil(BankTageNTables(bank)).W))
val prednum = ValidUndirectioned(UInt(log2Ceil(BankTageNTables(bank)).W))
......@@ -149,8 +134,7 @@ trait TBTParams extends HasXSParameter {
}
@chiselName
class TageBTable
(val numBr: Int)(implicit p: Parameters) extends XSModule with TBTParams{
class TageBTable(implicit p: Parameters) extends XSModule with TBTParams{
val io = IO(new Bundle {
val s0_fire = Input(Bool())
val s0_pc = Input(UInt(VAddrBits.W))
......@@ -269,26 +253,43 @@ class TageTable
val wrBypassEntries = 8
val phistLen = if (PathHistoryLength > histLen) histLen else PathHistoryLength
def compute_tag_and_hash(unhashed_idx: UInt, hist: UInt, phist: UInt) = {
def F(phist: UInt, len: Int) = {
val lenMask = Fill(len, 1.U(1.W))
val rowMask = Fill(log2Ceil(nRows), 1.U(1.W))
val masked = phist & lenMask
val a1 = masked & rowMask
val a2 = masked >> log2Ceil(nRows)
val a3 = ((a2 << tableIdx) & rowMask) + (a2 >> (log2Ceil(nRows) - tableIdx))
val a4 = a1 ^ a3
val res = ((a3 << tableIdx) & rowMask) + (a3 >> (log2Ceil(nRows) - tableIdx))
res
}
val idx_history = compute_folded_ghist(hist, log2Ceil(nRows))
val idx_phist = F(phist, (if (PathHistoryLength > histLen) histLen else PathHistoryLength))
// val idx = (unhashed_idx ^ (unhashed_idx >> (log2Ceil(nRows)-tableIdx+1)) ^ idx_history ^ idx_phist)(log2Ceil(nRows) - 1, 0)
val idx = (unhashed_idx ^ idx_history)(log2Ceil(nRows) - 1, 0)
val tag_history = compute_folded_ghist(hist, tagLen)
val alt_tag_history = compute_folded_ghist(hist, tagLen-1)
// Use another part of pc to make tags
val tag = ((unhashed_idx >> log2Ceil(nRows)) ^ tag_history ^ (alt_tag_history << 1)) (tagLen - 1, 0)
// def compute_tag_and_hash(unhashed_idx: UInt, hist: UInt, phist: UInt) = {
// def F(phist: UInt, len: Int) = {
// val lenMask = Fill(len, 1.U(1.W))
// val rowMask = Fill(log2Ceil(nRows), 1.U(1.W))
// val masked = phist & lenMask
// val a1 = masked & rowMask
// val a2 = masked >> log2Ceil(nRows)
// val a3 = ((a2 << tableIdx) & rowMask) + (a2 >> (log2Ceil(nRows) - tableIdx))
// val a4 = a1 ^ a3
// val res = ((a3 << tableIdx) & rowMask) + (a3 >> (log2Ceil(nRows) - tableIdx))
// res
// }
// val idx_history = compute_folded_ghist(hist, log2Ceil(nRows))
// val idx_phist = F(phist, (if (PathHistoryLength > histLen) histLen else PathHistoryLength))
// // val idx = (unhashed_idx ^ (unhashed_idx >> (log2Ceil(nRows)-tableIdx+1)) ^ idx_history ^ idx_phist)(log2Ceil(nRows) - 1, 0)
// val idx = (unhashed_idx ^ idx_history)(log2Ceil(nRows) - 1, 0)
// val tag_history = compute_folded_ghist(hist, tagLen)
// val alt_tag_history = compute_folded_ghist(hist, tagLen-1)
// // Use another part of pc to make tags
// val tag = ((unhashed_idx >> log2Ceil(nRows)) ^ tag_history ^ (alt_tag_history << 1)) (tagLen - 1, 0)
// (idx, tag)
// }
val idxFhInfo = (histLen, min(log2Ceil(nRows), histLen))
val tagFhInfo = (histLen, min(histLen, tagLen))
val altTagFhInfo = (histLen, min(histLen, tagLen-1))
val allFhInfos = Seq(idxFhInfo, tagFhInfo, altTagFhInfo)
def getFoldedHistoryInfo = allFhInfos.filter(_._1 >0).toSet
def compute_tag_and_hash(unhashed_idx: UInt, allFh: AllFoldedHistories) = {
val idx_fh = allFh.getHistWithInfo(idxFhInfo).folded_hist
val tag_fh = allFh.getHistWithInfo(tagFhInfo).folded_hist
val alt_tag_fh = allFh.getHistWithInfo(altTagFhInfo).folded_hist
// require(idx_fh.getWidth == log2Ceil(nRows))
val idx = (unhashed_idx ^ idx_fh)(log2Ceil(nRows)-1, 0)
val tag = ((unhashed_idx >> log2Ceil(nRows)) ^ tag_fh ^ (alt_tag_fh << 1)) (tagLen - 1, 0)
(idx, tag)
}
......@@ -316,7 +317,14 @@ class TageTable
val table = Module(new SRAMTemplate(new TageEntry, set=nRows, way=1, shouldReset=true, holdRead=true, singlePort=false))
val (s0_idx, s0_tag) = compute_tag_and_hash(req_unhashed_idx, io.req.bits.hist, io.req.bits.phist)
// val (s0_idx, s0_tag) = compute_tag_and_hash(req_unhashed_idx, io.req.bits.hist, io.req.bits.phist)
val (s0_idx, s0_tag) = compute_tag_and_hash(req_unhashed_idx, io.req.bits.folded_hist)
// TODO: remove this checking code
val idx_history = compute_folded_ghist(io.req.bits.hist, log2Ceil(nRows))
val idx_fh = io.req.bits.folded_hist.getHistWithInfo(idxFhInfo)
assert(idx_history === idx_fh.folded_hist)
////////////////////////////////////////
table.io.r.req.valid := io.req.valid
table.io.r.req.bits.setIdx := s0_idx
......@@ -352,7 +360,15 @@ class TageTable
// Use fetchpc to compute hash
val update_wdata = Wire(new TageEntry)
val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.hist, io.update.phist)
// val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.hist, io.update.phist)
val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.folded_hist)
// TODO: remove this checking code
val update_idx_history = compute_folded_ghist(io.update.hist, log2Ceil(nRows))
val update_idx_info = (histLen, min(log2Ceil(nRows), histLen))
val update_idx_fh = io.update.folded_hist.getHistWithInfo(update_idx_info)
assert(update_idx_history === update_idx_fh.folded_hist || !io.update.mask)
////////////////////////////////////////
table.io.w.apply(
valid = io.update.mask,
......@@ -444,43 +460,41 @@ class TageTable
if (BPUDebug && debug) {
XSPerfAccumulate(f"tage_table_wrbypass_hit", io.update.mask && wrbypass.io.hit)
XSPerfAccumulate(f"tage_table_wrbypass_enq", io.update.mask && !wrbypass.io.hit)
XSPerfAccumulate("tage_table_hits", PopCount(io.resp.valid))
val u = io.update
val b = PriorityEncoder(u.mask)
val ub = PriorityEncoder(u.uMask)
XSDebug(io.req.valid,
p"tableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, " +
p"hist=${Hexadecimal(io.req.bits.hist)}, idx=$s0_idx, " +
p"tag=$s0_tag\n")
XSDebug(RegNext(io.req.valid) && req_rhit,
p"TageTableResp: idx=$s1_idx, hit:$req_rhit, " +
p"ctr:${io.resp.bits.ctr}, u:${io.resp.bits.u}\n")
XSDebug(io.update.mask,
p"update Table: pc:${Hexadecimal(u.pc)}, hist:${Hexadecimal(u.hist)}, " +
p"taken:${u.taken}, alloc:${u.alloc}, oldCtr:${u.oldCtr}\n")
XSDebug(io.update.mask,
p"update Table: writing tag:$update_tag, " +
p"ctr: ${update_wdata.ctr} in idx ${update_idx}\n")
val hitCtr = wrbypass.io.ctr
XSDebug(wrbypass.io.hit && io.update.mask,
// p"bank $i wrbypass hit wridx:$wrbypass_hit_idx, idx:$update_idx, tag: $update_tag, " +
p"ctr:$hitCtr, newCtr:${update_wdata.ctr}")
XSDebug(RegNext(io.req.valid) && !req_rhit, "TageTableResp: not hit!\n")
// ------------------------------Debug-------------------------------------
val valids = Reg(Vec(nRows, Bool()))
when (reset.asBool) { valids.foreach(r => r := false.B) }
when (io.update.mask) { valids(update_idx) := true.B }
XSDebug("Table usage:------------------------\n")
XSDebug("%d out of %d rows are valid\n", PopCount(valids), nRows.U)
}
XSPerfAccumulate(f"tage_table_wrbypass_hit", io.update.mask && wrbypass.io.hit)
XSPerfAccumulate(f"tage_table_wrbypass_enq", io.update.mask && !wrbypass.io.hit)
XSPerfAccumulate("tage_table_hits", PopCount(io.resp.valid))
val u = io.update
val b = PriorityEncoder(u.mask)
val ub = PriorityEncoder(u.uMask)
XSDebug(io.req.valid,
p"tableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, " +
p"hist=${Hexadecimal(io.req.bits.hist)}, idx=$s0_idx, " +
p"tag=$s0_tag\n")
XSDebug(RegNext(io.req.valid) && req_rhit,
p"TageTableResp: idx=$s1_idx, hit:$req_rhit, " +
p"ctr:${io.resp.bits.ctr}, u:${io.resp.bits.u}\n")
XSDebug(io.update.mask,
p"update Table: pc:${Hexadecimal(u.pc)}, hist:${Hexadecimal(u.hist)}, " +
p"taken:${u.taken}, alloc:${u.alloc}, oldCtr:${u.oldCtr}\n")
XSDebug(io.update.mask,
p"update Table: writing tag:$update_tag, " +
p"ctr: ${update_wdata.ctr} in idx ${update_idx}\n")
val hitCtr = wrbypass.io.ctr
XSDebug(wrbypass.io.hit && io.update.mask,
// p"bank $i wrbypass hit wridx:$wrbypass_hit_idx, idx:$update_idx, tag: $update_tag, " +
p"ctr:$hitCtr, newCtr:${update_wdata.ctr}")
XSDebug(RegNext(io.req.valid) && !req_rhit, "TageTableResp: not hit!\n")
// ------------------------------Debug-------------------------------------
val valids = Reg(Vec(nRows, Bool()))
when (reset.asBool) { valids.foreach(r => r := false.B) }
when (io.update.mask) { valids(update_idx) := true.B }
XSDebug("Table usage:------------------------\n")
XSDebug("%d out of %d rows are valid\n", PopCount(valids), nRows.U)
}
......@@ -501,27 +515,29 @@ class Tage(implicit p: Parameters) extends BaseTage {
val resp_meta = Wire(MixedVec((0 until TageBanks).map(new TageMeta(_))))
override val meta_size = resp_meta.getWidth
val bank_tables = BankTableInfos.zipWithIndex.map {
val bank_tables = BankTageTableInfos.zipWithIndex.map {
case (info, b) =>
val tables = info.zipWithIndex.map {
case ((nRows, histLen, tagLen), i) =>
val t = Module(new TageTable(nRows, histLen, tagLen, UBitPeriod, i))
t.io.req.valid := io.s0_fire
t.io.req.bits.pc := s0_pc
t.io.req.bits.hist := io.in.bits.ghist << b
t.io.req.bits.folded_hist := io.in.bits.folded_hist
t.io.req.bits.hist := io.in.bits.ghist
t.io.req.bits.phist := io.in.bits.phist
t
}
tables
}
val bt = Module (new TageBTable(numBr))
val bt = Module (new TageBTable)
bt.io.s0_fire := io.s0_fire
bt.io.s0_pc := s0_pc
bt.io.update := io.update
val tage_fh_info = bank_tables.flatMap(_.map(_.getFoldedHistoryInfo).reduce(_++_)).toSet
override def getFoldedHistoryInfo = Some(tage_fh_info)
// Keep the table responses to process in s3
val s1_resps = MixedVecInit(bank_tables.map(b => VecInit(b.map(t => t.io.resp))))
//val s1_bim = io.in.bits.resp_in(0).s1.preds
......@@ -577,6 +593,7 @@ class Tage(implicit p: Parameters) extends BaseTage {
!(PriorityEncoder(update.preds.br_taken_mask) < w.U)))
val updateHist = update.ghist
val updatePhist = update.phist
val updateFHist = update.folded_hist
val updateMetas = update.meta.asTypeOf(MixedVec((0 until TageBanks).map(new TageMeta(_))))
......@@ -758,7 +775,8 @@ class Tage(implicit p: Parameters) extends BaseTage {
bank_tables(w)(i).io.update.u := RegNext(updateU(w)(i))
bank_tables(w)(i).io.update.pc := RegNext(update.pc)
// use fetch pc instead of instruction pc
bank_tables(w)(i).io.update.hist := RegNext(updateHist.predHist << w)
bank_tables(w)(i).io.update.folded_hist := RegNext(updateFHist)
bank_tables(w)(i).io.update.hist := RegNext(updateHist.predHist)
bank_tables(w)(i).io.update.phist := RegNext(updatePhist)
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册