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