xref: /XiangShan/src/main/scala/xiangshan/backend/trace/Interface.scala (revision 725e8ddc29ec6e96d16ceac10ae685c894296556)
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 TraceTrap(implicit val p: Parameters) extends Bundle with HasXSParameter {
11  val cause = UInt(CauseWidth.W)
12  val tval  = UInt(TvalWidth.W)
13  val priv  = Priv()
14}
15
16class TracePipe(iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
17  val itype     = Itype()
18  val iretire   = UInt(iretireWidth.W)
19  val ilastsize = Ilastsize()
20}
21
22class TraceBlock(hasIaddr: Boolean, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
23  val iaddr     = if (hasIaddr)   Some(UInt(IaddrWidth.W))                else None
24  val ftqIdx    = if (!hasIaddr)  Some(new FtqPtr)                        else None
25  val ftqOffset = if (!hasIaddr)  Some(UInt(log2Up(PredictWidth).W))      else None
26  val tracePipe = new TracePipe(iretireWidth)
27}
28
29class TraceBundle(hasIaddr: Boolean, blockSize: Int, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
30  val trap = Output(new TraceTrap)
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 isNotNone(itype: UInt) = itype =/= None
124
125  def isBranchType(itype: UInt) = itype === Branch
126
127  // supportSijump
128  def isUninferable(itype: UInt) = Seq(UninferableCall, UninferableTailCall, CoRoutineSwap,
129    UninferableTailCall, OtherUninferableJump).map(_ === itype).reduce(_ || _)
130}
131
132object Ilastsize extends NamedUInt(1) {
133  def HalfWord = 0.U
134  def Word     = 1.U
135}
136
137object Priv extends NamedUInt(3) {
138  def HU = 0.U
139  def HS = 1.U
140  def M  = 3.U
141  def D  = 4.U
142  def VU = 5.U
143  def VS = 6.U
144}
145
146class OpRegType extends Bundle {
147  val value = UInt(6.W)
148  def isX0   = this.value === 0.U
149  def isX1   = this.value === 1.U
150  def isX5   = this.value === 5.U
151  def isLink = Seq(isX1, isX5).reduce(_ || _)
152}
153