Skip to content

Commit

Permalink
Merge pull request #1057 from OpenXiangShan/ubtb-1K
Browse files Browse the repository at this point in the history
BPU: Modify ubtb to direct mapped from fully associative
  • Loading branch information
Lingrui98 committed Sep 26, 2021
2 parents 55bb031 + 719a3f8 commit ffcef82
Showing 1 changed file with 33 additions and 79 deletions.
112 changes: 33 additions & 79 deletions src/main/scala/xiangshan/frontend/uBTB.scala
Expand Up @@ -25,105 +25,55 @@ import chisel3.experimental.chiselName
import xiangshan.cache.mmu.CAMTemplate

trait MicroBTBParams extends HasXSParameter {
val numWays = 32
val numWays = 1024
val tagSize = 20
val lowerBitSize = 20
val untaggedBits = instOffsetBits
// val lowerBitSize = 20
val untaggedBits = log2Ceil(numWays) + instOffsetBits
}

@chiselName
class MicroBTB(implicit p: Parameters) extends BasePredictor
with MicroBTBParams
{
def getTag(pc: UInt) = (pc >> untaggedBits)(tagSize-1, 0)

class MicroBTBMeta extends XSBundle {
val valid = Bool()
val tag = UInt(tagSize.W)
}
val ubtbAddr = new TableAddr(log2Up(numWays), 1)

class MicroBTBOutMeta extends XSBundle {
val hit = Bool()
}

class MicroBTBEntry extends FTBEntry {}
class MicroBTBEntry extends FTBEntryWithTag {}

override val meta_size = WireInit(0.U.asTypeOf(new MicroBTBOutMeta)).getWidth // TODO: ReadResp shouldn't save useless members

class UBTBBank(val nWays: Int) extends XSModule with BPUUtils {
val io = IO(new Bundle {
val read_pc = Flipped(Valid(UInt(VAddrBits.W)))
val read_pc = Flipped(DecoupledIO(UInt(VAddrBits.W))) // TODO: Add ready
// val read_taken_mask = Input(Vec(numBr, Bool()))
val read_entry = Output(new FTBEntry)
val read_entry = Output(new MicroBTBEntry)
val read_hit = Output(Bool())

val update_valid = Input(Bool())
val update_write_tag = Input(UInt(tagSize.W))
val update_write_entry = Input(new MicroBTBEntry)
val update_pc = Input(UInt(VAddrBits.W))
})

val tagCam = Module(new CAMTemplate(UInt(tagSize.W), nWays, 2))
val valids = RegInit(VecInit(Seq.fill(nWays)(false.B))) // valids
val dataMem = Module(new AsyncDataModuleTemplate(new MicroBTBEntry, nWays, 1, 1))
val dataMem = Module(new SRAMTemplate(new MicroBTBEntry, set = numWays, way = 1, shouldReset = true, holdRead = true, singlePort = true))

val read_pc = io.read_pc.bits
val read_tag = getTag(read_pc)
val read_pc = RegNext(io.read_pc.bits)
val read_tag = ubtbAddr.getTag(read_pc)(tagSize-1,0)

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
dataMem.io.r.req.valid := io.read_pc.valid
dataMem.io.r.req.bits.setIdx := ubtbAddr.getIdx(io.read_pc.bits)

io.read_pc.ready := dataMem.io.r.req.ready

val hit_entry = Mux(hit, dataMem.io.rdata(0), 0.U.asTypeOf(new MicroBTBEntry))
val hit_entry = dataMem.io.r.resp.data(0)
val hit = hit_entry.entry.valid && hit_entry.tag === read_tag

io.read_entry := hit_entry
io.read_hit := hit

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)

require(tagSize % log2Ceil(nWays) == 0)

val update_alloc_way = RegInit(0.U(log2Ceil(nWays).W))

when (io.update_valid && !update_hit) {
update_alloc_way := update_alloc_way ^ foldTag(update_tag, log2Ceil(nWays))
}

val update_emptys = valids.map(!_)
val update_has_empty_way = update_emptys.reduce(_||_)
val update_empty_way = ParallelPriorityEncoder(update_emptys)
val update_way = Wire(UInt(log2Ceil(nWays).W))


val update_valid_reg = RegNext(io.update_valid)
val update_way_reg = RegNext(update_way)
val update_tag_reg = RegNext(update_tag)
val update_entry_reg = RegNext(io.update_write_entry)

val update_bypass_valid = update_valid_reg && io.update_valid && update_tag === update_tag_reg
update_way :=
Mux(update_bypass_valid, update_way_reg,
Mux(update_hit, update_hitWay,
Mux(update_has_empty_way, update_empty_way,
update_alloc_way)))

tagCam.io.r.req := VecInit(Seq(read_tag, update_tag))

tagCam.io.w.valid := update_valid_reg
tagCam.io.w.bits.index := update_way_reg
tagCam.io.w.bits.data := update_tag_reg

when (update_valid_reg) {
valids(update_way_reg) := true.B
}

dataMem.io.wen(0) := update_valid_reg
dataMem.io.waddr(0) := update_way_reg
dataMem.io.wdata(0) := update_entry_reg
dataMem.io.w.apply(io.update_valid, io.update_write_entry, ubtbAddr.getIdx(io.update_pc), io.update_valid)

} // uBTBBank

Expand All @@ -132,16 +82,18 @@ class MicroBTB(implicit p: Parameters) extends BasePredictor
val read_entry = bank.read_entry
val outMeta = Wire(new MicroBTBOutMeta)

XSDebug(p"uBTB entry, read_pc=${Hexadecimal(s1_pc)}\n")
XSDebug(p"uBTB entry, read_pc=${Hexadecimal(s0_pc)}\n")

bank.read_pc.valid := io.s1_fire
bank.read_pc.bits := s1_pc
bank.read_pc.valid := io.s0_fire
bank.read_pc.bits := s0_pc

io.s1_ready := bank.read_pc.ready

io.out.resp := io.in.bits.resp_in(0)
io.out.resp.s1.pc := s1_pc
io.out.resp.s1.preds.hit := bank.read_hit
io.out.resp.s1.ftb_entry := read_entry
io.out.resp.s1.preds.fromFtbEntry(read_entry, s1_pc)
io.out.resp.s1.ftb_entry := read_entry.entry
io.out.resp.s1.preds.fromFtbEntry(read_entry.entry, s1_pc)

when(!bank.read_hit) {
io.out.resp.s1.ftb_entry.pftAddr := s1_pc(instOffsetBits + log2Ceil(PredictWidth), instOffsetBits) ^ (1 << log2Ceil(PredictWidth)).U
Expand All @@ -160,18 +112,20 @@ class MicroBTB(implicit p: Parameters) extends BasePredictor
val u_taken_mask = update.preds.taken_mask
val u_meta = update.meta.asTypeOf(new MicroBTBOutMeta)

val u_tag = getTag(u_pc)
val u_tag = ubtbAddr.getTag(u_pc)

bank.update_valid := u_valid && u_taken
bank.update_write_tag := u_tag
bank.update_write_entry := update.ftb_entry
bank.update_valid := u_valid && u_taken && ((u_meta.hit && !update.old_entry) || !u_meta.hit)
bank.update_pc := u_pc
bank.update_write_entry.entry := update.ftb_entry
bank.update_write_entry.entry.valid := true.B
bank.update_write_entry.tag := u_tag

XSDebug("req_v=%b, req_pc=%x, hit=%b\n", io.s1_fire, s1_pc, bank.read_hit)
XSDebug("target=%x, real_taken_mask=%b, taken_mask=%b, brValids=%b, jmpValid=%b\n",
io.out.resp.s1.target, io.out.resp.s1.real_taken_mask.asUInt, io.out.resp.s1.preds.taken_mask.asUInt, read_entry.brValids.asUInt, read_entry.jmpValid.asUInt)
io.out.resp.s1.target, io.out.resp.s1.real_taken_mask.asUInt, io.out.resp.s1.preds.taken_mask.asUInt, read_entry.entry.brValids.asUInt, read_entry.entry.jmpValid.asUInt)

XSDebug(u_valid, "[update]Update from ftq\n")
XSDebug(u_valid, "[update]update_pc=%x, tag=%x\n", u_pc, getTag(u_pc))
XSDebug(u_valid, "[update]update_pc=%x, tag=%x\n", u_pc, ubtbAddr.getTag(u_pc))
XSDebug(u_valid, "[update]taken_mask=%b, brValids=%b, jmpValid=%b\n",
u_taken_mask.asUInt, update.ftb_entry.brValids.asUInt, update.ftb_entry.jmpValid)

Expand Down

0 comments on commit ffcef82

Please sign in to comment.