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 chisel3.experimental.chiselName 25 26trait BimParams extends HasXSParameter { 27 val bimSize = 2048 28 val bypassEntries = 4 29} 30 31@chiselName 32class BIM(implicit p: Parameters) extends BasePredictor with BimParams with BPUUtils { 33 val bimAddr = new TableAddr(log2Up(bimSize), 1) 34 35 val bim = Module(new SRAMTemplate(UInt(2.W), set = bimSize, way=numBr, shouldReset = false, holdRead = true)) 36 37 val doing_reset = RegInit(true.B) 38 val resetRow = RegInit(0.U(log2Ceil(bimSize).W)) 39 resetRow := resetRow + doing_reset 40 when (resetRow === (bimSize-1).U) { doing_reset := false.B } 41 42 val s0_idx = bimAddr.getIdx(s0_pc) 43 44 bim.io.r.req.valid := io.s0_fire 45 bim.io.r.req.bits.setIdx := s0_idx 46 47 io.in.ready := bim.io.r.req.ready 48 io.s1_ready := bim.io.r.req.ready 49 50 val s1_read = bim.io.r.resp.data 51 52 io.out.resp := io.in.bits.resp_in(0) 53 54 val s1_latch_taken_mask = VecInit(Cat((0 until numBr reverse).map(i => s1_read(i)(1))).asBools()) 55 val s1_latch_meta = s1_read.asUInt() 56 override val meta_size = s1_latch_meta.getWidth 57 58 io.out.resp.s1.preds.br_taken_mask := s1_latch_taken_mask 59 io.out.resp.s2.preds.br_taken_mask := RegEnable(s1_latch_taken_mask, 0.U.asTypeOf(Vec(numBr, Bool())), io.s1_fire) 60 61 io.out.resp.s3.preds.br_taken_mask := RegEnable(RegEnable(s1_latch_taken_mask, io.s1_fire), io.s2_fire) 62 io.out.s3_meta := RegEnable(RegEnable(s1_latch_meta, io.s1_fire), io.s2_fire) 63 64 // Update logic 65 val u_valid = RegNext(io.update.valid) 66 val update = RegNext(io.update.bits) 67 val u_idx = bimAddr.getIdx(update.pc) 68 69 val update_mask = LowerMask(PriorityEncoderOH(update.preds.br_taken_mask.asUInt)) 70 val newCtrs = Wire(Vec(numBr, UInt(2.W))) 71 val need_to_update = VecInit((0 until numBr).map(i => u_valid && update.ftb_entry.brValids(i) && update_mask(i))) 72 73 74 // Bypass logic 75 val wrbypass = Module(new WrBypass(UInt(2.W), bypassEntries, log2Up(bimSize), numWays = numBr)) 76 wrbypass.io.wen := need_to_update.reduce(_||_) 77 wrbypass.io.write_idx := u_idx 78 wrbypass.io.write_data := newCtrs 79 wrbypass.io.write_way_mask.map(_ := need_to_update) 80 81 val oldCtrs = 82 VecInit((0 until numBr).map(i => 83 Mux(wrbypass.io.hit && wrbypass.io.hit_data(i).valid, 84 wrbypass.io.hit_data(i).bits, 85 update.meta(2*i+1, 2*i)) 86 )) 87 88 val newTakens = update.preds.br_taken_mask 89 newCtrs := VecInit((0 until numBr).map(i => 90 satUpdate(oldCtrs(i), 2, newTakens(i)) 91 )) 92 93 94 bim.io.w.apply( 95 valid = need_to_update.asUInt.orR || doing_reset, 96 data = Mux(doing_reset, VecInit(Seq.fill(numBr)(2.U(2.W))), newCtrs), 97 setIdx = Mux(doing_reset, resetRow, u_idx), 98 waymask = Mux(doing_reset, Fill(numBr, 1.U(1.W)).asUInt(), need_to_update.asUInt()) 99 ) 100 101 val latch_s0_fire = RegNext(io.s0_fire) 102 103 XSDebug(doing_reset, "Doing reset...\n") 104 105 XSDebug(io.s0_fire, "req_pc=%x, req_idx=%d\n", s0_pc, s0_idx) 106 107 for(i <- 0 until numBr) { 108 XSDebug(latch_s0_fire, "last_cycle req %d: ctr=%b\n", i.U, s1_read(i)) 109 } 110 111 XSDebug(u_valid, "update_pc=%x, update_idx=%d, is_br=%b\n", update.pc, u_idx, update.ftb_entry.brValids.asUInt) 112 113 XSDebug(u_valid, "newTakens=%b\n", newTakens.asUInt) 114 115 for(i <- 0 until numBr) { 116 XSDebug(u_valid, "oldCtrs%d=%b\n", i.U, oldCtrs(i)) 117 } 118 119 for(i <- 0 until numBr) { 120 XSDebug(u_valid, "newCtrs%d=%b\n", i.U, newCtrs(i)) 121 } 122 123} 124