xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/TrapTvalMod.scala (revision 6639e9a467468f4e1b05a25a5de4500772aedeb1)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility.HasCircularQueuePtrHelper
7import xiangshan._
8import xiangshan.backend.fu.NewCSR.CSREvents.TargetPCBundle
9import xiangshan.backend.rob.RobPtr
10
11class TrapTvalMod(implicit p: Parameters) extends XSModule with HasCircularQueuePtrHelper {
12  val io = IO(new Bundle {
13    val fromCtrlBlock = Input(new Bundle {
14      val flush = ValidIO(new Redirect)
15      val robDeqPtr = Input(new RobPtr)
16    })
17
18    val targetPc = Input(ValidIO(new TargetPCBundle))
19    val clear = Input(Bool())
20    val tval = Output(UInt(XLEN.W))
21  })
22
23  private val valid = RegInit(false.B)
24  private val tval = Reg(UInt(XLEN.W))
25  private val robIdx = Reg(new RobPtr)
26
27  private val updateFromFlush = io.fromCtrlBlock.flush.valid && io.fromCtrlBlock.flush.bits.cfiUpdate.hasBackendFault
28  private val clearFromFlush = io.fromCtrlBlock.flush.valid && !io.fromCtrlBlock.flush.bits.cfiUpdate.hasBackendFault
29
30  when(io.targetPc.valid && io.targetPc.bits.raiseFault) {
31    valid := true.B
32    tval := io.targetPc.bits.pc
33    robIdx := io.fromCtrlBlock.robDeqPtr
34  }.elsewhen(valid) {
35    when(updateFromFlush && isBefore(io.fromCtrlBlock.flush.bits.robIdx, robIdx)) {
36      valid := true.B
37      tval := io.fromCtrlBlock.flush.bits.fullTarget
38      robIdx := io.fromCtrlBlock.flush.bits.robIdx
39    }.elsewhen(clearFromFlush && isBefore(io.fromCtrlBlock.flush.bits.robIdx, robIdx) || io.clear) {
40      valid := false.B
41    }
42  }.otherwise {
43    when(updateFromFlush) {
44      valid := true.B
45      tval := io.fromCtrlBlock.flush.bits.fullTarget
46      robIdx := io.fromCtrlBlock.flush.bits.robIdx
47    }
48  }
49
50  io.tval := tval
51
52  when(io.clear) { assert(valid) }
53}
54