提交 eded4773 编写于 作者: L Lingrui98

ubtb, ftb: remove tag from ftb entry

上级 872cd090
......@@ -34,9 +34,8 @@ trait FTBParams extends HasXSParameter with HasBPUConst {
val tagSize = 20
}
class FTBEntry (implicit p: Parameters) extends XSBundle with FTBParams with BPUUtils {
class FTBEntry(implicit p: Parameters) extends XSBundle with FTBParams with BPUUtils {
val valid = Bool()
val tag = UInt(tagSize.W)
val brOffset = Vec(numBr, UInt(log2Up(FetchWidth*2).W))
val brTargets = Vec(numBr, UInt(VAddrBits.W))
......@@ -74,10 +73,9 @@ class FTBEntry (implicit p: Parameters) extends XSBundle with FTBParams with BPU
def brIsSaved(offset: UInt) = (brValids zip brOffset).map{
case (v, off) => v && off === offset
}.reduce(_||_)
def display(cond: Bool): Unit = {
XSDebug(cond, p"-----------FTB entry----------- \n")
XSDebug(cond, p"v=${valid}, tag=${Hexadecimal(tag)}\n")
XSDebug(cond, p"v=${valid}\n")
for(i <- 0 until numBr) {
XSDebug(cond, p"[br$i]: v=${brValids(i)}, offset=${brOffset(i)}, target=${Hexadecimal(brTargets(i))}\n")
}
......@@ -87,6 +85,24 @@ class FTBEntry (implicit p: Parameters) extends XSBundle with FTBParams with BPU
XSDebug(cond, p"oversize=$oversize, last_is_rvc=$last_is_rvc\n")
XSDebug(cond, p"------------------------------- \n")
}
}
class FTBEntryWithTag(implicit p: Parameters) extends XSBundle with FTBParams with BPUUtils {
val entry = new FTBEntry
val tag = UInt(tagSize.W)
def display(cond: Bool): Unit = {
XSDebug(cond, p"-----------FTB entry----------- \n")
XSDebug(cond, p"v=${entry.valid}, tag=${Hexadecimal(tag)}\n")
for(i <- 0 until numBr) {
XSDebug(cond, p"[br$i]: v=${entry.brValids(i)}, offset=${entry.brOffset(i)}, target=${Hexadecimal(entry.brTargets(i))}\n")
}
XSDebug(cond, p"[jmp]: v=${entry.jmpValid}, offset=${entry.jmpOffset}, target=${Hexadecimal(entry.jmpTarget)}\n")
XSDebug(cond, p"pftAddr=${Hexadecimal(entry.pftAddr)}, carry=${entry.carry}\n")
XSDebug(cond, p"isCall=${entry.isCall}, isRet=${entry.isRet}, isjalr=${entry.isJalr}\n")
XSDebug(cond, p"oversize=${entry.oversize}, last_is_rvc=${entry.last_is_rvc}\n")
XSDebug(cond, p"------------------------------- \n")
}
}
class FTBMeta(implicit p: Parameters) extends XSBundle with FTBParams {
......@@ -112,7 +128,7 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
class FTBBank(val numSets: Int, val nWays: Int) extends XSModule with BPUUtils {
val io = IO(new Bundle {
val read_pc = Flipped(DecoupledIO(UInt(VAddrBits.W)))
val req_pc = Flipped(DecoupledIO(UInt(VAddrBits.W)))
val read_resp = Output(new FTBEntry)
// when ftb hit, read_hits.valid is true, and read_hits.bits is OH of hit way
......@@ -120,22 +136,23 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
val read_hits = Valid(Vec(numWays, Bool()))
val update_pc = Input(UInt(VAddrBits.W))
val update_write_data = Flipped(Valid(new FTBEntry))
val update_write_data = Flipped(Valid(new FTBEntryWithTag))
val update_write_mask = Input(UInt(numWays.W))
})
val ftb = Module(new SRAMTemplate(new FTBEntry, set = numSets, way = numWays, shouldReset = true, holdRead = true, singlePort = true))
val ftb = Module(new SRAMTemplate(new FTBEntryWithTag, set = numSets, way = numWays, shouldReset = true, holdRead = true, singlePort = true))
ftb.io.r.req.valid := io.read_pc.valid // io.s0_fire
ftb.io.r.req.bits.setIdx := ftbAddr.getIdx(io.read_pc.bits) // s0_idx
ftb.io.r.req.valid := io.req_pc.valid // io.s0_fire
ftb.io.r.req.bits.setIdx := ftbAddr.getIdx(io.req_pc.bits) // s0_idx
io.read_pc.ready := ftb.io.r.req.ready
io.req_pc.ready := ftb.io.r.req.ready
val read_tag = RegEnable(ftbAddr.getTag(io.read_pc.bits)(tagSize-1, 0), io.read_pc.valid)
val req_tag = RegEnable(ftbAddr.getTag(io.req_pc.bits)(tagSize-1, 0), io.req_pc.valid)
val read_datas = ftb.io.r.resp.data
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_datas(b).tag === read_tag && read_datas(b).valid))
val total_hits = VecInit((0 until numWays).map(b => read_tags(b) === req_tag && read_entries(b).valid))
val hit = total_hits.reduce(_||_)
val hit_way_1h = VecInit(PriorityEncoderOH(total_hits))
......@@ -158,11 +175,13 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
}
}
val allocWriteWay = allocWay(VecInit(read_datas.map(w => w.valid)).asUInt,
VecInit(read_datas.map(w => w.tag)).asUInt,
read_tag)
val allocWriteWay = allocWay(
VecInit(read_entries.map(_.valid)).asUInt,
VecInit(read_tags).asUInt,
req_tag
)
io.read_resp := PriorityMux(total_hits, read_datas) // Mux1H
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()))
......@@ -177,10 +196,10 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
val ftbBank = Module(new FTBBank(numSets, numWays))
ftbBank.io.read_pc.valid := io.s0_fire
ftbBank.io.read_pc.bits := s0_pc
ftbBank.io.req_pc.valid := io.s0_fire
ftbBank.io.req_pc.bits := s0_pc
io.s1_ready := ftbBank.io.read_pc.ready // && !io.redirect.valid
io.s1_ready := ftbBank.io.req_pc.ready // && !io.redirect.valid
val ftb_entry = RegEnable(ftbBank.io.read_resp, io.s1_fire)
val s1_hit = ftbBank.io.read_hits.valid
......@@ -192,14 +211,6 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
// io.out.bits.resp := RegEnable(io.in.bits.resp_in(0), 0.U.asTypeOf(new BranchPredictionResp), io.s1_fire)
io.out.resp := io.in.bits.resp_in(0)
// val s2_target = Wire(UInt(VAddrBits.W))
// s2_target := s2_pc + (FetchWidth*4).U
// when(s2_hit) {
// s2_target := Mux((io.in.bits.resp_in(0).s2.preds.taken_mask.asUInt & ftb_entry.brValids.asUInt) =/= 0.U,
// PriorityMux(io.in.bits.resp_in(0).s2.preds.taken_mask.asUInt & ftb_entry.brValids.asUInt, ftb_entry.brTargets),
// Mux(ftb_entry.jmpValid, ftb_entry.jmpTarget, fallThruAddr))
// }
val s1_latch_call_is_rvc = DontCare // TODO: modify when add RAS
io.out.resp.s2.preds.taken_mask := io.in.bits.resp_in(0).s2.preds.taken_mask
......@@ -210,7 +221,6 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
}
io.out.resp.s2.preds.hit := s2_hit
// io.out.resp.s2.preds.target := s2_target
io.out.resp.s2.pc := s2_pc
io.out.resp.s2.ftb_entry := ftb_entry
......@@ -234,8 +244,6 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
}
}
// io.out.resp.s3 := RegEnable(io.out.resp.s2, io.s2_fire)
// Update logic
val has_update = RegInit(VecInit(Seq.fill(64)(0.U(VAddrBits.W))))
val has_update_ptr = RegInit(0.U(log2Up(64)))
......@@ -246,9 +254,8 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
val u_valid = RegNext(io.update.valid && !io.update.bits.old_entry)
val u_way_mask = u_meta.writeWay
val ftb_write = WireInit(update.ftb_entry)
ftb_write.valid := true.B
val ftb_write = Wire(new FTBEntryWithTag)
ftb_write.entry := update.ftb_entry
ftb_write.tag := ftbAddr.getTag(update.pc)(tagSize-1, 0)
ftbBank.io.update_write_data.valid := u_valid
......@@ -266,7 +273,7 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU
}
if (debug && !env.FPGAPlatform && env.EnablePerfDebug) {
XSDebug("req_v=%b, req_pc=%x, ready=%b (resp at next cycle)\n", io.s0_fire, s0_pc, ftbBank.io.read_pc.ready)
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)
XSDebug("s2_taken_mask=%b, s2_real_taken_mask=%b\n",
io.in.bits.resp_in(0).s2.preds.taken_mask.asUInt, io.out.resp.s2.real_taken_mask().asUInt)
......
......@@ -46,39 +46,7 @@ class MicroBTB(implicit p: Parameters) extends BasePredictor
val hit = Bool()
}
class MicroBTBData extends FTBEntry {
// val brTargets = Vec(numBr, UInt(VAddrBits.W))
// val jmpTarget = UInt(VAddrBits.W)
// val pftAddr = UInt((log2Up(PredictWidth)+1).W)
}
class ReadResp extends FTBEntry {
val hit = Bool()
}
// object ReadResp {
// def apply(entry: MicroBTBMeta, hit: Bool)(implicit p: Parameters): ReadResp = {
// val e = Wire(new ReadResp())
//
// e.valid := entry.valid
// e.brOffset := entry.brOffset
// e.brTargets := entry.brTargets
// e.brValids := entry.brValids
// e.jmpOffset := entry.jmpOffset
// e.jmpTarget := entry.jmpTarget
// e.jmpValid := entry.jmpValid
//
// e.pftAddr := entry.pftAddr
// e.carry := entry.carry
// e.oversize := entry.oversize
// e.last_is_rvc := entry.last_is_rvc
//
// e.hit := hit
//
// e
// }
// }
class MicroBTBEntry extends FTBEntry {}
override val meta_size = WireInit(0.U.asTypeOf(new MicroBTBOutMeta)).getWidth // TODO: ReadResp shouldn't save useless members
......@@ -89,72 +57,30 @@ class MicroBTB(implicit p: Parameters) extends BasePredictor
val read_entry = Output(new FTBEntry)
val read_hit = Output(Bool())
val update_write_meta = Input(new MicroBTBMeta)
val update_write_data = Flipped(Valid(new MicroBTBData))
val update_taken_mask = Input(Vec(numBr, Bool()))
val update_mask = Input(UInt(numBr.W))
val update_valid = Input(Bool())
val update_write_tag = Input(UInt(tagSize.W))
val update_write_entry = Input(new MicroBTBEntry)
})
val tagCam = Module(new CAMTemplate(UInt(tagSize.W), nWays, 2))
val validMem = Module(new AsyncDataModuleTemplate(Bool(), nWays, nWays, 1)) // valids
val dataMem = Module(new AsyncDataModuleTemplate(new MicroBTBData, nWays, 1, 1))
for (w <- 0 until nWays) {
validMem.io.raddr(w) := w.U
}
val valids = validMem.io.rdata
// val rbims = bims.io.rdata.take(nWays)
// val rdatas = data.io.rdata
val valids = RegInit(VecInit(Seq.fill(nWays)(false.B))) // valids
val dataMem = Module(new AsyncDataModuleTemplate(new MicroBTBEntry, nWays, 1, 1))
val read_pc = io.read_pc.bits
val read_tag = getTag(read_pc)
// val hits = VecInit(rmetas.map(m => m.valid && m.tag === read_tag))
val hits = VecInit((0 until nWays).map(i => valids(i) && tagCam.io.r.resp(0)(i)))
val hit = hits.reduce(_||_)
val hitWay = OHToUInt(hits)
dataMem.io.raddr(0) := hitWay
// val hit_meta = ParallelMux(hits zip rmetas)
// val hit_data = ParallelMux(hits zip rdatas)
val hit_data = Mux(hit, dataMem.io.rdata(0), 0.U.asTypeOf(new MicroBTBData))
io.read_entry := DontCare
io.read_entry.valid := io.read_pc.valid
io.read_entry.tag := read_tag
io.read_entry.brOffset := hit_data.brOffset
io.read_entry.brTargets := hit_data.brTargets
io.read_entry.brValids := hit_data.brValids
val hit_entry = Mux(hit, dataMem.io.rdata(0), 0.U.asTypeOf(new MicroBTBEntry))
io.read_entry.jmpOffset := hit_data.jmpOffset
io.read_entry.jmpTarget := hit_data.jmpTarget
io.read_entry.jmpValid := hit_data.jmpValid
io.read_entry := hit_entry
io.read_hit := hit
io.read_entry.pftAddr := hit_data.pftAddr
io.read_entry.carry := hit_data.carry
io.read_entry.isCall := hit_data.isCall
io.read_entry.isRet := hit_data.isRet
io.read_entry.isJalr := hit_data.isJalr
io.read_entry.oversize := hit_data.oversize
io.read_entry.last_is_rvc := hit_data.last_is_rvc
val do_reset = RegInit(true.B)
val reset_way = RegInit(0.U(log2Ceil(nWays).W))
when (RegNext(reset.asBool) && !reset.asBool) {
do_reset := true.B
reset_way := 0.U
}
when (do_reset) { reset_way := reset_way + 1.U }
when (reset_way === (nWays-1).U) { do_reset := false.B }
val update_tag = io.update_write_meta.tag
val update_tag = io.update_write_tag
val update_hits = VecInit((0 until nWays).map(i => valids(i) && tagCam.io.r.resp(1)(i)))
val update_hit = update_hits.reduce(_||_)
val update_hitWay = OHToUInt(update_hits)
......@@ -163,21 +89,10 @@ class MicroBTB(implicit p: Parameters) extends BasePredictor
val update_alloc_way = RegInit(0.U(log2Ceil(nWays).W))
when (io.update_write_meta.valid && !update_hit) {
when (io.update_valid && !update_hit) {
update_alloc_way := update_alloc_way ^ foldTag(update_tag, log2Ceil(nWays))
}
// val update_alloc_way = {
// val source = Cat(VecInit(meta.map(_.tag)).asUInt, update_tag)
// val l = log2Ceil(nWays)
// val nChunks = (source.getWidth + l - 1) / l
// val chunks = (0 until nChunks) map { i =>
// source(min((i+1)*l, source.getWidth)-1, i*l)
// }
// ParallelXOR(chunks)
// }
val update_emptys = valids.map(!_)
val update_has_empty_way = update_emptys.reduce(_||_)
val update_empty_way = ParallelPriorityEncoder(update_emptys)
......@@ -185,24 +100,17 @@ class MicroBTB(implicit p: Parameters) extends BasePredictor
tagCam.io.r.req := VecInit(Seq(read_tag, update_tag))
tagCam.io.w.valid := do_reset || RegNext(io.update_write_meta.valid)
tagCam.io.w.bits.index := Mux(do_reset, reset_way, RegNext(update_way))
tagCam.io.w.bits.data := Mux(do_reset,
0.U(tagSize.W),
RegNext(io.update_write_meta.tag))
validMem.io.wen(0) := do_reset || RegNext(io.update_write_data.valid)
validMem.io.waddr(0) := Mux(do_reset, reset_way, RegNext(update_way))
validMem.io.wdata(0) := Mux(do_reset,
false.B,
RegNext(io.update_write_meta.valid))
tagCam.io.w.valid := RegNext(io.update_valid)
tagCam.io.w.bits.index := RegNext(update_way)
tagCam.io.w.bits.data := RegNext(io.update_write_tag)
dataMem.io.wen(0) := do_reset || RegNext(io.update_write_data.valid)
dataMem.io.waddr(0) := Mux(do_reset, reset_way, RegNext(update_way))
dataMem.io.wdata(0) := Mux(do_reset,
0.U.asTypeOf(new MicroBTBData),
RegNext(io.update_write_data.bits))
when (RegNext(io.update_valid)) {
valids(RegNext(update_way)) := true.B
}
dataMem.io.wen(0) := RegNext(io.update_valid)
dataMem.io.waddr(0) := RegNext(update_way)
dataMem.io.wdata(0) := RegNext(io.update_write_entry)
} // uBTBBank
......@@ -243,39 +151,10 @@ class MicroBTB(implicit p: Parameters) extends BasePredictor
val u_meta = update.meta.asTypeOf(new MicroBTBOutMeta)
val u_tag = getTag(u_pc)
// val u_target_lower = update.preds.target(lowerBitSize-1+instOffsetBits, instOffsetBits)
val data_write_valid = u_valid && u_taken
val meta_write_valid = u_valid && u_taken
val update_write_datas = Wire(new MicroBTBData)
val update_write_metas = Wire(new MicroBTBMeta)
update_write_metas := DontCare
update_write_metas.valid := meta_write_valid
update_write_metas.tag := u_tag
update_write_datas := DontCare
update_write_datas.brOffset := update.ftb_entry.brOffset
update_write_datas.brValids := update.ftb_entry.brValids
update_write_datas.jmpOffset := update.ftb_entry.jmpOffset
update_write_datas.jmpValid := update.ftb_entry.jmpValid
update_write_datas.isCall := update.ftb_entry.isCall
update_write_datas.isRet := update.ftb_entry.isRet
update_write_datas.isJalr := update.ftb_entry.isJalr
update_write_datas.carry := update.ftb_entry.carry
update_write_datas.oversize := update.ftb_entry.oversize
update_write_datas.last_is_rvc := update.ftb_entry.last_is_rvc
update_write_datas.jmpTarget := update.ftb_entry.jmpTarget
update_write_datas.brTargets := update.ftb_entry.brTargets
update_write_datas.pftAddr := update.ftb_entry.pftAddr
bank.update_write_meta := update_write_metas
bank.update_write_data.valid := data_write_valid
bank.update_write_data.bits := update_write_datas
bank.update_taken_mask := u_taken_mask
bank.update_mask := LowerMaskFromLowest(u_taken_mask.asUInt)
bank.update_valid := u_valid && u_taken
bank.update_write_tag := u_tag
bank.update_write_entry := update.ftb_entry
if (debug && !env.FPGAPlatform && env.EnablePerfDebug) {
XSDebug("req_v=%b, req_pc=%x, hit=%b\n", io.s1_fire, s1_pc, bank.read_hit)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册