diff --git a/src/main/scala/xiangshan/frontend/BPU.scala b/src/main/scala/xiangshan/frontend/BPU.scala index bef4a76f8e..ac50594133 100644 --- a/src/main/scala/xiangshan/frontend/BPU.scala +++ b/src/main/scala/xiangshan/frontend/BPU.scala @@ -848,7 +848,7 @@ class Predictor(implicit p: Parameters) extends XSModule with HasBPUConst with H val misPredictMask : UInt = io.ftq_to_bpu.update.bits.mispred_mask.asUInt val takenMask : UInt = io.ftq_to_bpu.update.bits.br_taken_mask.asUInt | - io.ftq_to_bpu.update.bits.ftb_entry.always_taken.asUInt // Always taken branch is recorded in history + (io.ftq_to_bpu.update.bits.ftb_entry.strong_bias.asUInt & io.ftq_to_bpu.update.bits.ftb_entry.brValids.asUInt) // Always taken branch is recorded in history val takenIdx : UInt = (PriorityEncoder(takenMask) + 1.U((log2Ceil(numBr)+1).W)).asUInt val misPredictIdx : UInt = (PriorityEncoder(misPredictMask) + 1.U((log2Ceil(numBr)+1).W)).asUInt val shouldShiftMask: UInt = Mux(takenMask.orR, diff --git a/src/main/scala/xiangshan/frontend/FTB.scala b/src/main/scala/xiangshan/frontend/FTB.scala index ef8d03e190..bbdf1b376c 100644 --- a/src/main/scala/xiangshan/frontend/FTB.scala +++ b/src/main/scala/xiangshan/frontend/FTB.scala @@ -196,7 +196,9 @@ class FTBEntry(implicit p: Parameters) extends FTBEntry_part with FTBParams with val last_may_be_rvi_call = Bool() - val always_taken = Vec(numBr, Bool()) + //Mark the conditional branch for the first jump and the jalr instruction that appears for the first time, + //and train the tag/ittage without using its results when strong_bias is true. + val strong_bias = Vec(numBr, Bool()) def getSlotForBr(idx: Int): FtbSlot = { require(idx <= numBr-1) @@ -375,7 +377,7 @@ class FTBEntry(implicit p: Parameters) extends FTBEntry_part with FTBParams with val isJalrDiff = this.isJalr === that.isJalr val lastMayBeRviCallDiff = this.last_may_be_rvi_call === that.last_may_be_rvi_call val alwaysTakenDiff : IndexedSeq[Bool] = - this.always_taken.zip(that.always_taken).map{ + this.strong_bias.zip(that.strong_bias).map{ case(x, y) => x === y } VecInit( @@ -751,10 +753,10 @@ class FTB(implicit p: Parameters) extends BasePredictor with FTBParams with BPUU for (i <- 0 until numBr) { for (out_fp & in_fp & s2_hit & s2_ftb_entry <- io.out.s2.full_pred zip io.in.bits.resp_in(0).s2.full_pred zip s2_hit_dup zip s2_ftb_entry_dup) - out_fp.br_taken_mask(i) := in_fp.br_taken_mask(i) || s2_hit && s2_ftb_entry.always_taken(i) + out_fp.br_taken_mask(i) := in_fp.br_taken_mask(i) || s2_hit && s2_ftb_entry.strong_bias(i) && s2_ftb_entry.brValids(i) for (out_fp & in_fp & s3_hit & s3_ftb_entry <- io.out.s3.full_pred zip io.in.bits.resp_in(0).s3.full_pred zip s3_hit_dup zip s3_ftb_entry_dup) - out_fp.br_taken_mask(i) := in_fp.br_taken_mask(i) || s3_hit && s3_ftb_entry.always_taken(i) + out_fp.br_taken_mask(i) := in_fp.br_taken_mask(i) || s3_hit && s3_ftb_entry.strong_bias(i) && s3_ftb_entry.brValids(i) } // Update logic diff --git a/src/main/scala/xiangshan/frontend/FauFTB.scala b/src/main/scala/xiangshan/frontend/FauFTB.scala index fd4100e3b8..49c3e515a3 100644 --- a/src/main/scala/xiangshan/frontend/FauFTB.scala +++ b/src/main/scala/xiangshan/frontend/FauFTB.scala @@ -109,7 +109,7 @@ class FauFTB(implicit p: Parameters) extends BasePredictor with FauFTBParams { fp.multiHit := false.B fp.fromFtbEntry(e, s1_pc_dup(0)) for (i <- 0 until numBr) { - fp.br_taken_mask(i) := c(i)(1) || e.always_taken(i) + fp.br_taken_mask(i) := c(i)(1) || (e.strong_bias(i) && e.brValids(i)) } } val s1_hit_full_pred = Mux1H(s1_hit_oh, s1_possible_full_preds) @@ -144,7 +144,7 @@ class FauFTB(implicit p: Parameters) extends BasePredictor with FauFTBParams { val u_s0_hit = u_s0_hit_oh.orR val u_s0_br_update_valids = VecInit((0 until numBr).map(w => - u.bits.ftb_entry.brValids(w) && u.valid && !u.bits.ftb_entry.always_taken(w) && + u.bits.ftb_entry.brValids(w) && u.valid && !u.bits.ftb_entry.strong_bias(w) && !(PriorityEncoder(u.bits.br_taken_mask) < w.U))) // s1 diff --git a/src/main/scala/xiangshan/frontend/ITTAGE.scala b/src/main/scala/xiangshan/frontend/ITTAGE.scala index 8852f629e7..f4347d6967 100644 --- a/src/main/scala/xiangshan/frontend/ITTAGE.scala +++ b/src/main/scala/xiangshan/frontend/ITTAGE.scala @@ -416,7 +416,7 @@ class ITTage(implicit p: Parameters) extends BaseITTage { val update = io.update.bits val updateValid = update.is_jalr && !update.is_ret && u_valid && update.ftb_entry.jmpValid && - update.jmp_taken && update.cfi_idx.valid && update.cfi_idx.bits === update.ftb_entry.tailSlot.offset + update.jmp_taken && update.cfi_idx.valid && update.cfi_idx.bits === update.ftb_entry.tailSlot.offset && !update.ftb_entry.strong_bias(numBr-1) // meta is splited by composer val updateMeta = update.meta.asTypeOf(new ITTageMeta) diff --git a/src/main/scala/xiangshan/frontend/NewFtq.scala b/src/main/scala/xiangshan/frontend/NewFtq.scala index 42449b48ff..305af90dcc 100644 --- a/src/main/scala/xiangshan/frontend/NewFtq.scala +++ b/src/main/scala/xiangshan/frontend/NewFtq.scala @@ -285,7 +285,7 @@ class FTBEntryGen(implicit p: Parameters) extends XSModule with HasBackendRedire init_br_slot.valid := true.B init_br_slot.offset := io.cfiIndex.bits init_br_slot.setLowerStatByTarget(io.start_addr, io.target, numBr == 1) - init_entry.always_taken(0) := true.B // set to always taken on init + init_entry.strong_bias(0) := true.B // set to strong bias on init } // case jmp @@ -293,6 +293,7 @@ class FTBEntryGen(implicit p: Parameters) extends XSModule with HasBackendRedire init_entry.tailSlot.offset := pd.jmpOffset init_entry.tailSlot.valid := new_jmp_is_jal || new_jmp_is_jalr init_entry.tailSlot.setLowerStatByTarget(io.start_addr, Mux(cfi_is_jalr, io.target, pd.jalTarget), isShare=false) + init_entry.strong_bias(numBr-1) := new_jmp_is_jalr // set strong bias for the jalr on init } val jmpPft = getLower(io.start_addr) +& pd.jmpOffset +& Mux(pd.rvcMask(pd.jmpOffset), 1.U, 2.U) @@ -329,9 +330,9 @@ class FTBEntryGen(implicit p: Parameters) extends XSModule with HasBackendRedire slot.valid := true.B slot.offset := new_br_offset slot.setLowerStatByTarget(io.start_addr, io.target, i == numBr-1) - old_entry_modified.always_taken(i) := true.B + old_entry_modified.strong_bias(i) := true.B }.elsewhen (new_br_offset > oe.allSlotsForBr(i).offset) { - old_entry_modified.always_taken(i) := false.B + old_entry_modified.strong_bias(i) := false.B // all other fields remain unchanged }.otherwise { // case i == 0, remain unchanged @@ -339,7 +340,7 @@ class FTBEntryGen(implicit p: Parameters) extends XSModule with HasBackendRedire val noNeedToMoveFromFormerSlot = (i == numBr-1).B && !oe.brSlots.last.valid when (!noNeedToMoveFromFormerSlot) { slot.fromAnotherSlot(oe.allSlotsForBr(i-1)) - old_entry_modified.always_taken(i) := oe.always_taken(i) + old_entry_modified.strong_bias(i) := oe.strong_bias(i) } } } @@ -372,15 +373,21 @@ class FTBEntryGen(implicit p: Parameters) extends XSModule with HasBackendRedire val jalr_target_modified = cfi_is_jalr && (old_target =/= io.target) && old_tail_is_jmp // TODO: pass full jalr target when (jalr_target_modified) { old_entry_jmp_target_modified.setByJmpTarget(io.start_addr, io.target) - old_entry_jmp_target_modified.always_taken := 0.U.asTypeOf(Vec(numBr, Bool())) + old_entry_jmp_target_modified.strong_bias := 0.U.asTypeOf(Vec(numBr, Bool())) } val old_entry_always_taken = WireInit(oe) val always_taken_modified_vec = Wire(Vec(numBr, Bool())) // whether modified or not for (i <- 0 until numBr) { - old_entry_always_taken.always_taken(i) := - oe.always_taken(i) && io.cfiIndex.valid && oe.brValids(i) && io.cfiIndex.bits === oe.brOffset(i) - always_taken_modified_vec(i) := oe.always_taken(i) && !old_entry_always_taken.always_taken(i) + if (i == numBr - 1){ + //strong bias of jalr should remain unchanged + old_entry_always_taken.strong_bias(i) := + oe.strong_bias(i) && io.cfiIndex.valid && io.cfiIndex.bits === oe.brOffset(i) && oe.tailSlot.valid + }else{ + old_entry_always_taken.strong_bias(i) := + oe.strong_bias(i) && io.cfiIndex.valid && oe.brValids(i) && io.cfiIndex.bits === oe.brOffset(i) + } + always_taken_modified_vec(i) := oe.strong_bias(i) && oe.brValids(i) && !old_entry_always_taken.strong_bias(i) } val always_taken_modified = always_taken_modified_vec.reduce(_||_) diff --git a/src/main/scala/xiangshan/frontend/Tage.scala b/src/main/scala/xiangshan/frontend/Tage.scala index db6d943d1c..09fc7d7bbf 100644 --- a/src/main/scala/xiangshan/frontend/Tage.scala +++ b/src/main/scala/xiangshan/frontend/Tage.scala @@ -625,7 +625,7 @@ class Tage(implicit p: Parameters) extends BaseTage { val u_valid = io.update.valid val update = io.update.bits val updateValids = VecInit((0 until TageBanks).map(w => - update.ftb_entry.brValids(w) && u_valid && !update.ftb_entry.always_taken(w) && + update.ftb_entry.brValids(w) && u_valid && !update.ftb_entry.strong_bias(w) && !(PriorityEncoder(update.br_taken_mask) < w.U))) val updateMeta = update.meta.asTypeOf(new TageMeta)