xref: /XiangShan/src/main/scala/xiangshan/frontend/Bim.scala (revision 67ba96b4871c459c09df20e3052738174021a830)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package xiangshan.frontend
18
19import chipsalliance.rocketchip.config.Parameters
20import chisel3._
21import chisel3.util._
22import xiangshan._
23import utils._
24import utility._
25import chisel3.experimental.chiselName
26
27trait BimParams extends HasXSParameter {
28  val bimSize = 2048
29  val bypassEntries = 4
30}
31
32@chiselName
33class BIM(implicit p: Parameters) extends BasePredictor with BimParams with BPUUtils {
34  val bimAddr = new TableAddr(log2Up(bimSize), 1)
35
36  val bim = Module(new SRAMTemplate(UInt(2.W), set = bimSize, way=numBr, shouldReset = false, holdRead = true))
37
38  val doing_reset = RegInit(true.B)
39  val resetRow = RegInit(0.U(log2Ceil(bimSize).W))
40  resetRow := resetRow + doing_reset
41  when (resetRow === (bimSize-1).U) { doing_reset := false.B }
42
43  val s0_idx = bimAddr.getIdx(s0_pc)
44
45  // bim.io.r.req.valid := io.s0_fire
46  bim.io.r.req.valid := false.B
47  bim.io.r.req.bits.setIdx := s0_idx
48
49  io.in.ready := bim.io.r.req.ready
50  io.s1_ready := bim.io.r.req.ready
51
52  val s1_read = bim.io.r.resp.data
53
54  io.out := io.in.bits.resp_in(0)
55
56  val s1_latch_taken_mask = VecInit(Cat((0 until numBr reverse).map(i => s1_read(i)(1))).asBools())
57  val s1_latch_meta       = s1_read.asUInt()
58  override val meta_size = s1_latch_meta.getWidth
59
60  // io.out.s1.full_pred.br_taken_mask := s1_latch_taken_mask
61  // io.out.s2.full_pred.br_taken_mask := RegEnable(s1_latch_taken_mask, 0.U.asTypeOf(Vec(numBr, Bool())), io.s1_fire)
62
63  io.out.last_stage_meta := RegEnable(RegEnable(s1_latch_meta, io.s1_fire), io.s2_fire) // TODO: configurable with total-stages
64
65  // Update logic
66  val u_valid = RegNext(io.update.valid)
67  val update = RegNext(io.update.bits)
68  val u_idx = bimAddr.getIdx(update.pc)
69
70  val update_mask = LowerMask(PriorityEncoderOH(update.br_taken_mask.asUInt))
71  val newCtrs = Wire(Vec(numBr, UInt(2.W)))
72  val need_to_update = VecInit((0 until numBr).map(i => u_valid && update.ftb_entry.brValids(i) && update_mask(i)))
73
74
75  // Bypass logic
76  val wrbypass = Module(new WrBypass(UInt(2.W), bypassEntries, log2Up(bimSize), numWays = numBr))
77  wrbypass.io.wen := need_to_update.reduce(_||_)
78  wrbypass.io.write_idx := u_idx
79  wrbypass.io.write_data := newCtrs
80  wrbypass.io.write_way_mask.map(_ := need_to_update)
81
82  val oldCtrs =
83    VecInit((0 until numBr).map(i =>
84      Mux(wrbypass.io.hit && wrbypass.io.hit_data(i).valid,
85        wrbypass.io.hit_data(i).bits,
86        update.meta(2*i+1, 2*i))
87    ))
88
89  val newTakens = update.br_taken_mask
90  newCtrs := VecInit((0 until numBr).map(i =>
91    satUpdate(oldCtrs(i), 2, newTakens(i))
92  ))
93
94
95  bim.io.w.apply(
96    valid = false.B,
97    // valid = need_to_update.asUInt.orR || doing_reset,
98    data = Mux(doing_reset, VecInit(Seq.fill(numBr)(2.U(2.W))), newCtrs),
99    setIdx = Mux(doing_reset, resetRow, u_idx),
100    waymask = Mux(doing_reset, Fill(numBr, 1.U(1.W)).asUInt(), need_to_update.asUInt())
101  )
102
103  val latch_s0_fire = RegNext(io.s0_fire)
104
105  XSDebug(doing_reset, "Doing reset...\n")
106
107  XSDebug(io.s0_fire, "req_pc=%x, req_idx=%d\n", s0_pc, s0_idx)
108
109  for(i <- 0 until numBr) {
110    XSDebug(latch_s0_fire, "last_cycle req %d: ctr=%b\n", i.U, s1_read(i))
111  }
112
113  XSDebug(u_valid, "update_pc=%x, update_idx=%d, is_br=%b\n", update.pc, u_idx, update.ftb_entry.brValids.asUInt)
114
115  XSDebug(u_valid, "newTakens=%b\n", newTakens.asUInt)
116
117  for(i <- 0 until numBr) {
118    XSDebug(u_valid, "oldCtrs%d=%b\n", i.U, oldCtrs(i))
119  }
120
121  for(i <- 0 until numBr) {
122    XSDebug(u_valid, "newCtrs%d=%b\n", i.U, newCtrs(i))
123  }
124
125}
126