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