未验证 提交 b3064620 编写于 作者: E Easton Man 提交者: GitHub

bpu: add plru replacer to WrBypass (#2050)

* bpu: add plru replacer in wrbypass

also remove tag in Tage and ITTage wrbypass

* tage: fix idx width

* bpu: wrbypass cleanup and add comments about shared replacer

* bpu: fix code style
上级 57ce618e
......@@ -273,11 +273,10 @@ class ITTageTable
us.io.waddr := update_idx
us.io.wdata := io.update.u
val wrbypass = Module(new WrBypass(UInt(ITTageCtrBits.W), wrBypassEntries, log2Ceil(nRows), tagWidth=tagLen))
val wrbypass = Module(new WrBypass(UInt(ITTageCtrBits.W), wrBypassEntries, log2Ceil(nRows)))
wrbypass.io.wen := io.update.valid
wrbypass.io.write_idx := update_idx
wrbypass.io.write_tag.map(_ := update_tag)
wrbypass.io.write_data.map(_ := update_wdata.ctr)
val old_ctr = Mux(wrbypass.io.hit, wrbypass.io.hit_data(0).bits, io.update.oldCtr)
......
......@@ -420,7 +420,7 @@ class TageTable
}
val bank_wrbypasses = Seq.fill(nBanks)(Seq.fill(numBr)(
Module(new WrBypass(UInt(TageCtrBits.W), perBankWrbypassEntries, 1, tagWidth=tagLen))
Module(new WrBypass(UInt(TageCtrBits.W), perBankWrbypassEntries, log2Ceil(bankSize)))
)) // let it corresponds to logical brIdx
for (b <- 0 until nBanks) {
......@@ -456,7 +456,6 @@ class TageTable
val br_pidx = get_phy_br_idx(update_unhashed_idx, li)
wrbypass.io.wen := io.update.mask(li) && update_req_bank_1h(b)
wrbypass.io.write_idx := get_bank_idx(update_idx)
wrbypass.io.write_tag.map(_ := update_tag)
wrbypass.io.write_data(0) := Mux1H(UIntToOH(br_pidx, numBr), per_bank_update_wdata(b)).ctr
}
}
......
......@@ -43,9 +43,6 @@ class WrBypass[T <: Data](gen: T, val numEntries: Int, val idxWidth: Int,
val hit_data = Vec(numWays, Valid(gen))
})
class WrBypassPtr extends CircularQueuePtr[WrBypassPtr](numEntries){
}
class Idx_Tag extends Bundle {
val idx = UInt(idxWidth.W)
val tag = if (hasTag) Some(UInt(tagWidth.W)) else None
......@@ -60,8 +57,6 @@ class WrBypass[T <: Data](gen: T, val numEntries: Int, val idxWidth: Int,
val valids = RegInit(0.U.asTypeOf(Vec(numEntries, Vec(numWays, Bool()))))
val ever_written = RegInit(0.U.asTypeOf(Vec(numEntries, Bool())))
val enq_ptr = RegInit(0.U.asTypeOf(new WrBypassPtr))
val enq_idx = enq_ptr.value
idx_tag_cam.io.r.req(0)(io.write_idx, io.write_tag.getOrElse(0.U))
val hits_oh = idx_tag_cam.io.r.resp(0).zip(ever_written).map {case (h, ew) => h && ew}
......@@ -74,6 +69,13 @@ class WrBypass[T <: Data](gen: T, val numEntries: Int, val idxWidth: Int,
io.hit_data(i).bits := data_mem.read(hit_idx)(i)
}
// Replacer
// Because data_mem can only write to one index
// Implementing a per-way replacer is meaningless
// So here use one replacer for all ways
val replacer = ReplacementPolicy.fromString("plru", numEntries) // numEntries in total
val replacer_touch_ways = Wire(Vec(1, Valid(UInt(log2Ceil(numEntries).W)))) // One index at a time
val enq_idx = replacer.way
val full_mask = Fill(numWays, 1.U(1.W)).asTypeOf(Vec(numWays, Bool()))
val update_way_mask = io.write_way_mask.getOrElse(full_mask)
......@@ -82,6 +84,9 @@ class WrBypass[T <: Data](gen: T, val numEntries: Int, val idxWidth: Int,
val data_write_idx = Mux(hit, hit_idx, enq_idx)
data_mem.write(data_write_idx, io.write_data, update_way_mask)
}
replacer_touch_ways(0).valid := io.wen
replacer_touch_ways(0).bits := Mux(hit, hit_idx, enq_idx)
replacer.access(replacer_touch_ways)
// update valids
for (i <- 0 until numWays) {
......@@ -104,7 +109,6 @@ class WrBypass[T <: Data](gen: T, val numEntries: Int, val idxWidth: Int,
idx_tag_cam.io.w.valid := enq_en
idx_tag_cam.io.w.bits.index := enq_idx
idx_tag_cam.io.w.bits.data(io.write_idx, io.write_tag.getOrElse(0.U))
enq_ptr := enq_ptr + enq_en
XSPerfAccumulate("wrbypass_hit", io.wen && hit)
XSPerfAccumulate("wrbypass_miss", io.wen && !hit)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册