xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/TrapInstMod.scala (revision 887862dbb8debde8ab099befc426493834a69ee7)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utility.{HasCircularQueuePtrHelper, XSError}
7import xiangshan._
8import xiangshan.backend.Bundles.TrapInstInfo
9import xiangshan.backend.decode.Imm_Z
10import xiangshan.frontend.FtqPtr
11import xiangshan.backend.decode.isa.bitfield.OPCODE5Bit
12
13class FtqInfo(implicit p: Parameters) extends XSBundle {
14  val ftqPtr = new FtqPtr()
15  val ftqOffset = UInt(log2Up(PredictWidth).W)
16}
17
18class TrapInstMod(implicit p: Parameters) extends Module with HasCircularQueuePtrHelper {
19  val io = IO(new Bundle {
20    val fromDecode = Input(new Bundle {
21      val trapInstInfo = ValidIO(new TrapInstInfo)
22    })
23
24    val fromRob = Input(new Bundle {
25      val flush = ValidIO(new FtqInfo)
26    })
27
28    val faultCsrUop = Input(ValidIO(new Bundle {
29      val fuOpType = FuOpType()
30      val imm      = UInt(Imm_Z().len.W)
31      val ftqInfo  = new FtqInfo
32    }))
33
34    val readClear = Input(Bool())
35    val currentTrapInst = Output(ValidIO(UInt(32.W)))
36  })
37
38  // alias
39  val flush = io.fromRob.flush
40  val newTrapInstInfo = io.fromDecode.trapInstInfo
41
42  val valid = RegInit(false.B)
43  val trapInstInfo = Reg(new TrapInstInfo)
44
45  val csrAddr = Imm_Z().getCSRAddr(io.faultCsrUop.bits.imm)
46  val rs1 = Imm_Z().getRS1(io.faultCsrUop.bits.imm)
47  val rd = Imm_Z().getRD(io.faultCsrUop.bits.imm)
48  val func3 = CSROpType.getFunc3(io.faultCsrUop.bits.fuOpType)
49
50  val csrInst = Cat(csrAddr, rs1, func3, rd, OPCODE5Bit.SYSTEM, "b11".U)
51  require(csrInst.getWidth == 32)
52
53  val newCSRInstValid = io.faultCsrUop.valid
54  val newCSRInst = WireInit(0.U.asTypeOf(new TrapInstInfo))
55  newCSRInst.instr := csrInst
56  newCSRInst.ftqPtr := io.faultCsrUop.bits.ftqInfo.ftqPtr
57  newCSRInst.ftqOffset := io.faultCsrUop.bits.ftqInfo.ftqOffset
58
59  when (flush.valid && valid && trapInstInfo.needFlush(flush.bits.ftqPtr, flush.bits.ftqOffset)) {
60    valid := false.B
61  }.elsewhen(io.readClear) {
62    valid := false.B
63  }.elsewhen(newCSRInstValid) {
64    valid := true.B
65    trapInstInfo := newCSRInst
66  }.elsewhen(newTrapInstInfo.valid && !valid) {
67    valid := true.B
68    trapInstInfo := newTrapInstInfo.bits
69    trapInstInfo.instr := Mux(
70      newTrapInstInfo.bits.instr(1, 0) === "b11".U,
71      newTrapInstInfo.bits.instr,
72      newTrapInstInfo.bits.instr(15, 0)
73    )
74  }
75
76  io.currentTrapInst.valid := valid
77  io.currentTrapInst.bits := trapInstInfo.instr
78}
79