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