@@ -67,10 +67,8 @@ class MicroBtb(implicit p: Parameters) extends BasePredictor with HasMicroBtbPar
6767 private val s1_hitIdx = OHToUInt (s1_hitOH)
6868 private val s1_hitEntry = entries(s1_hitIdx)
6969
70- // we do not need to check attribute.isDirect/Indirect here, as entry.slot1.takenCnt is initialized to weak taken
71- // and for those jumps, takenCnt will remain unchanged during training,
72- // so e.slot1.takenCnt.isPositive is always true if e.slot1.attribute.isDirect/Indirect
73- io.prediction.taken := s1_hit && s1_hitEntry.slot1.takenCnt.isPositive
70+ // we do always-taken prediction in ubtb
71+ io.prediction.taken := s1_hit
7472 io.prediction.cfiPosition := s1_hitEntry.slot1.position
7573 io.prediction.target := getFullTarget(s1_startVAddr, s1_hitEntry.slot1.target, s1_hitEntry.slot1.targetCarry)
7674 io.prediction.attribute := s1_hitEntry.slot1.attribute
@@ -142,12 +140,9 @@ class MicroBtb(implicit p: Parameters) extends BasePredictor with HasMicroBtbPar
142140
143141 // calculate hit flags, valid only when t0_hit
144142 private val t0_hitNotUseful = t0_hitEntry.usefulCnt.isSaturateNegative
145- private val t0_hitPositionLow = t0_hitEntry.slot1.position > t0_position
146- private val t0_hitPositionHigh = t0_hitEntry.slot1.position < t0_position
147143 private val t0_hitPositionSame = t0_hitEntry.slot1.position === t0_position
148144 private val t0_hitAttributeSame = t0_hitEntry.slot1.attribute === t0_attribute
149145 private val t0_hitTargetSame = t0_hitEntry.slot1.target === t0_target
150- private val t0_hitTaken = t0_hitEntry.slot1.takenCnt.isPositive
151146
152147 /* *** train stage 1 ***
153148 * - select victim
@@ -169,24 +164,19 @@ class MicroBtb(implicit p: Parameters) extends BasePredictor with HasMicroBtbPar
169164
170165 // hit states (flags), valid only when t1_hit
171166 private val t1_hitNotUseful = RegEnable (t0_hitNotUseful, t0_valid)
172- private val t1_hitPositionLow = RegEnable (t0_hitPositionLow, t0_valid)
173- private val t1_hitPositionHigh = RegEnable (t0_hitPositionHigh, t0_valid)
174167 private val t1_hitPositionSame = RegEnable (t0_hitPositionSame, t0_valid)
175168 private val t1_hitAttributeSame = RegEnable (t0_hitAttributeSame, t0_valid)
176169 private val t1_hitTargetSame = RegEnable (t0_hitTargetSame, t0_valid)
177- private val t1_hitTaken = RegEnable (t0_hitTaken, t0_valid)
178170
179171 // init a new entry
180172 private def initEntryIfNotUseful (notUseful : Bool ): Unit =
181173 when(notUseful) {
182- t1_updatedEntry.valid := true .B
183- t1_updatedEntry.tag := t1_tag
174+ t1_updatedEntry.tag := t1_tag
184175 t1_updatedEntry.usefulCnt.resetPositive() // usefulCnt inits at strong positive, in/decrease by policy
185176 // slot1
186- t1_updatedEntry.slot1.position := t1_position
187- t1_updatedEntry.slot1.attribute := t1_attribute
188- t1_updatedEntry.slot1.target := t1_target
189- t1_updatedEntry.slot1.takenCnt.resetNeutral() // takenCnt inits at neutral (weak taken), in/decrease by policy
177+ t1_updatedEntry.slot1.position := t1_position
178+ t1_updatedEntry.slot1.attribute := t1_attribute
179+ t1_updatedEntry.slot1.target := t1_target
190180 t1_updatedEntry.slot1.isStaticTarget := true .B // inits at true, set to false when we see a different target
191181 t1_updatedEntry.slot1.targetCarry.foreach(_ := t1_targetCarry.get) // if (EnableTargetFix)
192182 // TODO: 2-taken train
@@ -198,63 +188,20 @@ class MicroBtb(implicit p: Parameters) extends BasePredictor with HasMicroBtbPar
198188 when(t1_valid) {
199189 when(! t1_hit) {
200190 // not hit
201- // simply init a new entry
191+ // init a new entry if actually taken
202192 initEntryIfNotUseful(true .B )
203- }.elsewhen(! t1_hitAttributeSame) {
204- // hit, but attribute mismatch
205- // if already not useful, init a new entry, otherwise decrease usefulCnt
193+ }.elsewhen(! t1_hitAttributeSame || ! t1_hitPositionSame || ! t1_hitTargetSame || ! t1_actualTaken ) {
194+ // hit, but attribute/position mismatch, or actually not taken
195+ // if already not useful and actually taken , init a new entry, otherwise decrease usefulCnt
206196 initEntryIfNotUseful(t1_hitNotUseful)
207- }.elsewhen(t1_attribute.isConditional) {
208- // attribute match, and is conditional (branch)
209- when(
210- // branch position match, and actual taken
211- t1_hitPositionSame && t1_actualTaken
212- ) {
213- // increase takenCnt
214- t1_updatedEntry.slot1.takenCnt.value := t1_hitEntry.slot1.takenCnt.getIncrease
215- }.elsewhen(
216- // branch position match, and actual not taken
217- t1_hitPositionSame && ! t1_actualTaken ||
218- // an actual taken branch is at higher address -> the predicted position is actual not taken
219- t1_hitPositionHigh && t1_actualTaken ||
220- // actual not taken, but predicted taken -> no matter position, the predicted position is actual not taken
221- ! t1_actualTaken && t1_hitTaken
222- ) {
223- // decrease takenCnt
224- t1_updatedEntry.slot1.takenCnt.value := t1_hitEntry.slot1.takenCnt.getDecrease
225- }
226- when(
227- // branch position match, and both actual & predicted taken -> prediction correct, useful
228- t1_hitPositionSame && t1_actualTaken && t1_hitTaken
229- ) {
230- // increase usefulCnt
231- t1_updatedEntry.usefulCnt.value := t1_hitEntry.usefulCnt.getIncrease
232- }.elsewhen(
233- // position mismatch -> not useful
234- ! t1_hitPositionSame ||
235- // actual not taken -> fall through, not useful
236- ! t1_actualTaken
237- ) {
238- // decrease usefulCnt
239- t1_updatedEntry.usefulCnt.value := t1_hitEntry.usefulCnt.getDecrease
240- }
241- }.otherwise {
242- // attribute match, and is direct / indirect jump
243- when(! t1_hitPositionSame) {
244- // position mismatch
245- // if already not useful, init a new entry, otherwise decrease usefulCnt
246- initEntryIfNotUseful(t1_hitNotUseful)
247- }.elsewhen(t1_hitTargetSame) {
248- // position match, and target match
249- // increase usefulCnt
250- t1_updatedEntry.usefulCnt.value := t1_hitEntry.usefulCnt.getIncrease
251- }.otherwise {
252- // position match, but target mismatch (should not happen for direct jumps unless self-modifies)
253- // decrease usefulCnt
254- t1_updatedEntry.usefulCnt.value := t1_hitEntry.usefulCnt.getDecrease
255- // and, since we've seen a different target, target is not static anymore
197+ // and, if we've seen a different target, mark target as not static
198+ when(! t1_hitTargetSame) {
256199 t1_updatedEntry.slot1.isStaticTarget := false .B
257200 }
201+ }.otherwise {
202+ // everything matches, and actually taken
203+ // increase usefulCnt
204+ t1_updatedEntry.usefulCnt.value := t1_hitEntry.usefulCnt.getIncrease
258205 }
259206 }
260207
@@ -284,31 +231,4 @@ class MicroBtb(implicit p: Parameters) extends BasePredictor with HasMicroBtbPar
284231 t1_hitAttributeSame && ! t1_hitPositionSame && t1_hitNotUseful
285232 )
286233 )
287-
288- XSPerfAccumulate (" mispredictAttribute" , t1_valid && t1_hit && ! t1_hitAttributeSame)
289-
290- XSPerfAccumulate (
291- " mispredictConditional" ,
292- t1_valid && t1_hit && t1_hitAttributeSame && t1_attribute.isConditional && (
293- t1_hitPositionSame && t1_actualTaken && ! t1_hitTaken ||
294- t1_hitPositionHigh && t1_actualTaken ||
295- ! t1_actualTaken && t1_hitTaken
296- )
297- )
298-
299- XSPerfAccumulate (
300- " mispredictDirect" ,
301- t1_valid && t1_hit && t1_hitAttributeSame && t1_attribute.isDirect && (
302- ! t1_hitPositionSame ||
303- ! t1_hitTargetSame // should not happen unless self-modifies
304- )
305- )
306-
307- XSPerfAccumulate (
308- " mispredictIndirect" ,
309- t1_valid && t1_hit && t1_hitAttributeSame && t1_attribute.isIndirect && (
310- ! t1_hitPositionSame ||
311- ! t1_hitTargetSame
312- )
313- )
314234}
0 commit comments