uBTB.scala 5.2 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

trait MicroBTBParams extends HasXSParameter {
28
  val numWays = 1024
Z
zoujr 已提交
29
  val tagSize = 20
30 31
  // val lowerBitSize = 20
  val untaggedBits = log2Ceil(numWays) + instOffsetBits
Z
zoujr 已提交
32 33 34 35 36 37
}

@chiselName
class MicroBTB(implicit p: Parameters) extends BasePredictor
  with MicroBTBParams
{
38
  val ubtbAddr = new TableAddr(log2Up(numWays), 1)
39

40 41
  class MicroBTBOutMeta extends XSBundle {
    val hit = Bool()
Z
zoujr 已提交
42 43
  }

44
  class MicroBTBEntry extends FTBEntryWithTag {}
45

46
  override val meta_size = WireInit(0.U.asTypeOf(new MicroBTBOutMeta)).getWidth // TODO: ReadResp shouldn't save useless members
Z
zoujr 已提交
47

48
  class UBTBBank(val nWays: Int) extends XSModule with BPUUtils {
Z
zoujr 已提交
49
    val io = IO(new Bundle {
50
      val read_pc = Flipped(DecoupledIO(UInt(VAddrBits.W))) // TODO: Add ready
51
      // val read_taken_mask = Input(Vec(numBr, Bool()))
52
      val read_entry = Output(new MicroBTBEntry)
L
Lingrui98 已提交
53
      val read_hit = Output(Bool())
Z
zoujr 已提交
54

L
Lingrui98 已提交
55 56
      val update_valid = Input(Bool())
      val update_write_entry = Input(new MicroBTBEntry)
57
      val update_pc = Input(UInt(VAddrBits.W))
Z
zoujr 已提交
58 59
    })

60
    val dataMem = Module(new SRAMTemplate(new MicroBTBEntry, set = numWays, way = 1, shouldReset = true, holdRead = true, singlePort = true))
Z
zoujr 已提交
61

62 63
    val read_pc = RegNext(io.read_pc.bits)
    val read_tag = ubtbAddr.getTag(read_pc)(tagSize-1,0)
Z
zoujr 已提交
64

65 66
    dataMem.io.r.req.valid := io.read_pc.valid
    dataMem.io.r.req.bits.setIdx := ubtbAddr.getIdx(io.read_pc.bits)
Z
zoujr 已提交
67

68
    io.read_pc.ready := dataMem.io.r.req.ready
Z
zoujr 已提交
69

70 71
    val hit_entry = dataMem.io.r.resp.data(0)
    val hit = hit_entry.entry.valid && hit_entry.tag === read_tag
72

L
Lingrui98 已提交
73 74
    io.read_entry := hit_entry
    io.read_hit := hit
75

76
    dataMem.io.w.apply(io.update_valid, io.update_write_entry, ubtbAddr.getIdx(io.update_pc), io.update_valid)
Z
zoujr 已提交
77

Z
zoujr 已提交
78
  } // uBTBBank
Z
zoujr 已提交
79

L
Lingrui98 已提交
80 81 82
  val ubtbBank = Module(new UBTBBank(numWays))
  val bank = ubtbBank.io
  val read_entry = bank.read_entry
83
  val outMeta = Wire(new MicroBTBOutMeta)
Z
zoujr 已提交
84

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

87 88
  bank.read_pc.valid := io.s0_fire
  bank.read_pc.bits := s0_pc
Z
zoujr 已提交
89

90
  io.s1_ready := bank.read_pc.ready
Z
zoujr 已提交
91

Z
zoujr 已提交
92 93
  io.out.resp := io.in.bits.resp_in(0)
  io.out.resp.s1.pc := s1_pc
L
Lingrui98 已提交
94
  io.out.resp.s1.preds.hit := bank.read_hit
95 96
  io.out.resp.s1.ftb_entry := read_entry.entry
  io.out.resp.s1.preds.fromFtbEntry(read_entry.entry, s1_pc)
L
Lingrui98 已提交
97 98

  outMeta.hit := bank.read_hit
99
  io.out.s3_meta := RegEnable(RegEnable(outMeta.asUInt, io.s1_fire), io.s2_fire)
Z
zoujr 已提交
100 101 102 103 104

  // Update logic
  val update = RegNext(io.update.bits)
  val u_valid = RegNext(io.update.valid)
  val u_pc = update.pc
Z
zoujr 已提交
105
  val u_taken = update.preds.taken
106
  val u_br_taken_mask = update.preds.br_taken_mask
107
  val u_meta = update.meta.asTypeOf(new MicroBTBOutMeta)
Z
zoujr 已提交
108

109
  val u_tag = ubtbAddr.getTag(u_pc)
L
Lingrui98 已提交
110

111 112 113 114 115
  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.entry := update.ftb_entry
  bank.update_write_entry.entry.valid := true.B
  bank.update_write_entry.tag := u_tag
Z
zoujr 已提交
116

L
Lingrui98 已提交
117 118
  XSDebug("req_v=%b, req_pc=%x, hit=%b\n", io.s1_fire, s1_pc, bank.read_hit)
  XSDebug("target=%x, real_taken_mask=%b, taken_mask=%b, brValids=%b, jmpValid=%b\n",
119
    io.out.resp.s1.target, io.out.resp.s1.real_slot_taken_mask.asUInt, io.out.resp.s1.preds.br_taken_mask.asUInt, read_entry.entry.brValids.asUInt, read_entry.entry.jmpValid.asUInt)
Z
zoujr 已提交
120

L
Lingrui98 已提交
121
  XSDebug(u_valid, "[update]Update from ftq\n")
122
  XSDebug(u_valid, "[update]update_pc=%x, tag=%x\n", u_pc, ubtbAddr.getTag(u_pc))
L
Lingrui98 已提交
123
  XSDebug(u_valid, "[update]taken_mask=%b, brValids=%b, jmpValid=%b\n",
124
    u_br_taken_mask.asUInt, update.ftb_entry.brValids.asUInt, update.ftb_entry.jmpValid)
Z
zoujr 已提交
125

L
Lingrui98 已提交
126 127
  XSPerfAccumulate("ubtb_read_hits", RegNext(io.s1_fire) && bank.read_hit)
  XSPerfAccumulate("ubtb_read_misses", RegNext(io.s1_fire) && !bank.read_hit)
128

L
Lingrui98 已提交
129 130
  XSPerfAccumulate("ubtb_commit_hits", u_valid && u_meta.hit)
  XSPerfAccumulate("ubtb_commit_misses", u_valid && !u_meta.hit)
Z
zoujr 已提交
131

132 133 134 135 136 137 138 139 140 141 142
  val perfinfo = IO(new Bundle(){
    val perfEvents = Output(new PerfEventsBundle(2))
  })
  val perfEvents = Seq(
    ("ubtb_commit_hits       ", u_valid &&  u_meta.hit),
    ("ubtb_commit_misse      ", u_valid && !u_meta.hit),
  )

  for (((perf_out,(perf_name,perf)),i) <- perfinfo.perfEvents.perf_events.zip(perfEvents).zipWithIndex) {
    perf_out.incr_step := RegNext(perf)
  }
Z
zoujr 已提交
143
}