提交 5371700e 编写于 作者: Z zoujr

BPU: Fix FTB Replacement bug

上级 c6bf0bff
......@@ -3,7 +3,7 @@ name: EMU Test
on:
push:
branches: [ master, ftb-lru ]
branches: [ master ]
pull_request:
branches: [ master ]
......
......@@ -198,6 +198,7 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
val io = IO(new Bundle {
val req_pc = Flipped(DecoupledIO(UInt(VAddrBits.W)))
val read_resp = Output(new FTBEntry)
val s1_fire = Input(Bool())
// when ftb hit, read_hits.valid is true, and read_hits.bits is OH of hit way
// when ftb not hit, read_hits.valid is false, and read_hits is OH of allocWay
......@@ -224,7 +225,7 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
val read_entries = ftb.io.r.resp.data.map(_.entry)
val read_tags = ftb.io.r.resp.data.map(_.tag)
val total_hits = VecInit((0 until numWays).map(b => read_tags(b) === req_tag && read_entries(b).valid && RegNext(io.req_pc.valid)))
val total_hits = VecInit((0 until numWays).map(b => read_tags(b) === req_tag && read_entries(b).valid && (io.s1_fire || io.update_access)))
val hit = total_hits.reduce(_||_)
// val hit_way_1h = VecInit(PriorityEncoderOH(total_hits))
val hit_way = PriorityEncoder(total_hits)
......@@ -278,10 +279,22 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
// req_tag
// )
def allocWay(valids: UInt, idx: UInt) = {
if (numWays > 1) {
val w = Wire(UInt(log2Up(numWays).W))
val valid = WireInit(valids.andR)
w := Mux(valid, replacer.way(idx), PriorityEncoder(~valids))
w
}else {
val w = WireInit(0.U)
w
}
}
io.read_resp := PriorityMux(total_hits, read_entries) // Mux1H
io.read_hits.valid := hit
// io.read_hits.bits := Mux(hit, hit_way_1h, VecInit(UIntToOH(allocWriteWay).asBools()))
io.read_hits.bits := Mux(hit, hit_way, 0.U)
io.read_hits.bits := hit_way
// XSDebug(!hit, "FTB not hit, alloc a way: %d\n", allocWriteWay)
......@@ -289,10 +302,13 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
val u_valid = io.update_write_data.valid
val u_data = io.update_write_data.bits
val u_idx = ftbAddr.getIdx(io.update_pc)
val u_mask = UIntToOH(Mux(io.update_write_alloc, replacer.way(u_idx), io.update_write_way))
val allocWriteWay = allocWay(VecInit(read_entries.map(_.valid)).asUInt, u_idx)
val u_mask = UIntToOH(Mux(io.update_write_alloc, allocWriteWay, io.update_write_way))
for (i <- 0 until numWays) {
XSPerfAccumulate(f"replace_way$i", io.update_write_alloc && OHToUInt(u_mask) === i.U)
XSPerfAccumulate(f"ftb_replace_way$i", u_valid && io.update_write_alloc && OHToUInt(u_mask) === i.U)
XSPerfAccumulate(f"ftb_replace_way${i}_has_empty", u_valid && io.update_write_alloc && !read_entries.map(_.valid).reduce(_&&_) && OHToUInt(u_mask) === i.U)
XSPerfAccumulate(f"ftb_hit_way$i", hit && !io.update_access && hit_way === i.U)
}
ftb.io.w.apply(u_valid, u_data, u_idx, u_mask)
......@@ -370,7 +386,7 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
}
// assert(!(u_valid && RegNext(u_valid) && update.pc === RegNext(update.pc)))
assert(!(u_valid && RegNext(u_valid)))
// assert(!(u_valid && RegNext(u_valid)))
// val u_way = u_queue.io.deq.bits.hit_way
......@@ -394,7 +410,8 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
ftbBank.io.update_write_way := Mux(update_now, u_meta.writeWay, ftbBank.io.read_hits.bits)
// ftbBank.io.update_write_alloc := Mux(update_now, !u_queue.io.deq.bits.hit, !ftbBank.io.read_hits.valid)
ftbBank.io.update_write_alloc := Mux(update_now, false.B, !ftbBank.io.read_hits.valid)
ftbBank.io.update_access := u_valid && !u_meta.hit
ftbBank.io.update_access := RegNext(u_valid && !u_meta.hit)
ftbBank.io.s1_fire := io.s1_fire
XSDebug("req_v=%b, req_pc=%x, ready=%b (resp at next cycle)\n", io.s0_fire, s0_pc, ftbBank.io.req_pc.ready)
XSDebug("s2_hit=%b, hit_way=%b\n", s2_hit, writeWay.asUInt)
......
......@@ -848,8 +848,8 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
io.toBpu.redirect <> Mux(fromBackendRedirect.valid, fromBackendRedirect, ifuRedirectToBpu)
val do_commit = Wire(Bool())
val canCommit = commPtr =/= ifuWbPtr && !do_commit &&
val may_have_stall_from_bpu = RegInit(false.B)
val canCommit = commPtr =/= ifuWbPtr && !may_have_stall_from_bpu &&
Cat(commitStateQueue(commPtr.value).map(s => {
s === c_invalid || s === c_commited
})).andR()
......@@ -870,21 +870,25 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
// need one cycle to read mem and srams
val do_commit_ptr = RegNext(commPtr)
do_commit := RegNext(canCommit, init=false.B)
when (do_commit) { commPtr := commPtr + 1.U }
val do_commit = RegNext(canCommit, init=false.B)
when (canCommit) { commPtr := commPtr + 1.U }
val commit_state = RegNext(commitStateQueue(commPtr.value))
val commit_cfi = WireInit(RegNext(cfiIndex_vec(commPtr.value)))
when (commit_state(commit_cfi.bits) =/= c_commited) {
commit_cfi.valid := false.B
val can_commit_cfi = WireInit(cfiIndex_vec(commPtr.value))
when (commitStateQueue(commPtr.value)(can_commit_cfi.bits) =/= c_commited) {
can_commit_cfi.valid := false.B
}
val commit_cfi = RegNext(can_commit_cfi)
val commit_mispredict = VecInit((RegNext(mispredict_vec(commPtr.value)) zip commit_state).map {
case (mis, state) => mis && state === c_commited
})
val commit_hit = RegNext(entry_hit_status(commPtr.value))
val can_commit_hit = entry_hit_status(commPtr.value)
val commit_hit = RegNext(can_commit_hit)
val commit_target = RegNext(update_target(commPtr.value))
val commit_valid = commit_hit === h_hit || commit_cfi.valid // hit or taken
val to_bpu_hit = can_commit_hit === h_hit || can_commit_hit === h_false_hit
may_have_stall_from_bpu := can_commit_cfi.valid && !to_bpu_hit && !RegNext(may_have_stall_from_bpu)
io.toBpu.update := DontCare
io.toBpu.update.valid := commit_valid && do_commit
......@@ -969,6 +973,7 @@ class Ftq(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelpe
XSPerfAccumulate("to_ifu_stall", io.toIfu.req.valid && !io.toIfu.req.ready)
XSPerfAccumulate("from_bpu_real_bubble", !enq.valid && enq.ready && allowBpuIn)
XSPerfAccumulate("bpu_to_ftq_bubble", bpuPtr === ifuPtr)
val from_bpu = io.fromBpu.resp.bits
def in_entry_len_map_gen(resp: BranchPredictionBundle)(stage: String) = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册