xref: /XiangShan/src/main/scala/xiangshan/backend/trace/Interface.scala (revision 491c16ade93d4956fec6dde187943d72bb010bc4)
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(hasOffset: Boolean = false)(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 ftqOffset = if (hasOffset)  Some(UInt(log2Up(PredictWidth).W)) else None
53      val itype     = UInt(ItypeWidth.W)
54      val iretire   = UInt(IretireWidthCompressed.W)
55      val ilastsize = UInt(IlastsizeWidth.W)
56    }))
57  })
58}
59
60object Itype extends NamedUInt(4) {
61  def None                 = 0.U
62  def Exception            = 1.U    //rob
63  def Interrupt            = 2.U    //rob
64  def ExpIntReturn         = 3.U    //rename
65  def NonTaken             = 4.U    //commit
66  def Taken                = 5.U    //commit
67  def UninferableJump      = 6.U    //It's reserved when width of itype is 4.
68  def reserved             = 7.U    //reserved
69  def UninferableCall      = 8.U    //rename
70  def InferableCall        = 9.U    //rename
71  def UninferableTailCall  = 10.U   //rename
72  def InferableTailCall    = 11.U   //rename
73  def CoRoutineSwap        = 12.U   //rename
74  def FunctionReturn       = 13.U   //rename
75  def OtherUninferableJump = 14.U   //rename
76  def OtherInferableJump   = 15.U   //rename
77
78  // Assuming the branchType is NonTaken here, it will be correctly modified after writeBack.
79  def Branch = NonTaken
80
81  def jumpTypeGen(brType: UInt, rd: OpRegType, rs: OpRegType): UInt = {
82
83    val isEqualRdRs = rd === rs
84    val isJal       = brType === BrType.jal
85    val isJalr      = brType === BrType.jalr
86    val isBranch    = brType === BrType.branch
87
88    // push to RAS when rd is link, pop from RAS when rs is link
89    def isUninferableCall      = isJalr && rd.isLink && (!rs.isLink || rs.isLink && isEqualRdRs)  //8   push
90    def isInferableCall        = isJal && rd.isLink                                               //9   push
91    def isUninferableTailCall  = isJalr && rd.isX0 && !rs.isLink                                  //10  no op
92    def isInferableTailCall    = isJal && rd.isX0                                                 //11  no op
93    def isCoRoutineSwap        = isJalr && rd.isLink && rs.isLink && !isEqualRdRs                 //12  pop then push
94    def isFunctionReturn       = isJalr && !rd.isLink && rs.isLink                                //13  pop
95    def isOtherUninferableJump = isJalr && !rd.isLink && !rd.isX0 && !rs.isLink                   //14  no op
96    def isOtherInferableJump   = isJal && !rd.isLink && !rd.isX0                                  //15  no op
97
98    val jumpType = Mux1H(
99      Seq(
100        isBranch,
101        isUninferableCall,
102        isInferableCall,
103        isUninferableTailCall,
104        isInferableTailCall,
105        isCoRoutineSwap,
106        isFunctionReturn,
107        isOtherUninferableJump,
108        isOtherInferableJump,
109      ),
110      Seq(
111        Branch,
112        UninferableCall,
113        InferableCall,
114        UninferableTailCall,
115        InferableTailCall,
116        CoRoutineSwap,
117        FunctionReturn,
118        OtherUninferableJump,
119        OtherInferableJump,
120      )
121    )
122
123    Mux(isBranch || isJal || isJalr, jumpType, 0.U)
124  }
125
126  def isTrap(itype: UInt) = Seq(Exception, Interrupt).map(_ === itype).reduce(_ || _)
127
128  def isTrapOrXret(itype: UInt) = Seq(Exception, Interrupt, ExpIntReturn).map(_ === itype).reduce(_ || _)
129
130  def isNotNone(itype: UInt) = itype =/= None
131
132  def isBranchType(itype: UInt) = itype === Branch
133
134  // supportSijump
135  def isUninferable(itype: UInt) = Seq(UninferableCall, UninferableTailCall, CoRoutineSwap,
136    UninferableTailCall, OtherUninferableJump).map(_ === itype).reduce(_ || _)
137}
138
139object Ilastsize extends NamedUInt(1) {
140  def HalfWord = 0.U
141  def Word     = 1.U
142}
143
144object Priv extends NamedUInt(3) {
145  def HU = 0.U
146  def HS = 1.U
147  def M  = 3.U
148  def D  = 4.U
149  def VU = 5.U
150  def VS = 6.U
151}
152
153class OpRegType extends Bundle {
154  val value = UInt(6.W)
155  def isX0   = this.value === 0.U
156  def isX1   = this.value === 1.U
157  def isX5   = this.value === 5.U
158  def isLink = Seq(isX1, isX5).reduce(_ || _)
159}
160