xref: /XiangShan/src/main/scala/xiangshan/frontend/RAS.scala (revision adc0b8df362e0cfb8fa501689b4ff9d64b86a618)
109c6f1ddSLingrui98/***************************************************************************************
209c6f1ddSLingrui98* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
309c6f1ddSLingrui98* Copyright (c) 2020-2021 Peng Cheng Laboratory
409c6f1ddSLingrui98*
509c6f1ddSLingrui98* XiangShan is licensed under Mulan PSL v2.
609c6f1ddSLingrui98* You can use this software according to the terms and conditions of the Mulan PSL v2.
709c6f1ddSLingrui98* You may obtain a copy of Mulan PSL v2 at:
809c6f1ddSLingrui98*          http://license.coscl.org.cn/MulanPSL2
909c6f1ddSLingrui98*
1009c6f1ddSLingrui98* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
1109c6f1ddSLingrui98* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
1209c6f1ddSLingrui98* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
1309c6f1ddSLingrui98*
1409c6f1ddSLingrui98* See the Mulan PSL v2 for more details.
1509c6f1ddSLingrui98***************************************************************************************/
1609c6f1ddSLingrui98
1709c6f1ddSLingrui98package xiangshan.frontend
1809c6f1ddSLingrui98
1909c6f1ddSLingrui98import chipsalliance.rocketchip.config.Parameters
2009c6f1ddSLingrui98import chisel3._
2109c6f1ddSLingrui98import chisel3.experimental.chiselName
2209c6f1ddSLingrui98import chisel3.util._
2309c6f1ddSLingrui98import utils._
243c02ee8fSwakafaimport utility._
2509c6f1ddSLingrui98import xiangshan._
2609c6f1ddSLingrui98
27*adc0b8dfSGuokai Chenimport scala.{Tuple2 => &}
28*adc0b8dfSGuokai Chen
29*adc0b8dfSGuokai Chen
3009c6f1ddSLingrui98class RASEntry()(implicit p: Parameters) extends XSBundle {
3109c6f1ddSLingrui98    val retAddr = UInt(VAddrBits.W)
3209c6f1ddSLingrui98    val ctr = UInt(8.W) // layer of nested call functions
3309c6f1ddSLingrui98}
3409c6f1ddSLingrui98
3509c6f1ddSLingrui98@chiselName
3609c6f1ddSLingrui98class RAS(implicit p: Parameters) extends BasePredictor {
3709c6f1ddSLingrui98  object RASEntry {
3809c6f1ddSLingrui98    def apply(retAddr: UInt, ctr: UInt): RASEntry = {
3909c6f1ddSLingrui98      val e = Wire(new RASEntry)
4009c6f1ddSLingrui98      e.retAddr := retAddr
4109c6f1ddSLingrui98      e.ctr := ctr
4209c6f1ddSLingrui98      e
4309c6f1ddSLingrui98    }
4409c6f1ddSLingrui98  }
4509c6f1ddSLingrui98
4609c6f1ddSLingrui98  @chiselName
4709c6f1ddSLingrui98  class RASStack(val rasSize: Int) extends XSModule {
4809c6f1ddSLingrui98    val io = IO(new Bundle {
4909c6f1ddSLingrui98      val push_valid = Input(Bool())
5009c6f1ddSLingrui98      val pop_valid = Input(Bool())
5109c6f1ddSLingrui98      val spec_new_addr = Input(UInt(VAddrBits.W))
5209c6f1ddSLingrui98
5309c6f1ddSLingrui98      val recover_sp = Input(UInt(log2Up(rasSize).W))
5409c6f1ddSLingrui98      val recover_top = Input(new RASEntry)
5509c6f1ddSLingrui98      val recover_valid = Input(Bool())
5609c6f1ddSLingrui98      val recover_push = Input(Bool())
5709c6f1ddSLingrui98      val recover_pop = Input(Bool())
5809c6f1ddSLingrui98      val recover_new_addr = Input(UInt(VAddrBits.W))
5909c6f1ddSLingrui98
6009c6f1ddSLingrui98      val sp = Output(UInt(log2Up(rasSize).W))
6109c6f1ddSLingrui98      val top = Output(new RASEntry)
6209c6f1ddSLingrui98    })
6309c6f1ddSLingrui98
6409c6f1ddSLingrui98    val debugIO = IO(new Bundle{
657e8709feSLingrui98        val spec_push_entry = Output(new RASEntry)
667e8709feSLingrui98        val spec_alloc_new = Output(Bool())
677e8709feSLingrui98        val recover_push_entry = Output(new RASEntry)
687e8709feSLingrui98        val recover_alloc_new = Output(Bool())
6909c6f1ddSLingrui98        val sp = Output(UInt(log2Up(rasSize).W))
7009c6f1ddSLingrui98        val topRegister = Output(new RASEntry)
7109c6f1ddSLingrui98        val out_mem = Output(Vec(RasSize, new RASEntry))
7209c6f1ddSLingrui98    })
7309c6f1ddSLingrui98
7409c6f1ddSLingrui98    val stack = Mem(RasSize, new RASEntry)
7509c6f1ddSLingrui98    val sp = RegInit(0.U(log2Up(rasSize).W))
768088cde1SGuokai Chen    val top = RegInit(0.U.asTypeOf(new RASEntry()))
7709c6f1ddSLingrui98    val topPtr = RegInit(0.U(log2Up(rasSize).W))
7809c6f1ddSLingrui98
79d0a8077aSLingrui98    val wen = WireInit(false.B)
808088cde1SGuokai Chen    val write_bypass_entry = RegInit(0.U.asTypeOf(new RASEntry()))
81eb6496c5SLingrui98    val write_bypass_ptr = RegInit(0.U(log2Up(rasSize).W))
82eb6496c5SLingrui98    val write_bypass_valid = RegInit(false.B)
83d0a8077aSLingrui98    when (wen) {
84d0a8077aSLingrui98      write_bypass_valid := true.B
85d0a8077aSLingrui98    }.elsewhen (write_bypass_valid) {
86d0a8077aSLingrui98      write_bypass_valid := false.B
87d0a8077aSLingrui98    }
88d0a8077aSLingrui98
89d0a8077aSLingrui98    when (write_bypass_valid) {
90d0a8077aSLingrui98      stack(write_bypass_ptr) := write_bypass_entry
91d0a8077aSLingrui98    }
92d0a8077aSLingrui98
9309c6f1ddSLingrui98    def ptrInc(ptr: UInt) = Mux(ptr === (rasSize-1).U, 0.U, ptr + 1.U)
9409c6f1ddSLingrui98    def ptrDec(ptr: UInt) = Mux(ptr === 0.U, (rasSize-1).U, ptr - 1.U)
9509c6f1ddSLingrui98
967e8709feSLingrui98    val spec_alloc_new = io.spec_new_addr =/= top.retAddr || top.ctr.andR
9709c6f1ddSLingrui98    val recover_alloc_new = io.recover_new_addr =/= io.recover_top.retAddr || io.recover_top.ctr.andR
9809c6f1ddSLingrui98
9909c6f1ddSLingrui98    // TODO: fix overflow and underflow bugs
10009c6f1ddSLingrui98    def update(recover: Bool)(do_push: Bool, do_pop: Bool, do_alloc_new: Bool,
10109c6f1ddSLingrui98                              do_sp: UInt, do_top_ptr: UInt, do_new_addr: UInt,
10209c6f1ddSLingrui98                              do_top: RASEntry) = {
10309c6f1ddSLingrui98      when (do_push) {
10409c6f1ddSLingrui98        when (do_alloc_new) {
10509c6f1ddSLingrui98          sp     := ptrInc(do_sp)
10609c6f1ddSLingrui98          topPtr := do_sp
10709c6f1ddSLingrui98          top.retAddr := do_new_addr
1087e8709feSLingrui98          top.ctr := 0.U
109d0a8077aSLingrui98          // write bypass
110d0a8077aSLingrui98          wen := true.B
111d0a8077aSLingrui98          write_bypass_entry := RASEntry(do_new_addr, 0.U)
112d0a8077aSLingrui98          write_bypass_ptr := do_sp
11309c6f1ddSLingrui98        }.otherwise {
11409c6f1ddSLingrui98          when (recover) {
11509c6f1ddSLingrui98            sp := do_sp
11609c6f1ddSLingrui98            topPtr := do_top_ptr
11709c6f1ddSLingrui98            top.retAddr := do_top.retAddr
11809c6f1ddSLingrui98          }
11909c6f1ddSLingrui98          top.ctr := do_top.ctr + 1.U
120d0a8077aSLingrui98          // write bypass
121d0a8077aSLingrui98          wen := true.B
122d0a8077aSLingrui98          write_bypass_entry := RASEntry(do_new_addr, do_top.ctr + 1.U)
123d0a8077aSLingrui98          write_bypass_ptr := do_top_ptr
12409c6f1ddSLingrui98        }
12509c6f1ddSLingrui98      }.elsewhen (do_pop) {
1267e8709feSLingrui98        when (do_top.ctr === 0.U) {
12709c6f1ddSLingrui98          sp     := ptrDec(do_sp)
12809c6f1ddSLingrui98          topPtr := ptrDec(do_top_ptr)
129d0a8077aSLingrui98          // read bypass
130d0a8077aSLingrui98          top :=
131d0a8077aSLingrui98            Mux(ptrDec(do_top_ptr) === write_bypass_ptr && write_bypass_valid,
132d0a8077aSLingrui98              write_bypass_entry,
133d0a8077aSLingrui98              stack.read(ptrDec(do_top_ptr))
134d0a8077aSLingrui98            )
13509c6f1ddSLingrui98        }.otherwise {
13609c6f1ddSLingrui98          when (recover) {
13709c6f1ddSLingrui98            sp := do_sp
13809c6f1ddSLingrui98            topPtr := do_top_ptr
13909c6f1ddSLingrui98            top.retAddr := do_top.retAddr
14009c6f1ddSLingrui98          }
14109c6f1ddSLingrui98          top.ctr := do_top.ctr - 1.U
142d0a8077aSLingrui98          // write bypass
143d0a8077aSLingrui98          wen := true.B
144d0a8077aSLingrui98          write_bypass_entry := RASEntry(do_top.retAddr, do_top.ctr - 1.U)
145d0a8077aSLingrui98          write_bypass_ptr := do_top_ptr
14609c6f1ddSLingrui98        }
14709c6f1ddSLingrui98      }.otherwise {
14809c6f1ddSLingrui98        when (recover) {
14909c6f1ddSLingrui98          sp := do_sp
15009c6f1ddSLingrui98          topPtr := do_top_ptr
15109c6f1ddSLingrui98          top := do_top
152d0a8077aSLingrui98          // write bypass
153d0a8077aSLingrui98          wen := true.B
154d0a8077aSLingrui98          write_bypass_entry := do_top
155d0a8077aSLingrui98          write_bypass_ptr := do_top_ptr
15609c6f1ddSLingrui98        }
15709c6f1ddSLingrui98      }
15809c6f1ddSLingrui98    }
15909c6f1ddSLingrui98
160d717fd1eSLingrui98
16109c6f1ddSLingrui98    update(io.recover_valid)(
16209c6f1ddSLingrui98      Mux(io.recover_valid, io.recover_push,     io.push_valid),
16309c6f1ddSLingrui98      Mux(io.recover_valid, io.recover_pop,      io.pop_valid),
1647e8709feSLingrui98      Mux(io.recover_valid, recover_alloc_new,   spec_alloc_new),
16509c6f1ddSLingrui98      Mux(io.recover_valid, io.recover_sp,       sp),
16609c6f1ddSLingrui98      Mux(io.recover_valid, io.recover_sp - 1.U, topPtr),
16709c6f1ddSLingrui98      Mux(io.recover_valid, io.recover_new_addr, io.spec_new_addr),
16809c6f1ddSLingrui98      Mux(io.recover_valid, io.recover_top,      top))
16909c6f1ddSLingrui98
17009c6f1ddSLingrui98    io.sp := sp
17109c6f1ddSLingrui98    io.top := top
17209c6f1ddSLingrui98
1736fe623afSLingrui98    val resetIdx = RegInit(0.U(log2Ceil(RasSize).W))
1746fe623afSLingrui98    val do_reset = RegInit(true.B)
1756fe623afSLingrui98    when (do_reset) {
1766fe623afSLingrui98      stack.write(resetIdx, RASEntry(0x80000000L.U, 0.U))
1776fe623afSLingrui98    }
1786fe623afSLingrui98    resetIdx := resetIdx + do_reset
1796fe623afSLingrui98    when (resetIdx === (RasSize-1).U) {
1806fe623afSLingrui98      do_reset := false.B
1816fe623afSLingrui98    }
1826fe623afSLingrui98
1837e8709feSLingrui98    debugIO.spec_push_entry := RASEntry(io.spec_new_addr, Mux(spec_alloc_new, 1.U, top.ctr + 1.U))
1847e8709feSLingrui98    debugIO.spec_alloc_new := spec_alloc_new
1857e8709feSLingrui98    debugIO.recover_push_entry := RASEntry(io.recover_new_addr, Mux(recover_alloc_new, 1.U, io.recover_top.ctr + 1.U))
1867e8709feSLingrui98    debugIO.recover_alloc_new := recover_alloc_new
18709c6f1ddSLingrui98    debugIO.sp := sp
18809c6f1ddSLingrui98    debugIO.topRegister := top
18909c6f1ddSLingrui98    for (i <- 0 until RasSize) {
190d0a8077aSLingrui98        debugIO.out_mem(i) := Mux(i.U === write_bypass_ptr && write_bypass_valid, write_bypass_entry, stack.read(i.U))
19109c6f1ddSLingrui98    }
19209c6f1ddSLingrui98  }
19309c6f1ddSLingrui98
19409c6f1ddSLingrui98  val spec = Module(new RASStack(RasSize))
19509c6f1ddSLingrui98  val spec_ras = spec.io
196cb4f77ceSLingrui98  val spec_top_addr = spec_ras.top.retAddr
19709c6f1ddSLingrui98
19809c6f1ddSLingrui98
199cb4f77ceSLingrui98  val s2_spec_push = WireInit(false.B)
200cb4f77ceSLingrui98  val s2_spec_pop = WireInit(false.B)
201f4ebc4b2SLingrui98  val s2_full_pred = io.in.bits.resp_in(0).s2.full_pred
202f4ebc4b2SLingrui98  // when last inst is an rvi call, fall through address would be set to the middle of it, so an addition is needed
203*adc0b8dfSGuokai Chen  val s2_spec_new_addr = s2_full_pred(2).fallThroughAddr + Mux(s2_full_pred(2).last_may_be_rvi_call, 2.U, 0.U)
204cb4f77ceSLingrui98  spec_ras.push_valid := s2_spec_push
205cb4f77ceSLingrui98  spec_ras.pop_valid  := s2_spec_pop
206cb4f77ceSLingrui98  spec_ras.spec_new_addr := s2_spec_new_addr
20709c6f1ddSLingrui98
20809c6f1ddSLingrui98  // confirm that the call/ret is the taken cfi
209*adc0b8dfSGuokai Chen  s2_spec_push := io.s2_fire(2) && s2_full_pred(2).hit_taken_on_call && !io.s3_redirect(2)
210*adc0b8dfSGuokai Chen  s2_spec_pop  := io.s2_fire(2) && s2_full_pred(2).hit_taken_on_ret  && !io.s3_redirect(2)
21109c6f1ddSLingrui98
212*adc0b8dfSGuokai Chen  val s2_jalr_target_dup = io.out.s2.full_pred.map(_.jalr_target)
213*adc0b8dfSGuokai Chen  val s2_last_target_in_dup = s2_full_pred.map(_.targets.last)
214*adc0b8dfSGuokai Chen  val s2_last_target_out_dup = io.out.s2.full_pred.map(_.targets.last)
215*adc0b8dfSGuokai Chen  val s2_is_jalr_dup = s2_full_pred.map(_.is_jalr)
216*adc0b8dfSGuokai Chen  val s2_is_ret_dup = s2_full_pred.map(_.is_ret)
217b30c10d6SLingrui98  // assert(is_jalr && is_ret || !is_ret)
218*adc0b8dfSGuokai Chen  val ras_enable_dup = dup(RegNext(io.ctrl.ras_enable))
219*adc0b8dfSGuokai Chen  for (ras_enable & s2_is_ret & s2_jalr_target <-
220*adc0b8dfSGuokai Chen    ras_enable_dup zip s2_is_ret_dup zip s2_jalr_target_dup) {
221*adc0b8dfSGuokai Chen      when(s2_is_ret && ras_enable) {
222cb4f77ceSLingrui98        s2_jalr_target := spec_top_addr
223b30c10d6SLingrui98        // FIXME: should use s1 globally
22409c6f1ddSLingrui98      }
225*adc0b8dfSGuokai Chen    }
226*adc0b8dfSGuokai Chen  for (s2_lto & s2_is_jalr & s2_jalr_target & s2_lti <-
227*adc0b8dfSGuokai Chen    s2_last_target_out_dup zip s2_is_jalr_dup zip s2_jalr_target_dup zip s2_last_target_in_dup) {
228*adc0b8dfSGuokai Chen      s2_lto := Mux(s2_is_jalr, s2_jalr_target, s2_lti)
229*adc0b8dfSGuokai Chen    }
23009c6f1ddSLingrui98
231*adc0b8dfSGuokai Chen  val s3_top_dup = io.s2_fire.map(f => RegEnable(spec_ras.top, f))
232*adc0b8dfSGuokai Chen  val s3_sp = RegEnable(spec_ras.sp, io.s2_fire(2))
233*adc0b8dfSGuokai Chen  val s3_spec_new_addr = RegEnable(s2_spec_new_addr, io.s2_fire(2))
234cb4f77ceSLingrui98
235*adc0b8dfSGuokai Chen  val s3_full_pred = io.in.bits.resp_in(0).s3.full_pred
236*adc0b8dfSGuokai Chen  val s3_jalr_target_dup = io.out.s3.full_pred.map(_.jalr_target)
237*adc0b8dfSGuokai Chen  val s3_last_target_in_dup = s3_full_pred.map(_.targets.last)
238*adc0b8dfSGuokai Chen  val s3_last_target_out_dup = io.out.s3.full_pred.map(_.targets.last)
239*adc0b8dfSGuokai Chen  val s3_is_jalr_dup = s3_full_pred.map(_.is_jalr)
240*adc0b8dfSGuokai Chen  val s3_is_ret_dup = s3_full_pred.map(_.is_ret)
241cb4f77ceSLingrui98  // assert(is_jalr && is_ret || !is_ret)
242*adc0b8dfSGuokai Chen
243*adc0b8dfSGuokai Chen  for (ras_enable & s3_is_ret & s3_jalr_target & s3_top <-
244*adc0b8dfSGuokai Chen    ras_enable_dup zip s3_is_ret_dup zip s3_jalr_target_dup zip s3_top_dup) {
245*adc0b8dfSGuokai Chen      when(s3_is_ret && ras_enable) {
246cb4f77ceSLingrui98        s3_jalr_target := s3_top.retAddr
247cb4f77ceSLingrui98        // FIXME: should use s1 globally
248cb4f77ceSLingrui98      }
249*adc0b8dfSGuokai Chen    }
250*adc0b8dfSGuokai Chen  for (s3_lto & s3_is_jalr & s3_jalr_target & s3_lti <-
251*adc0b8dfSGuokai Chen    s3_last_target_out_dup zip s3_is_jalr_dup zip s3_jalr_target_dup zip s3_last_target_in_dup) {
252*adc0b8dfSGuokai Chen      s3_lto := Mux(s3_is_jalr, s3_jalr_target, s3_lti)
253*adc0b8dfSGuokai Chen    }
254cb4f77ceSLingrui98
255*adc0b8dfSGuokai Chen  val s3_pushed_in_s2 = RegEnable(s2_spec_push, io.s2_fire(2))
256*adc0b8dfSGuokai Chen  val s3_popped_in_s2 = RegEnable(s2_spec_pop,  io.s2_fire(2))
257*adc0b8dfSGuokai Chen  val s3_push = io.in.bits.resp_in(0).s3.full_pred(2).hit_taken_on_call
258*adc0b8dfSGuokai Chen  val s3_pop  = io.in.bits.resp_in(0).s3.full_pred(2).hit_taken_on_ret
259cb4f77ceSLingrui98
260*adc0b8dfSGuokai Chen  val s3_recover = io.s3_fire(2) && (s3_pushed_in_s2 =/= s3_push || s3_popped_in_s2 =/= s3_pop)
261c2d1ec7dSLingrui98  io.out.last_stage_spec_info.rasSp  := s3_sp
262*adc0b8dfSGuokai Chen  io.out.last_stage_spec_info.rasTop := s3_top_dup(2)
26309c6f1ddSLingrui98
26409c6f1ddSLingrui98
26509c6f1ddSLingrui98  val redirect = RegNext(io.redirect)
266cb4f77ceSLingrui98  val do_recover = redirect.valid || s3_recover
26709c6f1ddSLingrui98  val recover_cfi = redirect.bits.cfiUpdate
26809c6f1ddSLingrui98
26909c6f1ddSLingrui98  val retMissPred  = do_recover && redirect.bits.level === 0.U && recover_cfi.pd.isRet
27009c6f1ddSLingrui98  val callMissPred = do_recover && redirect.bits.level === 0.U && recover_cfi.pd.isCall
27109c6f1ddSLingrui98  // when we mispredict a call, we must redo a push operation
27209c6f1ddSLingrui98  // similarly, when we mispredict a return, we should redo a pop
27309c6f1ddSLingrui98  spec_ras.recover_valid := do_recover
2745df98e43SLingrui98  spec_ras.recover_push := Mux(redirect.valid, callMissPred, s3_push)
2755df98e43SLingrui98  spec_ras.recover_pop  := Mux(redirect.valid, retMissPred, s3_pop)
27609c6f1ddSLingrui98
277cb4f77ceSLingrui98  spec_ras.recover_sp  := Mux(redirect.valid, recover_cfi.rasSp, s3_sp)
278*adc0b8dfSGuokai Chen  spec_ras.recover_top := Mux(redirect.valid, recover_cfi.rasEntry, s3_top_dup(2))
279cb4f77ceSLingrui98  spec_ras.recover_new_addr := Mux(redirect.valid, recover_cfi.pc + Mux(recover_cfi.pd.isRVC, 2.U, 4.U), s3_spec_new_addr)
28009c6f1ddSLingrui98
281cb4f77ceSLingrui98
282cb4f77ceSLingrui98  XSPerfAccumulate("ras_s3_recover", s3_recover)
283cb4f77ceSLingrui98  XSPerfAccumulate("ras_redirect_recover", redirect.valid)
284cb4f77ceSLingrui98  XSPerfAccumulate("ras_s3_and_redirect_recover_at_the_same_time", s3_recover && redirect.valid)
28509c6f1ddSLingrui98  // TODO: back-up stack for ras
28609c6f1ddSLingrui98  // use checkpoint to recover RAS
28709c6f1ddSLingrui98
28809c6f1ddSLingrui98  val spec_debug = spec.debugIO
28909c6f1ddSLingrui98  XSDebug("----------------RAS----------------\n")
29009c6f1ddSLingrui98  XSDebug(" TopRegister: 0x%x   %d \n",spec_debug.topRegister.retAddr,spec_debug.topRegister.ctr)
29109c6f1ddSLingrui98  XSDebug("  index       addr           ctr \n")
29209c6f1ddSLingrui98  for(i <- 0 until RasSize){
29309c6f1ddSLingrui98      XSDebug("  (%d)   0x%x      %d",i.U,spec_debug.out_mem(i).retAddr,spec_debug.out_mem(i).ctr)
29409c6f1ddSLingrui98      when(i.U === spec_debug.sp){XSDebug(false,true.B,"   <----sp")}
29509c6f1ddSLingrui98      XSDebug(false,true.B,"\n")
29609c6f1ddSLingrui98  }
2977e8709feSLingrui98  XSDebug(s2_spec_push, "s2_spec_push  inAddr: 0x%x  inCtr: %d |  allocNewEntry:%d |   sp:%d \n",
2987e8709feSLingrui98  s2_spec_new_addr,spec_debug.spec_push_entry.ctr,spec_debug.spec_alloc_new,spec_debug.sp.asUInt)
299*adc0b8dfSGuokai Chen  XSDebug(s2_spec_pop, "s2_spec_pop  outAddr: 0x%x \n",io.out.s2.getTarget(2))
3007e8709feSLingrui98  val s3_recover_entry = spec_debug.recover_push_entry
3017e8709feSLingrui98  XSDebug(s3_recover && s3_push, "s3_recover_push  inAddr: 0x%x  inCtr: %d |  allocNewEntry:%d |   sp:%d \n",
3027e8709feSLingrui98    s3_recover_entry.retAddr, s3_recover_entry.ctr, spec_debug.recover_alloc_new, s3_sp.asUInt)
303*adc0b8dfSGuokai Chen  XSDebug(s3_recover && s3_pop, "s3_recover_pop  outAddr: 0x%x \n",io.out.s3.getTarget(2))
30409c6f1ddSLingrui98  val redirectUpdate = redirect.bits.cfiUpdate
3057e8709feSLingrui98  XSDebug(do_recover && callMissPred, "redirect_recover_push\n")
3067e8709feSLingrui98  XSDebug(do_recover && retMissPred, "redirect_recover_pop\n")
3077e8709feSLingrui98  XSDebug(do_recover, "redirect_recover(SP:%d retAddr:%x ctr:%d) \n",
3087e8709feSLingrui98      redirectUpdate.rasSp,redirectUpdate.rasEntry.retAddr,redirectUpdate.rasEntry.ctr)
3094813e060SLingrui98
3104813e060SLingrui98  generatePerfEvent()
31109c6f1ddSLingrui98}
312