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