xref: /XiangShan/src/main/scala/xiangshan/frontend/Bim.scala (revision 803124a63779cc65b44dd1b8b1d848bb8407a6ac)
109c6f1ddSLingrui98/***************************************************************************************
209c6f1ddSLingrui98* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
309c6f1ddSLingrui98* Copyright (c) 2020-2021 Peng Cheng Laboratory
409c6f1ddSLingrui98*
509c6f1ddSLingrui98* XiangShan is licensed under Mulan PSL v2.
609c6f1ddSLingrui98* You can use this software according to the terms and conditions of the Mulan PSL v2.
709c6f1ddSLingrui98* You may obtain a copy of Mulan PSL v2 at:
809c6f1ddSLingrui98*          http://license.coscl.org.cn/MulanPSL2
909c6f1ddSLingrui98*
1009c6f1ddSLingrui98* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
1109c6f1ddSLingrui98* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1209c6f1ddSLingrui98* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1309c6f1ddSLingrui98*
1409c6f1ddSLingrui98* See the Mulan PSL v2 for more details.
1509c6f1ddSLingrui98***************************************************************************************/
1609c6f1ddSLingrui98
1709c6f1ddSLingrui98package xiangshan.frontend
1809c6f1ddSLingrui98
1909c6f1ddSLingrui98import chipsalliance.rocketchip.config.Parameters
2009c6f1ddSLingrui98import chisel3._
2109c6f1ddSLingrui98import chisel3.util._
2209c6f1ddSLingrui98import xiangshan._
2309c6f1ddSLingrui98import utils._
2409c6f1ddSLingrui98import chisel3.experimental.chiselName
2509c6f1ddSLingrui98
2609c6f1ddSLingrui98trait BimParams extends HasXSParameter {
2709c6f1ddSLingrui98  val bimSize = 2048
2809c6f1ddSLingrui98  val bypassEntries = 4
2909c6f1ddSLingrui98}
3009c6f1ddSLingrui98
3109c6f1ddSLingrui98@chiselName
3209c6f1ddSLingrui98class BIM(implicit p: Parameters) extends BasePredictor with BimParams with BPUUtils {
3309c6f1ddSLingrui98  val bimAddr = new TableAddr(log2Up(bimSize), 1)
3409c6f1ddSLingrui98
3509c6f1ddSLingrui98  val bim = Module(new SRAMTemplate(UInt(2.W), set = bimSize, way=numBr, shouldReset = false, holdRead = true))
3609c6f1ddSLingrui98
3709c6f1ddSLingrui98  val doing_reset = RegInit(true.B)
3809c6f1ddSLingrui98  val resetRow = RegInit(0.U(log2Ceil(bimSize).W))
3909c6f1ddSLingrui98  resetRow := resetRow + doing_reset
4009c6f1ddSLingrui98  when (resetRow === (bimSize-1).U) { doing_reset := false.B }
4109c6f1ddSLingrui98
4209c6f1ddSLingrui98  val s0_idx = bimAddr.getIdx(s0_pc)
4309c6f1ddSLingrui98
444dec0a5eSLingrui98  // bim.io.r.req.valid := io.s0_fire
454dec0a5eSLingrui98  bim.io.r.req.valid := false.B
4609c6f1ddSLingrui98  bim.io.r.req.bits.setIdx := s0_idx
4709c6f1ddSLingrui98
4809c6f1ddSLingrui98  io.in.ready := bim.io.r.req.ready
4909c6f1ddSLingrui98  io.s1_ready := bim.io.r.req.ready
5009c6f1ddSLingrui98
5109c6f1ddSLingrui98  val s1_read = bim.io.r.resp.data
5209c6f1ddSLingrui98
5309c6f1ddSLingrui98  io.out.resp := io.in.bits.resp_in(0)
5409c6f1ddSLingrui98
5509c6f1ddSLingrui98  val s1_latch_taken_mask = VecInit(Cat((0 until numBr reverse).map(i => s1_read(i)(1))).asBools())
5609c6f1ddSLingrui98  val s1_latch_meta       = s1_read.asUInt()
5709c6f1ddSLingrui98  override val meta_size = s1_latch_meta.getWidth
5809c6f1ddSLingrui98
594dec0a5eSLingrui98  // io.out.resp.s1.full_pred.br_taken_mask := s1_latch_taken_mask
604dec0a5eSLingrui98  // io.out.resp.s2.full_pred.br_taken_mask := RegEnable(s1_latch_taken_mask, 0.U.asTypeOf(Vec(numBr, Bool())), io.s1_fire)
6109c6f1ddSLingrui98
62cb4f77ceSLingrui98  io.out.last_stage_meta := RegEnable(RegEnable(s1_latch_meta, io.s1_fire), io.s2_fire) // TODO: configurable with total-stages
6309c6f1ddSLingrui98
6409c6f1ddSLingrui98  // Update logic
6509c6f1ddSLingrui98  val u_valid = RegNext(io.update.valid)
6609c6f1ddSLingrui98  val update = RegNext(io.update.bits)
6709c6f1ddSLingrui98  val u_idx = bimAddr.getIdx(update.pc)
6809c6f1ddSLingrui98
69*803124a6SLingrui98  val update_mask = LowerMask(PriorityEncoderOH(update.br_taken_mask.asUInt))
70569b279fSLingrui98  val newCtrs = Wire(Vec(numBr, UInt(2.W)))
71569b279fSLingrui98  val need_to_update = VecInit((0 until numBr).map(i => u_valid && update.ftb_entry.brValids(i) && update_mask(i)))
72569b279fSLingrui98
73569b279fSLingrui98
7409c6f1ddSLingrui98  // Bypass logic
75569b279fSLingrui98  val wrbypass = Module(new WrBypass(UInt(2.W), bypassEntries, log2Up(bimSize), numWays = numBr))
76569b279fSLingrui98  wrbypass.io.wen := need_to_update.reduce(_||_)
77569b279fSLingrui98  wrbypass.io.write_idx := u_idx
78569b279fSLingrui98  wrbypass.io.write_data := newCtrs
79569b279fSLingrui98  wrbypass.io.write_way_mask.map(_ := need_to_update)
8009c6f1ddSLingrui98
81569b279fSLingrui98  val oldCtrs =
82569b279fSLingrui98    VecInit((0 until numBr).map(i =>
83569b279fSLingrui98      Mux(wrbypass.io.hit && wrbypass.io.hit_data(i).valid,
84569b279fSLingrui98        wrbypass.io.hit_data(i).bits,
85569b279fSLingrui98        update.meta(2*i+1, 2*i))
86569b279fSLingrui98    ))
8709c6f1ddSLingrui98
88*803124a6SLingrui98  val newTakens = update.br_taken_mask
89569b279fSLingrui98  newCtrs := VecInit((0 until numBr).map(i =>
9009c6f1ddSLingrui98    satUpdate(oldCtrs(i), 2, newTakens(i))
9109c6f1ddSLingrui98  ))
9209c6f1ddSLingrui98
9309c6f1ddSLingrui98
9409c6f1ddSLingrui98  bim.io.w.apply(
954dec0a5eSLingrui98    valid = false.B,
964dec0a5eSLingrui98    // valid = need_to_update.asUInt.orR || doing_reset,
9709c6f1ddSLingrui98    data = Mux(doing_reset, VecInit(Seq.fill(numBr)(2.U(2.W))), newCtrs),
9809c6f1ddSLingrui98    setIdx = Mux(doing_reset, resetRow, u_idx),
9909c6f1ddSLingrui98    waymask = Mux(doing_reset, Fill(numBr, 1.U(1.W)).asUInt(), need_to_update.asUInt())
10009c6f1ddSLingrui98  )
10109c6f1ddSLingrui98
10209c6f1ddSLingrui98  val latch_s0_fire = RegNext(io.s0_fire)
10309c6f1ddSLingrui98
10409c6f1ddSLingrui98  XSDebug(doing_reset, "Doing reset...\n")
10509c6f1ddSLingrui98
10609c6f1ddSLingrui98  XSDebug(io.s0_fire, "req_pc=%x, req_idx=%d\n", s0_pc, s0_idx)
10709c6f1ddSLingrui98
10809c6f1ddSLingrui98  for(i <- 0 until numBr) {
10909c6f1ddSLingrui98    XSDebug(latch_s0_fire, "last_cycle req %d: ctr=%b\n", i.U, s1_read(i))
11009c6f1ddSLingrui98  }
11109c6f1ddSLingrui98
11209c6f1ddSLingrui98  XSDebug(u_valid, "update_pc=%x, update_idx=%d, is_br=%b\n", update.pc, u_idx, update.ftb_entry.brValids.asUInt)
11309c6f1ddSLingrui98
11409c6f1ddSLingrui98  XSDebug(u_valid, "newTakens=%b\n", newTakens.asUInt)
11509c6f1ddSLingrui98
11609c6f1ddSLingrui98  for(i <- 0 until numBr) {
11709c6f1ddSLingrui98    XSDebug(u_valid, "oldCtrs%d=%b\n", i.U, oldCtrs(i))
11809c6f1ddSLingrui98  }
11909c6f1ddSLingrui98
12009c6f1ddSLingrui98  for(i <- 0 until numBr) {
12109c6f1ddSLingrui98    XSDebug(u_valid, "newCtrs%d=%b\n", i.U, newCtrs(i))
12209c6f1ddSLingrui98  }
12309c6f1ddSLingrui98
12409c6f1ddSLingrui98}
125