uBTB.scala 5.8 KB
Newer Older
Z
zoujr 已提交
1 2
/***************************************************************************************
* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
L
Lingrui98 已提交
3
* Copyright (c) 2020-2021 Peng Cheng Laboratory
Z
zoujr 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
*
* XiangShan is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*
* See the Mulan PSL v2 for more details.
***************************************************************************************/

package xiangshan.frontend

import chipsalliance.rocketchip.config.Parameters
import chisel3._
import chisel3.util._
import utils._
import xiangshan._
import chisel3.experimental.chiselName
Z
zoujr 已提交
25
import xiangshan.cache.mmu.CAMTemplate
Z
zoujr 已提交
26

27 28 29
trait MicroBTBParams extends HasXSParameter with HasBPUParameter {
  val numEntries = UbtbSize
  def ubtbAddr = new TableAddr(log2Up(numEntries), 1)
L
Lingrui98 已提交
30 31
}

32 33 34 35 36 37 38
class NewMicroBTBEntry(implicit p: Parameters) extends XSBundle with MicroBTBParams {
  // val valid = Bool()
  val nextAddr = UInt(VAddrBits.W) // could be target or fallThrough
  val cfiOffset = UInt(log2Ceil(PredictWidth).W)
  val taken = Bool()
  val takenOnBr = Bool()
  val brNumOH = UInt((numBr+1).W) // used to speculative update histPtr
L
Lingrui98 已提交
39
  val oversize = Bool()
40

L
Lingrui98 已提交
41
  def fromBpuUpdateBundle(u: BranchPredictionUpdate) = {
42 43 44 45 46 47 48
    // this.valid := true.B
    this.nextAddr := u.getTarget
    this.cfiOffset := u.cfiIndex.bits
    this.taken := u.taken
    this.takenOnBr := (u.lastBrPosOH.init zip u.full_pred.br_taken_mask).map{case (a, b) => a && b}.reduce(_||_)
    this.brNumOH := u.lastBrPosOH.asUInt()
    this.oversize := u.full_pred.oversize && (!u.taken || u.taken && u.cfiIndex.bits.andR)
L
Lingrui98 已提交
49
  }
Z
zoujr 已提交
50 51
}

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
// class MicroBTBEntry(implicit p: Parameters) extends XSBundle with MicroBTBParams {
//   val valid = Bool()
//   val tag = UInt(tagSize.W)
//   val slot_valids = Vec(totalSlot, Bool())
//   val offsets = Vec(totalSlot, UInt(log2Ceil(PredictWidth).W))
//   val targets = Vec(totalSlot, UInt(VAddrBits.W))
//   val fallThroughAddr = UInt(VAddrBits.W)
//   val oversize = Bool()
//   val last_is_br = Bool()
//   def brValids = VecInit(slot_valids.init :+ (slot_valids.last && last_is_br))
//   def jmpValid = VecInit(slot_valids.last && !last_is_br)
//   def fromBpuUpdateBundle(u: BranchPredictionUpdate) = {
//     this.valid := true.B
//     this.tag := ubtbAddr.getTag(u.pc)
//     this.slot_valids := VecInit(u.ftb_entry.brSlots.map(_.valid) :+ u.ftb_entry.tailSlot.valid)
//     this.offsets := u.ftb_entry.getOffsetVec
//     this.targets := u.ftb_entry.getTargetVec(u.pc)
//     this.fallThroughAddr := u.ftb_entry.getFallThrough(u.pc)
//     this.oversize := u.ftb_entry.oversize
//     this.last_is_br := u.ftb_entry.tailSlot.sharing
//   }
// }

Z
zoujr 已提交
75 76
@chiselName
class MicroBTB(implicit p: Parameters) extends BasePredictor
77
  with MicroBTBParams with HasPerfEvents
Z
zoujr 已提交
78
{
L
Lingrui98 已提交
79
  
80

81 82
  class MicroBTBOutMeta extends XSBundle {
    val hit = Bool()
Z
zoujr 已提交
83 84
  }

L
Lingrui98 已提交
85

86

87
  override val meta_size = WireInit(0.U.asTypeOf(new MicroBTBOutMeta)).getWidth // TODO: ReadResp shouldn't save useless members
88 89
  
  def getIdx(pc: UInt) = pc(log2Ceil(numEntries)+instOffsetBits-1, instOffsetBits)
Z
zoujr 已提交
90

91 92 93 94
  val fh_info = (UbtbGHRLength, log2Ceil(UbtbSize))
  println(s"ubtb fh info ${fh_info}")
  def get_ghist_from_fh(afh: AllFoldedHistories) = afh.getHistWithInfo(fh_info)
  val s0_ridx = getIdx(s0_pc) ^ get_ghist_from_fh(io.in.bits.folded_hist).folded_hist
95 96 97 98 99 100 101
  val dataMem = Module(new SRAMTemplate(new NewMicroBTBEntry, set=numEntries, way=1, shouldReset=false, holdRead=true, singlePort=false))
  dataMem.io.r.req.valid := io.s0_fire
  dataMem.io.r.req.bits.setIdx := s0_ridx
  val validArray = RegInit(0.U.asTypeOf(Vec(numEntries, Bool())))
  // io.out.resp
  val s1_ridx = RegEnable(s0_ridx, io.s0_fire)
  val resp_valid = validArray(s1_ridx)
Z
zoujr 已提交
102 103


104
  val outMeta = Wire(new MicroBTBOutMeta)
Z
zoujr 已提交
105

106
  XSDebug(p"uBTB entry, read_pc=${Hexadecimal(s0_pc)}\n")
Z
zoujr 已提交
107

108 109
  io.out.resp.s1.minimal_pred.fromMicroBTBEntry(resp_valid, dataMem.io.r.resp.data(0), s1_pc)
  io.out.resp.s1.is_minimal := true.B
Z
zoujr 已提交
110

111
  outMeta.hit := true.B
L
Lingrui98 已提交
112
  io.out.last_stage_meta := RegEnable(outMeta.asUInt, io.s1_fire)
Z
zoujr 已提交
113 114 115 116 117

  // Update logic
  val update = RegNext(io.update.bits)
  val u_valid = RegNext(io.update.valid)
  val u_pc = update.pc
118
  val u_br_taken_mask = update.full_pred.br_taken_mask
119
  val u_meta = update.meta.asTypeOf(new MicroBTBOutMeta)
120 121
  val u_data = Wire(new NewMicroBTBEntry)
  u_data.fromBpuUpdateBundle(update)
122
  val u_idx = getIdx(update.pc) ^ get_ghist_from_fh(update.folded_hist).folded_hist
Z
zoujr 已提交
123

124 125 126 127
  dataMem.io.w.apply(u_valid, u_data, u_idx, 1.U(1.W))
  when (u_valid) {
    validArray(u_idx) := true.B
  }
L
Lingrui98 已提交
128

129 130 131
  // bank.update_valid := u_valid && u_taken && ((u_meta.hit && !update.old_entry) || !u_meta.hit)
  // bank.update_pc := u_pc
  // bank.update_write_entry.fromBpuUpdateBundle(update)
Z
zoujr 已提交
132

133 134
  // XSDebug("req_v=%b, req_pc=%x, hit=%b\n", io.s1_fire, s1_pc, bank.read_hit)
  XSDebug("target=%x\n", io.out.resp.s1.getTarget)
Z
zoujr 已提交
135

L
Lingrui98 已提交
136
  XSDebug(u_valid, "[update]Update from ftq\n")
137
  XSDebug(u_valid, "[update]update_pc=%x, tag=%x\n", u_pc, ubtbAddr.getTag(u_pc))
L
Lingrui98 已提交
138
  XSDebug(u_valid, "[update]taken_mask=%b, brValids=%b, jmpValid=%b\n",
139
    u_br_taken_mask.asUInt, update.ftb_entry.brValids.asUInt, update.ftb_entry.jmpValid)
Z
zoujr 已提交
140

141 142
  // XSPerfAccumulate("ubtb_read_hits", RegNext(io.s1_fire) && bank.read_hit)
  // XSPerfAccumulate("ubtb_read_misses", RegNext(io.s1_fire) && !bank.read_hit)
143

L
Lingrui98 已提交
144 145
  XSPerfAccumulate("ubtb_commit_hits", u_valid && u_meta.hit)
  XSPerfAccumulate("ubtb_commit_misses", u_valid && !u_meta.hit)
Z
zoujr 已提交
146

147
  val perfEvents = Seq(
148 149
    ("ubtb_commit_hit       ", u_valid &&  u_meta.hit),
    ("ubtb_commit_miss      ", u_valid && !u_meta.hit),
150
  )
151
  generatePerfEvent()
Z
zoujr 已提交
152
}