提交 ab835d5b 编写于 作者: L Lingrui98

Merge branch 'dev-frontend-bpu' into dev-frontend

...@@ -176,6 +176,10 @@ class BPUStage extends XSModule { ...@@ -176,6 +176,10 @@ class BPUStage extends XSModule {
val p = io.pred.bits val p = io.pred.bits
XSDebug(io.pred.fire(), "outPred: redirect=%d, taken=%d, jmpIdx=%d, hasNTBrs=%d, target=%x, saveHalfRVI=%d\n", XSDebug(io.pred.fire(), "outPred: redirect=%d, taken=%d, jmpIdx=%d, hasNTBrs=%d, target=%x, saveHalfRVI=%d\n",
p.redirect, p.taken, p.jmpIdx, p.hasNotTakenBrs, p.target, p.saveHalfRVI) p.redirect, p.taken, p.jmpIdx, p.hasNotTakenBrs, p.target, p.saveHalfRVI)
XSDebug(io.pred.fire() && p.taken, "outPredTaken: fetchPC:%x, jmpPC:%x\n",
inLatch.pc, inLatch.pc + (jmpIdx << 1.U))
XSDebug(io.pred.fire() && p.redirect, "outPred: previous target:%x redirected to %x \n",
inLatch.target, p.target)
} }
class BPUStage1 extends BPUStage { class BPUStage1 extends BPUStage {
...@@ -269,10 +273,10 @@ class BPUStage3 extends BPUStage { ...@@ -269,10 +273,10 @@ class BPUStage3 extends BPUStage {
io.out.bits.brInfo(i).tageMeta := io.in.bits.brInfo(i).tageMeta io.out.bits.brInfo(i).tageMeta := io.in.bits.brInfo(i).tageMeta
} }
XSDebug(io.predecode.valid, "predecode: mask:%b\n", io.predecode.bits.mask) XSDebug(io.predecode.valid, "predecode: pc:%x, mask:%b\n", inLatch.pc, io.predecode.bits.mask)
for (i <- 0 until PredictWidth) { for (i <- 0 until PredictWidth) {
val p = io.predecode.bits.pd(i) val p = io.predecode.bits.pd(i)
XSDebug(io.predecode.valid, "predecode(%d): brType:%d, br:%d, jal:%d, jalr:%d, call:%d, ret:%d, RVC:%d, excType:%d\n", XSDebug(io.predecode.valid && io.predecode.bits.mask(i), "predecode(%d): brType:%d, br:%d, jal:%d, jalr:%d, call:%d, ret:%d, RVC:%d, excType:%d\n",
i.U, p.brType, p.isBr, p.isJal, p.isJalr, p.isCall, p.isRet, p.isRVC, p.excType) i.U, p.brType, p.isBr, p.isJal, p.isJalr, p.isCall, p.isRet, p.isRVC, p.excType)
} }
} }
...@@ -422,7 +426,7 @@ class BPU extends BaseBPU { ...@@ -422,7 +426,7 @@ class BPU extends BaseBPU {
s1.io.in.valid := io.in.valid s1.io.in.valid := io.in.valid
s1.io.in.bits.pc := io.in.bits.pc s1.io.in.bits.pc := io.in.bits.pc
s1.io.in.bits.mask := io.in.bits.inMask s1.io.in.bits.mask := io.in.bits.inMask
s1.io.in.bits.target := npc(s1_inLatch.bits.pc, PopCount(s1_inLatch.bits.inMask)) // Deault target npc s1.io.in.bits.target := npc(io.in.bits.pc, PopCount(io.in.bits.inMask)) // Deault target npc
s1.io.in.bits.resp := s1_resp_in s1.io.in.bits.resp := s1_resp_in
s1.io.in.bits.brInfo <> s1_brInfo_in s1.io.in.bits.brInfo <> s1_brInfo_in
......
...@@ -44,9 +44,14 @@ class BIM extends BasePredictor with BimParams{ ...@@ -44,9 +44,14 @@ class BIM extends BasePredictor with BimParams{
val pcLatch = RegEnable(io.pc.bits, io.pc.valid) val pcLatch = RegEnable(io.pc.bits, io.pc.valid)
val bim = List.fill(BimBanks) { val bim = List.fill(BimBanks) {
Module(new SRAMTemplate(UInt(2.W), set = nRows, shouldReset = true, holdRead = true)) Module(new SRAMTemplate(UInt(2.W), set = nRows, shouldReset = false, holdRead = true))
} }
val doing_reset = RegInit(true.B)
val resetRow = RegInit(0.U(log2Ceil(nRows).W))
resetRow := resetRow + doing_reset
when (resetRow === (nRows-1).U) { doing_reset := false.B }
val baseBank = bimAddr.getBank(io.pc.bits) val baseBank = bimAddr.getBank(io.pc.bits)
val realMask = circularShiftRight(io.inMask, BimBanks, baseBank) val realMask = circularShiftRight(io.inMask, BimBanks, baseBank)
...@@ -91,8 +96,8 @@ class BIM extends BasePredictor with BimParams{ ...@@ -91,8 +96,8 @@ class BIM extends BasePredictor with BimParams{
val needToUpdate = io.update.valid && !oldSaturated && u.pd.isBr val needToUpdate = io.update.valid && !oldSaturated && u.pd.isBr
for (b <- 0 until BimBanks) { for (b <- 0 until BimBanks) {
bim(b).io.w.req.valid := needToUpdate && b.U === updateBank bim(b).io.w.req.valid := needToUpdate && b.U === updateBank || doing_reset
bim(b).io.w.req.bits.setIdx := updateRow bim(b).io.w.req.bits.setIdx := Mux(doing_reset, resetRow, updateRow)
bim(b).io.w.req.bits.data := satUpdate(oldCtr, 2, newTaken) bim(b).io.w.req.bits.data := Mux(doing_reset, 2.U(2.W), satUpdate(oldCtr, 2, newTaken))
} }
} }
\ No newline at end of file
...@@ -8,6 +8,8 @@ import utils._ ...@@ -8,6 +8,8 @@ import utils._
import chisel3.util.experimental.BoringUtils import chisel3.util.experimental.BoringUtils
import xiangshan.backend.decode.XSTrap import xiangshan.backend.decode.XSTrap
import scala.math.min
trait BTBParams extends HasXSParameter { trait BTBParams extends HasXSParameter {
val nRows = BtbSize / (PredictWidth * BtbWays) val nRows = BtbSize / (PredictWidth * BtbWays)
val offsetLen = 13 val offsetLen = 13
...@@ -126,18 +128,42 @@ class BTB extends BasePredictor with BTBParams{ ...@@ -126,18 +128,42 @@ class BTB extends BasePredictor with BTBParams{
val baseTag = btbAddr.getTag(pcLatch) val baseTag = btbAddr.getTag(pcLatch)
val tagIncremented = VecInit((0 until BtbBanks).map(b => RegEnable(isInNextRow(b.U) && nextRowStartsUp, io.pc.valid))) val tagIncremented = VecInit((0 until BtbBanks).map(b => RegEnable(isInNextRow(b.U) && nextRowStartsUp, io.pc.valid)))
val realTags = VecInit((0 until BtbBanks).map(b => Mux(tagIncremented(b), baseTag + 1.U, baseTag)))
val totalHits = VecInit((0 until BtbBanks).map( b => val totalHits = VecInit((0 until BtbBanks).map( b =>
VecInit((0 until BtbWays).map( w => VecInit((0 until BtbWays).map( w =>
// This should correspond to the real mask from last valid cycle! // This should correspond to the real mask from last valid cycle!
metaRead(w)(b).tag === Mux(tagIncremented(b), baseTag + 1.U, baseTag) && metaRead(w)(b).valid && realMaskLatch(b) metaRead(w)(b).tag === realTags(b) && metaRead(w)(b).valid && realMaskLatch(b)
)) ))
)) ))
val bankHits = VecInit(totalHits.map(_.reduce(_||_))) val bankHits = VecInit(totalHits.map(_.reduce(_||_)))
val bankHitWays = VecInit(totalHits.map(PriorityEncoder(_))) val bankHitWays = VecInit(totalHits.map(PriorityEncoder(_)))
def allocWay(valids: UInt, meta_tags: UInt, req_tag: UInt) = {
if (BtbWays > 1) {
val w = Wire(UInt(log2Up(BtbWays).W))
val valid = WireInit(valids.andR)
val tags = Cat(meta_tags, req_tag)
val l = log2Up(BtbWays)
val nChunks = (tags.getWidth + l - 1) / l
val chunks = (0 until nChunks).map( i =>
tags(min((i+1)*l, tags.getWidth)-1, i*l)
)
w := Mux(valid, chunks.reduce(_^_), PriorityEncoder(~valids))
w
} else {
val w = WireInit(0.U)
w
}
}
val allocWays = VecInit((0 until BtbBanks).map(b =>
allocWay(VecInit(metaRead.map(w => w(b).valid)).asUInt,
VecInit(metaRead.map(w => w(b).tag)).asUInt,
realTags(b))))
val writeWay = VecInit((0 until BtbBanks).map( val writeWay = VecInit((0 until BtbBanks).map(
b => Mux(bankHits(b), bankHitWays(b), LFSR64()(0)) b => Mux(bankHits(b), bankHitWays(b), allocWays(b))
)) ))
// e.g: baseBank == 5 => (5, 6,..., 15, 0, 1, 2, 3, 4) // e.g: baseBank == 5 => (5, 6,..., 15, 0, 1, 2, 3, 4)
...@@ -179,7 +205,7 @@ class BTB extends BasePredictor with BTBParams{ ...@@ -179,7 +205,7 @@ class BTB extends BasePredictor with BTBParams{
val metaWrite = BtbMetaEntry(btbAddr.getTag(u.pc), pdInfoToBTBtype(u.pd), u.pd.isRVC) val metaWrite = BtbMetaEntry(btbAddr.getTag(u.pc), pdInfoToBTBtype(u.pd), u.pd.isRVC)
val dataWrite = BtbDataEntry(new_offset, new_extended) val dataWrite = BtbDataEntry(new_offset, new_extended)
val updateValid = io.update.valid val updateValid = io.update.valid && u.isMisPred
// Update btb // Update btb
for (w <- 0 until BtbWays) { for (w <- 0 until BtbWays) {
for (b <- 0 until BtbBanks) { for (b <- 0 until BtbBanks) {
...@@ -215,6 +241,15 @@ class BTB extends BasePredictor with BTBParams{ ...@@ -215,6 +241,15 @@ class BTB extends BasePredictor with BTBParams{
XSDebug(validLatch && bankHits(bankIdxInOrder(i)), "resp(%d): bank(%d) hits, tgt=%x, isRVC=%d, type=%d\n", XSDebug(validLatch && bankHits(bankIdxInOrder(i)), "resp(%d): bank(%d) hits, tgt=%x, isRVC=%d, type=%d\n",
i.U, idx, io.resp.targets(i), io.resp.isRVC(i), io.resp.types(i)) i.U, idx, io.resp.targets(i), io.resp.isRVC(i), io.resp.types(i))
} }
XSDebug(updateValid, "update_req: pc=0x%x, target=0x%x, offset=%x, extended=%d, way=%d, bank=%d, row=0x%x\n", XSDebug(updateValid, "update_req: pc=0x%x, target=0x%x, misPred=%d, offset=%x, extended=%d, way=%d, bank=%d, row=0x%x\n",
u.pc, new_target, new_offset, new_extended, updateWay, updateBankIdx, updateRow) u.pc, new_target, u.isMisPred, new_offset, new_extended, updateWay, updateBankIdx, updateRow)
for (i <- 0 until BtbBanks) {
// Conflict when not hit and allocating a valid entry
val conflict = metaRead(allocWays(i))(i).valid && !bankHits(i)
XSDebug(conflict, "bank(%d) is trying to allocate a valid way(%d)\n", i.U, allocWays(i))
// There is another circumstance when a branch is on its way to update while another
// branch chose the same way to udpate, then after the first branch is wrote in,
// the second branch will overwrite the first branch
}
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册