diff --git a/src/main/scala/utils/DataModuleTemplate.scala b/src/main/scala/utils/DataModuleTemplate.scala index 4d16bcb43c0408e3db532de36599a23ddf59930a..3e7861ed2ca95e6e93fad24cbaeef3cc3ac47fe4 100644 --- a/src/main/scala/utils/DataModuleTemplate.scala +++ b/src/main/scala/utils/DataModuleTemplate.scala @@ -86,13 +86,15 @@ class DataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWr class SyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int) extends DataModuleTemplate(gen, numEntries, numRead, numWrite, true) class AsyncDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, numWrite: Int) extends DataModuleTemplate(gen, numEntries, numRead, numWrite, false) -class Folded1WDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, isSync: Boolean, width: Int) extends Module { +class Folded1WDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: Int, + isSync: Boolean, width: Int, hasResetEn: Boolean = true) extends Module { val io = IO(new Bundle { val raddr = Vec(numRead, Input(UInt(log2Up(numEntries).W))) val rdata = Vec(numRead, Output(gen)) val wen = Input(Bool()) val waddr = Input(UInt(log2Up(numEntries).W)) val wdata = Input(gen) + val resetEn = if (hasResetEn) Some(Input(Bool())) else None }) require(width > 0 && isPow2(width)) @@ -103,6 +105,9 @@ class Folded1WDataModuleTemplate[T <: Data](gen: T, numEntries: Int, numRead: In val data = Mem(nRows, Vec(width, gen)) val doing_reset = RegInit(true.B) + if (hasResetEn) { + io.resetEn.map(en => when (en) { doing_reset := true.B }) + } val resetRow = RegInit(0.U(log2Ceil(nRows).W)) resetRow := resetRow + doing_reset when (resetRow === (nRows-1).U) { doing_reset := false.B } diff --git a/src/main/scala/utils/SRAMTemplate.scala b/src/main/scala/utils/SRAMTemplate.scala index bb1044f8bcbcc2176596542dafcd3dd11eac8fbb..1d4677d9c2aa3307e317a025e8832090cc8f732c 100644 --- a/src/main/scala/utils/SRAMTemplate.scala +++ b/src/main/scala/utils/SRAMTemplate.scala @@ -168,7 +168,7 @@ class FoldedSRAMTemplate[T <: Data](gen: T, set: Int, width: Int = 4, io.w.req.ready := array.io.w.req.ready val raddr = io.r.req.bits.setIdx >> log2Ceil(width) - val ridx = RegNext(io.r.req.bits.setIdx(log2Ceil(width)-1, 0)) + val ridx = RegNext(if (width != 1) io.r.req.bits.setIdx(log2Ceil(width)-1, 0) else 0.U(1.W)) val ren = io.r.req.valid array.io.r.req.valid := ren @@ -178,7 +178,7 @@ class FoldedSRAMTemplate[T <: Data](gen: T, set: Int, width: Int = 4, val wen = io.w.req.valid val wdata = VecInit(Seq.fill(width)(io.w.req.bits.data(0))) val waddr = io.w.req.bits.setIdx >> log2Ceil(width) - val wmask = UIntToOH(io.w.req.bits.setIdx(log2Ceil(width)-1, 0)) + val wmask = UIntToOH(if (width != 1) io.w.req.bits.setIdx(log2Ceil(width)-1, 0) else 1.U(1.W)) array.io.w.apply(wen, wdata, waddr, wmask) } diff --git a/src/main/scala/xiangshan/frontend/ITTAGE.scala b/src/main/scala/xiangshan/frontend/ITTAGE.scala index a607038e4708d6000a294943f100470d7127ba2a..aa3f0ae906674911a2d6ffe986f6403e16ee401e 100644 --- a/src/main/scala/xiangshan/frontend/ITTAGE.scala +++ b/src/main/scala/xiangshan/frontend/ITTAGE.scala @@ -36,7 +36,7 @@ trait ITTageParams extends HasXSParameter with HasBPUParameter { val ITTageNTables = ITTageTableInfos.size // Number of tage tables val UBitPeriod = 2048 val ITTageCtrBits = 2 - val uFoldedWidth = 8 + val uFoldedWidth = 16 val TickWidth = 8 def ctr_null(ctr: UInt, ctrBits: Int = ITTageCtrBits) = { ctr === 0.U @@ -149,11 +149,23 @@ class ITTageTable )(implicit p: Parameters) extends ITTageModule with HasFoldedHistory { val io = IO(new Bundle() { - val req = Input(Valid(new ITTageReq)) + val req = Flipped(DecoupledIO(new ITTageReq)) val resp = Output(Valid(new ITTageResp)) val update = Input(new ITTageUpdate) }) + val SRAM_SIZE=128 + val nBanks = 2 + val bankSize = nRows / nBanks + val bankFoldWidth = if (bankSize >= SRAM_SIZE) bankSize / SRAM_SIZE else 1 + + if (bankSize < SRAM_SIZE) { + println(f"warning: ittage table $tableIdx has small sram depth of $bankSize") + } + val bankIdxWidth = log2Ceil(nBanks) + def get_bank_mask(idx: UInt) = VecInit((0 until nBanks).map(idx(bankIdxWidth-1, 0) === _.U)) + def get_bank_idx(idx: UInt) = idx >> bankIdxWidth + // override val debug = true // bypass entries for tage update val wrBypassEntries = 4 @@ -186,12 +198,14 @@ class ITTageTable def inc_ctr(ctr: UInt, taken: Bool): UInt = satUpdate(ctr, ITTageCtrBits, taken) class ITTageEntry() extends ITTageBundle { - val valid = Bool() + // val valid = Bool() val tag = UInt(tagLen.W) val ctr = UInt(ITTageCtrBits.W) val target = UInt(VAddrBits.W) } + val validArray = RegInit(0.U(nRows.W)) + // Why need add instOffsetBits? val ittageEntrySz = 1 + tagLen + ITTageCtrBits + VAddrBits @@ -204,60 +218,58 @@ class ITTageTable // val (s0_idx, s0_tag) = compute_tag_and_hash(s0_unhashed_idx, io.req.bits.hist, io.req.bits.phist) val (s0_idx, s0_tag) = compute_tag_and_hash(s0_unhashed_idx, io.req.bits.folded_hist) - val (s1_idx, s1_tag) = (RegEnable(s0_idx, io.req.valid), RegEnable(s0_tag, io.req.valid)) - - val us = Module(new SyncDataModuleTemplate(Bool(), nRows, 1, 1)) - val table = Module(new SRAMTemplate(new ITTageEntry, set=nRows, way=1, shouldReset=true, holdRead=true, singlePort=false)) - - table.io.r.req.valid := io.req.valid - table.io.r.req.bits.setIdx := s0_idx + val (s1_idx, s1_tag) = (RegEnable(s0_idx, io.req.fire), RegEnable(s0_tag, io.req.fire)) + val s0_bank_req_1h = get_bank_mask(s0_idx) + val s1_bank_req_1h = RegEnable(s0_bank_req_1h, io.req.fire) + + val us = Module(new Folded1WDataModuleTemplate(Bool(), nRows, 1, isSync=true, width=uFoldedWidth)) + // val table = Module(new SRAMTemplate(new ITTageEntry, set=nRows, way=1, shouldReset=true, holdRead=true, singlePort=false)) + val table_banks = Seq.fill(nBanks)( + Module(new FoldedSRAMTemplate(new ITTageEntry, set=nRows/nBanks, width=bankFoldWidth, shouldReset=false, holdRead=true, singlePort=true))) + + for (b <- 0 until nBanks) { + table_banks(b).io.r.req.valid := io.req.fire && s0_bank_req_1h(b) + table_banks(b).io.r.req.bits.setIdx := get_bank_idx(s0_idx) + } us.io.raddr(0) := s0_idx - val s1_table_r = table.io.r.resp.data(0) + val table_banks_r = table_banks.map(_.io.r.resp.data(0)) - - val s1_req_rhit = s1_table_r.valid && s1_table_r.tag === s1_tag + val resp_selected = Mux1H(s1_bank_req_1h, table_banks_r) + val s1_req_rhit = validArray(s1_idx) && resp_selected.tag === s1_tag io.resp.valid := (if (tagLen != 0) s1_req_rhit else true.B) // && s1_mask(b) - io.resp.bits.ctr := s1_table_r.ctr + io.resp.bits.ctr := resp_selected.ctr io.resp.bits.u := us.io.rdata(0) - io.resp.bits.target := s1_table_r.target - - // TODO: reset all us at once? - val doing_reset_u = RegInit(true.B) - val resetRow = RegInit(0.U(log2Ceil(nRows).W)) - resetRow := resetRow + doing_reset_u - when (io.update.reset_u) { - doing_reset_u := true.B - }.elsewhen (resetRow === (nRows-1).U) { - doing_reset_u := false.B - } + io.resp.bits.target := resp_selected.target + // Use fetchpc to compute hash // val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.hist, io.update.phist) val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.folded_hist) + val update_req_bank_1h = get_bank_mask(update_idx) + val update_idx_in_bank = get_bank_idx(update_idx) val update_target = io.update.target - val update_wdata = Wire(new ITTageEntry) + + for (b <- 0 until nBanks) { + table_banks(b).io.w.apply( + valid = io.update.valid && update_req_bank_1h(b), + data = update_wdata, + setIdx = update_idx_in_bank, + waymask = true.B + ) + } - table.io.w.apply( - valid = io.update.valid, - data = update_wdata, - setIdx = update_idx, - waymask = io.update.valid - ) - - val update_u = io.update.u - - val u_wen = io.update.uValid || doing_reset_u - val u_waddr = Mux(doing_reset_u, resetRow, update_idx) - val u_wdata = Mux(doing_reset_u, false.B, update_u) + val bank_conflict = (0 until nBanks).map(b => table_banks(b).io.w.req.valid && s0_bank_req_1h(b)).reduce(_||_) + io.req.ready := !bank_conflict + XSPerfAccumulate(f"ittage_table_bank_conflict", bank_conflict) - us.io.wen(0) := u_wen - us.io.waddr(0) := u_waddr - us.io.wdata(0) := u_wdata + us.io.wen := io.update.uValid + us.io.waddr := update_idx + us.io.wdata := io.update.u val wrbypass = Module(new WrBypass(UInt(ITTageCtrBits.W), wrBypassEntries, log2Ceil(nRows), tagWidth=tagLen)) @@ -268,21 +280,30 @@ class ITTageTable val old_ctr = Mux(wrbypass.io.hit, wrbypass.io.hit_data(0).bits, io.update.oldCtr) update_wdata.ctr := Mux(io.update.alloc, 2.U, inc_ctr(old_ctr, io.update.correct)) - update_wdata.valid := true.B update_wdata.tag := update_tag // only when ctr is null update_wdata.target := Mux(ctr_null(old_ctr), update_target, io.update.old_target) + + val newValidArray = VecInit(validArray.asBools) + when (io.update.valid) { + newValidArray(update_idx) := true.B + validArray := newValidArray.asUInt + } + // reset all us in 32 cycles + us.io.resetEn.map(_ := io.update.reset_u) + + XSPerfAccumulate("ittage_table_updates", io.update.valid) XSPerfAccumulate("ittage_table_hits", io.resp.valid) if (BPUDebug && debug) { val u = io.update val idx = s0_idx val tag = s0_tag - XSDebug(io.req.valid, + XSDebug(io.req.fire, p"ITTageTableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, " + p"idx=$idx, tag=$tag\n") - XSDebug(RegNext(io.req.valid) && s1_req_rhit, + XSDebug(RegNext(io.req.fire) && s1_req_rhit, p"ITTageTableResp: idx=$s1_idx, hit:${s1_req_rhit}, " + p"ctr:${io.resp.bits.ctr}, u:${io.resp.bits.u}, tar:${Hexadecimal(io.resp.bits.target)}\n") XSDebug(io.update.valid, @@ -293,7 +314,7 @@ class ITTageTable p"update ITTAGE Table: writing tag:${update_tag}, " + p"ctr: ${update_wdata.ctr}, target:${Hexadecimal(update_wdata.target)}" + p" in idx $update_idx\n") - XSDebug(RegNext(io.req.valid) && !s1_req_rhit, "TageTableResp: no hits!\n") + XSDebug(RegNext(io.req.fire) && !s1_req_rhit, "TageTableResp: no hits!\n") // ------------------------------Debug------------------------------------- @@ -342,11 +363,6 @@ class ITTage(implicit p: Parameters) extends BaseITTage { case ((nRows, histLen, tagLen), i) => // val t = if(EnableBPD) Module(new TageTable(nRows, histLen, tagLen, UBitPeriod)) else Module(new FakeTageTable) val t = Module(new ITTageTable(nRows, histLen, tagLen, UBitPeriod, i)) - // t.io.req.valid := io.pc.valid - // t.io.req.bits.pc := io.pc.bits - // t.io.req.bits.hist := io.hist - // t.io.req.bits.mask := io.inMask - t.io.req.valid := io.s0_fire t.io.req.bits.pc := s0_pc t.io.req.bits.folded_hist := io.in.bits.folded_hist @@ -620,6 +636,9 @@ class ITTage(implicit p: Parameters) extends BaseITTage { tables(i).io.update.folded_hist := RegNext(updateFhist) } + // all should be ready for req + io.s1_ready := tables.map(_.io.req.ready).reduce(_&&_) + XSPerfAccumulate(f"ittage_write_blocks_read", !io.s1_ready) // Debug and perf info def pred_perf(name: String, cond: Bool) = XSPerfAccumulate(s"${name}_at_pred", cond && io.s2_fire) diff --git a/src/main/scala/xiangshan/frontend/Tage.scala b/src/main/scala/xiangshan/frontend/Tage.scala index e6ff7129033e8892bdaac4b3bc717ff525489296..bb54180c5eeb9724e06fda9b47e43117ce488035 100644 --- a/src/main/scala/xiangshan/frontend/Tage.scala +++ b/src/main/scala/xiangshan/frontend/Tage.scala @@ -36,9 +36,11 @@ trait TageParams extends HasBPUConst with HasXSParameter { val BankTageNTables = BankTageTableInfos.map(_.size) // Number of tage tables val UBitPeriod = 256 val TageCtrBits = 3 - val uFoldedWidth = 8 + val uFoldedWidth = 32 val TickWidth = 8 + + val TotalBits = BankTageTableInfos.map { info => info.map{ case (s, h, t) => { @@ -46,6 +48,7 @@ trait TageParams extends HasBPUConst with HasXSParameter { } }.reduce(_+_) }.reduce(_+_) + } trait HasFoldedHistory { @@ -214,37 +217,29 @@ class TageTable )(implicit p: Parameters) extends TageModule with HasFoldedHistory { val io = IO(new Bundle() { - val req = Input(Valid(new TageReq)) + val req = Flipped(DecoupledIO(new TageReq)) val resp = Output(Valid(new TageResp)) val update = Input(new TageUpdate) }) + + + val SRAM_SIZE = 128 // physical size + require(nRows % SRAM_SIZE == 0) + val nBanks = 4 + val bankSize = nRows / nBanks + val bankFoldWidth = if (bankSize >= SRAM_SIZE) bankSize / SRAM_SIZE else 1 + + if (bankSize < SRAM_SIZE) { + println(f"warning: tage table $tableIdx has small sram depth of $bankSize") + } + val bankIdxWidth = log2Ceil(nBanks) + def get_bank_mask(idx: UInt) = VecInit((0 until nBanks).map(idx(bankIdxWidth-1, 0) === _.U)) + def get_bank_idx(idx: UInt) = idx >> bankIdxWidth + // bypass entries for tage update val wrBypassEntries = 8 val phistLen = if (PathHistoryLength > histLen) histLen else PathHistoryLength - // def compute_tag_and_hash(unhashed_idx: UInt, hist: UInt, phist: UInt) = { - // def F(phist: UInt, len: Int) = { - // val lenMask = Fill(len, 1.U(1.W)) - // val rowMask = Fill(log2Ceil(nRows), 1.U(1.W)) - // val masked = phist & lenMask - // val a1 = masked & rowMask - // val a2 = masked >> log2Ceil(nRows) - // val a3 = ((a2 << tableIdx) & rowMask) + (a2 >> (log2Ceil(nRows) - tableIdx)) - // val a4 = a1 ^ a3 - // val res = ((a3 << tableIdx) & rowMask) + (a3 >> (log2Ceil(nRows) - tableIdx)) - // res - // } - // val idx_history = compute_folded_ghist(hist, log2Ceil(nRows)) - // val idx_phist = F(phist, (if (PathHistoryLength > histLen) histLen else PathHistoryLength)) - // // val idx = (unhashed_idx ^ (unhashed_idx >> (log2Ceil(nRows)-tableIdx+1)) ^ idx_history ^ idx_phist)(log2Ceil(nRows) - 1, 0) - // val idx = (unhashed_idx ^ idx_history)(log2Ceil(nRows) - 1, 0) - // val tag_history = compute_folded_ghist(hist, tagLen) - // val alt_tag_history = compute_folded_ghist(hist, tagLen-1) - // // Use another part of pc to make tags - // val tag = ((unhashed_idx >> log2Ceil(nRows)) ^ tag_history ^ (alt_tag_history << 1)) (tagLen - 1, 0) - // (idx, tag) - // } - val idxFhInfo = (histLen, min(log2Ceil(nRows), histLen)) val tagFhInfo = (histLen, min(histLen, tagLen)) @@ -265,14 +260,13 @@ class TageTable def inc_ctr(ctr: UInt, taken: Bool): UInt = satUpdate(ctr, TageCtrBits, taken) class TageEntry() extends TageBundle { - val valid = Bool() + // val valid = Bool() val tag = UInt(tagLen.W) val ctr = UInt(TageCtrBits.W) } - // Why need add instOffsetBits? - // val tageEntrySz = instOffsetBits + tagLen + TageCtrBits - val tageEntrySz = 1 + tagLen + TageCtrBits + val validArray = RegInit(0.U(nRows.W)) + // pc is start address of basic block, most 2 branch inst in block // def getUnhashedIdx(pc: UInt) = pc >> (instOffsetBits+log2Ceil(TageBanks)) @@ -281,42 +275,41 @@ class TageTable // val s1_pc = io.req.bits.pc val req_unhashed_idx = getUnhashedIdx(io.req.bits.pc) - val us = Module(new SyncDataModuleTemplate(Bool(), nRows, 1, 1)) + val us = Module(new Folded1WDataModuleTemplate(Bool(), nRows, 1, isSync=true, width=uFoldedWidth)) - val table = Module(new SRAMTemplate(new TageEntry, set=nRows, way=1, shouldReset=true, holdRead=true, singlePort=false)) + val table_banks = Seq.fill(nBanks)( + Module(new FoldedSRAMTemplate(new TageEntry, set=nRows/nBanks, width=bankFoldWidth, shouldReset=false, holdRead=true, singlePort=true))) + // val table = Module(new SRAMTemplate(new TageEntry, set=nRows, way=1, shouldReset=false, holdRead=true, singlePort=false)) val (s0_idx, s0_tag) = compute_tag_and_hash(req_unhashed_idx, io.req.bits.folded_hist) + val s0_bank_req_1h = get_bank_mask(s0_idx) - table.io.r.req.valid := io.req.valid - table.io.r.req.bits.setIdx := s0_idx + for (b <- 0 until nBanks) { + table_banks(b).io.r.req.valid := io.req.fire && s0_bank_req_1h(b) + table_banks(b).io.r.req.bits.setIdx := get_bank_idx(s0_idx) + } us.io.raddr(0) := s0_idx // us.io.raddr(1) := DontCare // us.io.raddr(2) := DontCare - val s1_idx = RegEnable(s0_idx, io.req.valid) - val s1_tag = RegEnable(s0_tag, io.req.valid) + val s1_idx = RegEnable(s0_idx, io.req.fire) + val s1_tag = RegEnable(s0_tag, io.req.fire) + val s1_bank_req_1h = RegEnable(s0_bank_req_1h, io.req.fire) - val table_r = table.io.r.resp.data(0) // s1 + val tables_r = table_banks.map(_.io.r.resp.data(0)) // s1 - val req_rhit = table_r.valid && table_r.tag === s1_tag + val resp_selected = Mux1H(s1_bank_req_1h, tables_r) + val req_rhit = validArray(s1_idx) && resp_selected.tag === s1_tag io.resp.valid := req_rhit - io.resp.bits.ctr := table_r.ctr + io.resp.bits.ctr := resp_selected.ctr io.resp.bits.u := us.io.rdata(0) - - // TODO: reset all us at once? - val doing_reset_u = RegInit(true.B) - val resetRow = RegInit(0.U(log2Ceil(nRows).W)) - resetRow := resetRow + doing_reset_u - when (io.update.reset_u) { - doing_reset_u := true.B - }.elsewhen (resetRow === (nRows-1).U) { - doing_reset_u := false.B - } + // reset all us in 32 cycles + us.io.resetEn.map(_ := io.update.reset_u) // Use fetchpc to compute hash @@ -324,40 +317,59 @@ class TageTable // val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.hist, io.update.phist) val (update_idx, update_tag) = compute_tag_and_hash(getUnhashedIdx(io.update.pc), io.update.folded_hist) + val update_req_bank_1h = get_bank_mask(update_idx) + val update_idx_in_bank = get_bank_idx(update_idx) - table.io.w.apply( - valid = io.update.mask, - data = update_wdata, - setIdx = update_idx, - waymask = true.B - ) + val not_silent_update = Wire(Bool()) + + for (b <- 0 until nBanks) { + table_banks(b).io.w.apply( + valid = io.update.mask && update_req_bank_1h(b) && not_silent_update, + data = update_wdata, + setIdx = update_idx_in_bank, + waymask = true.B + ) + } + val bank_conflict = (0 until nBanks).map(b => table_banks(b).io.w.req.valid && s0_bank_req_1h(b)).reduce(_||_) + io.req.ready := !bank_conflict + XSPerfAccumulate(f"tage_table_bank_conflict", bank_conflict) - val update_u = io.update.u - val u_wen = io.update.uMask || doing_reset_u - val u_waddr = Mux(doing_reset_u, resetRow, update_idx) - val u_wdata = Mux(doing_reset_u, false.B, update_u) + val newValidArray = VecInit(validArray.asBools) + when (io.update.mask) { + newValidArray(update_idx) := true.B + validArray := newValidArray.asUInt + } - us.io.wen(0) := u_wen - us.io.waddr(0) := u_waddr - us.io.wdata(0) := u_wdata + us.io.wen := io.update.uMask + us.io.waddr := update_idx + us.io.wdata := io.update.u val wrbypass = Module(new WrBypass(UInt(TageCtrBits.W), wrBypassEntries, log2Ceil(nRows), tagWidth=tagLen)) - wrbypass.io.wen := io.update.mask + wrbypass.io.wen := io.update.mask && not_silent_update wrbypass.io.write_data.map(_ := update_wdata.ctr) + val bypass_ctr = wrbypass.io.hit_data(0).bits update_wdata.ctr := Mux(io.update.alloc, Mux(io.update.taken, 4.U, 3.U), Mux(wrbypass.io.hit, - inc_ctr(wrbypass.io.hit_data(0).bits, io.update.taken), + inc_ctr(bypass_ctr, io.update.taken), inc_ctr(io.update.oldCtr, io.update.taken) ) ) - update_wdata.valid := true.B update_wdata.tag := update_tag + // remove silent updates + def silentUpdate(ctr: UInt, taken: Bool) = { + ctr.andR && taken || !ctr.orR && !taken + } + not_silent_update := + Mux(wrbypass.io.hit, + !silentUpdate(bypass_ctr, io.update.taken), + !silentUpdate(io.update.oldCtr, io.update.taken)) || + io.update.alloc wrbypass.io.write_idx := update_idx wrbypass.io.write_tag.map(_ := update_tag) @@ -367,16 +379,18 @@ class TageTable XSPerfAccumulate(f"tage_table_wrbypass_hit", io.update.mask && wrbypass.io.hit) XSPerfAccumulate(f"tage_table_wrbypass_enq", io.update.mask && !wrbypass.io.hit) + XSPerfAccumulate(f"tage_table_real_updates", io.update.mask && not_silent_update) + XSPerfAccumulate(f"tage_table_silent_updates_eliminated", io.update.mask && !not_silent_update) XSPerfAccumulate("tage_table_hits", PopCount(io.resp.valid)) val u = io.update val b = PriorityEncoder(u.mask) val ub = PriorityEncoder(u.uMask) - XSDebug(io.req.valid, + XSDebug(io.req.fire, p"tableReq: pc=0x${Hexadecimal(io.req.bits.pc)}, " + p"idx=$s0_idx, tag=$s0_tag\n") - XSDebug(RegNext(io.req.valid) && req_rhit, + XSDebug(RegNext(io.req.fire) && req_rhit, p"TageTableResp: idx=$s1_idx, hit:$req_rhit, " + p"ctr:${io.resp.bits.ctr}, u:${io.resp.bits.u}\n") XSDebug(io.update.mask, @@ -385,7 +399,7 @@ class TageTable XSDebug(io.update.mask, p"update Table: writing tag:$update_tag, " + p"ctr: ${update_wdata.ctr} in idx ${update_idx}\n") - XSDebug(RegNext(io.req.valid) && !req_rhit, "TageTableResp: not hit!\n") + XSDebug(RegNext(io.req.fire) && !req_rhit, "TageTableResp: not hit!\n") // ------------------------------Debug------------------------------------- val valids = Reg(Vec(nRows, Bool())) @@ -655,6 +669,7 @@ class Tage(implicit p: Parameters) extends BaseTage { } XSPerfAccumulate(s"tage_bank_${w}_reset_u", updateResetU(w)) + XSPerfAccumulate(s"tage_bank_${w}_mispred", updateValid && updateMisPred) } @@ -684,6 +699,10 @@ class Tage(implicit p: Parameters) extends BaseTage { bt.io.update.valid := RegNext(baseupdate.reduce(_||_)) bt.io.update_cnt := RegNext(updatebcnt) + // all should be ready for req + io.s1_ready := bank_tables.flatMap(_.map(_.io.req.ready)).reduce(_&&_) + XSPerfAccumulate(f"tage_write_blocks_read", !io.s1_ready) + def pred_perf(name: String, cnt: UInt) = XSPerfAccumulate(s"${name}_at_pred", cnt) def commit_perf(name: String, cnt: UInt) = XSPerfAccumulate(s"${name}_at_commit", cnt) def tage_perf(name: String, pred_cnt: UInt, commit_cnt: UInt) = {