xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/TrapInstMod.scala (revision 1bc48dd1fa0af361fd194c65bad3b86349ec2903)
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    when (!valid) {
66      trapInstInfo := newCSRInst
67    }.elsewhen(valid &&
68      (newCSRInst.ftqPtr === trapInstInfo.ftqPtr && newCSRInst.ftqOffset < trapInstInfo.ftqOffset ||
69      newCSRInst.ftqPtr < trapInstInfo.ftqPtr)
70    ) {
71      trapInstInfo := newCSRInst
72    }
73  }.elsewhen(newTrapInstInfo.valid && !valid) {
74    valid := true.B
75    trapInstInfo := newTrapInstInfo.bits
76    trapInstInfo.instr := Mux(
77      newTrapInstInfo.bits.instr(1, 0) === "b11".U,
78      newTrapInstInfo.bits.instr,
79      newTrapInstInfo.bits.instr(15, 0)
80    )
81  }
82
83  io.currentTrapInst.valid := valid
84  io.currentTrapInst.bits := trapInstInfo.instr
85}
86