xref: /XiangShan/src/main/scala/xiangshan/backend/trace/Interface.scala (revision 7da4513bca2c8a5b0aa433f4c859c25e12b2eb26)
1package xiangshan.backend.trace
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import utils.NamedUInt
7import xiangshan.HasXSParameter
8import xiangshan.frontend.{BrType, FtqPtr, PreDecodeInfo}
9
10class TraceCSR(implicit val p: Parameters) extends Bundle with HasXSParameter {
11  val cause = UInt(CauseWidth.W)
12  val tval  = UInt(TvalWidth.W)
13  val lastPriv    = Priv()
14  val currentPriv = Priv()
15}
16
17class TracePipe(iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
18  val itype     = Itype()
19  val iretire   = UInt(iretireWidth.W)
20  val ilastsize = Ilastsize()
21}
22
23class TraceBlock(hasIaddr: Boolean, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
24  val iaddr     = if (hasIaddr)   Some(UInt(IaddrWidth.W))                else None
25  val ftqIdx    = if (!hasIaddr)  Some(new FtqPtr)                        else None
26  val ftqOffset = if (!hasIaddr)  Some(UInt(log2Up(PredictWidth).W))      else None
27  val tracePipe = new TracePipe(iretireWidth)
28}
29
30class TraceBundle(hasIaddr: Boolean, blockSize: Int, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
31  val blocks = Vec(blockSize, ValidIO(new TraceBlock(hasIaddr, iretireWidth)))
32}
33
34class FromEncoder extends Bundle {
35  val enable = Bool()
36  val stall  = Bool()
37}
38
39class TraceCoreInterface(implicit val p: Parameters) extends Bundle with HasXSParameter {
40  val fromEncoder = Input(new Bundle {
41    val enable = Bool()
42    val stall  = Bool()
43  })
44  val toEncoder = Output(new Bundle {
45    val priv   = Priv()
46    val trap   = new Bundle{
47      val cause = UInt(CauseWidth.W)
48      val tval  = UInt(TvalWidth.W)
49    }
50    val groups = Vec(TraceGroupNum, ValidIO(new Bundle{
51      val iaddr     = UInt(IaddrWidth.W)
52      val itype     = UInt(ItypeWidth.W)
53      val iretire   = UInt(IretireWidthCompressed.W)
54      val ilastsize = UInt(IlastsizeWidth.W)
55    }))
56  })
57}
58
59object Itype extends NamedUInt(4) {
60  def None                 = 0.U
61  def Exception            = 1.U    //rob
62  def Interrupt            = 2.U    //rob
63  def ExpIntReturn         = 3.U    //rename
64  def NonTaken             = 4.U    //commit
65  def Taken                = 5.U    //commit
66  def UninferableJump      = 6.U    //It's reserved when width of itype is 4.
67  def reserved             = 7.U    //reserved
68  def UninferableCall      = 8.U    //rename
69  def InferableCall        = 9.U    //rename
70  def UninferableTailCall  = 10.U   //rename
71  def InferableTailCall    = 11.U   //rename
72  def CoRoutineSwap        = 12.U   //rename
73  def FunctionReturn       = 13.U   //rename
74  def OtherUninferableJump = 14.U   //rename
75  def OtherInferableJump   = 15.U   //rename
76
77  // Assuming the branchType is NonTaken here, it will be correctly modified after writeBack.
78  def Branch = NonTaken
79
80  def jumpTypeGen(brType: UInt, rd: OpRegType, rs: OpRegType): UInt = {
81
82    val isEqualRdRs = rd === rs
83    val isJal       = brType === BrType.jal
84    val isJalr      = brType === BrType.jalr
85    val isBranch    = brType === BrType.branch
86
87    // push to RAS when rd is link, pop from RAS when rs is link
88    def isUninferableCall      = isJalr && rd.isLink && (!rs.isLink || rs.isLink && isEqualRdRs)  //8   push
89    def isInferableCall        = isJal && rd.isLink                                               //9   push
90    def isUninferableTailCall  = isJalr && rd.isX0 && !rs.isLink                                  //10  no op
91    def isInferableTailCall    = isJal && rd.isX0                                                 //11  no op
92    def isCoRoutineSwap        = isJalr && rd.isLink && rs.isLink && !isEqualRdRs                 //12  pop then push
93    def isFunctionReturn       = isJalr && !rd.isLink && rs.isLink                                //13  pop
94    def isOtherUninferableJump = isJalr && !rd.isLink && !rd.isX0 && !rs.isLink                   //14  no op
95    def isOtherInferableJump   = isJal && !rd.isLink && !rd.isX0                                  //15  no op
96
97    val jumpType = Mux1H(
98      Seq(
99        isBranch,
100        isUninferableCall,
101        isInferableCall,
102        isUninferableTailCall,
103        isInferableTailCall,
104        isCoRoutineSwap,
105        isFunctionReturn,
106        isOtherUninferableJump,
107        isOtherInferableJump,
108      ),
109      Seq(
110        Branch,
111        UninferableCall,
112        InferableCall,
113        UninferableTailCall,
114        InferableTailCall,
115        CoRoutineSwap,
116        FunctionReturn,
117        OtherUninferableJump,
118        OtherInferableJump,
119      )
120    )
121
122    Mux(isBranch || isJal || isJalr, jumpType, 0.U)
123  }
124
125  def isTrap(itype: UInt) = Seq(Exception, Interrupt).map(_ === itype).reduce(_ || _)
126
127  def isTrapOrXret(itype: UInt) = Seq(Exception, Interrupt, ExpIntReturn).map(_ === itype).reduce(_ || _)
128
129  def isNotNone(itype: UInt) = itype =/= None
130
131  def isBranchType(itype: UInt) = itype === Branch
132
133  // supportSijump
134  def isUninferable(itype: UInt) = Seq(UninferableCall, UninferableTailCall, CoRoutineSwap,
135    UninferableTailCall, OtherUninferableJump).map(_ === itype).reduce(_ || _)
136}
137
138object Ilastsize extends NamedUInt(1) {
139  def HalfWord = 0.U
140  def Word     = 1.U
141}
142
143object Priv extends NamedUInt(3) {
144  def HU = 0.U
145  def HS = 1.U
146  def M  = 3.U
147  def D  = 4.U
148  def VU = 5.U
149  def VS = 6.U
150}
151
152class OpRegType extends Bundle {
153  val value = UInt(6.W)
154  def isX0   = this.value === 0.U
155  def isX1   = this.value === 1.U
156  def isX5   = this.value === 5.U
157  def isLink = Seq(isX1, isX5).reduce(_ || _)
158}
159