xref: /XiangShan/src/main/scala/xiangshan/backend/trace/Interface.scala (revision fd448a9d595e5d45a847c41429d2cb838496664e)
149162c9aSGuanghui Chengpackage xiangshan.backend.trace
249162c9aSGuanghui Cheng
349162c9aSGuanghui Chengimport chisel3._
449162c9aSGuanghui Chengimport chisel3.util._
549162c9aSGuanghui Chengimport org.chipsalliance.cde.config.Parameters
649162c9aSGuanghui Chengimport utils.NamedUInt
749162c9aSGuanghui Chengimport xiangshan.HasXSParameter
849162c9aSGuanghui Chengimport xiangshan.frontend.{BrType, FtqPtr, PreDecodeInfo}
949162c9aSGuanghui Cheng
10c308d936Schengguanghuiclass TraceCSR(implicit val p: Parameters) extends Bundle with HasXSParameter {
114907ec88Schengguanghui  val cause = UInt(CauseWidth.W)
124907ec88Schengguanghui  val tval  = UInt(TvalWidth.W)
13c308d936Schengguanghui  val lastPriv    = Priv()
14c308d936Schengguanghui  val currentPriv = Priv()
1549162c9aSGuanghui Cheng}
1649162c9aSGuanghui Cheng
1749162c9aSGuanghui Chengclass TracePipe(iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
1849162c9aSGuanghui Cheng  val itype     = Itype()
1949162c9aSGuanghui Cheng  val iretire   = UInt(iretireWidth.W)
2049162c9aSGuanghui Cheng  val ilastsize = Ilastsize()
2149162c9aSGuanghui Cheng}
2249162c9aSGuanghui Cheng
2349162c9aSGuanghui Chengclass TraceBlock(hasIaddr: Boolean, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
244907ec88Schengguanghui  val iaddr     = if (hasIaddr)   Some(UInt(IaddrWidth.W))                else None
2549162c9aSGuanghui Cheng  val ftqIdx    = if (!hasIaddr)  Some(new FtqPtr)                        else None
2649162c9aSGuanghui Cheng  val ftqOffset = if (!hasIaddr)  Some(UInt(log2Up(PredictWidth).W))      else None
2749162c9aSGuanghui Cheng  val tracePipe = new TracePipe(iretireWidth)
2849162c9aSGuanghui Cheng}
2949162c9aSGuanghui Cheng
3049162c9aSGuanghui Chengclass TraceBundle(hasIaddr: Boolean, blockSize: Int, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter {
3149162c9aSGuanghui Cheng  val blocks = Vec(blockSize, ValidIO(new TraceBlock(hasIaddr, iretireWidth)))
3249162c9aSGuanghui Cheng}
3349162c9aSGuanghui Cheng
3449162c9aSGuanghui Chengclass FromEncoder extends Bundle {
3549162c9aSGuanghui Cheng  val enable = Bool()
3649162c9aSGuanghui Cheng  val stall  = Bool()
3749162c9aSGuanghui Cheng}
3849162c9aSGuanghui Cheng
39*fd448a9dSchengguanghuiclass TraceCoreInterface(hasOffset: Boolean = false)(implicit val p: Parameters) extends Bundle with HasXSParameter {
4049162c9aSGuanghui Cheng  val fromEncoder = Input(new Bundle {
4149162c9aSGuanghui Cheng    val enable = Bool()
4249162c9aSGuanghui Cheng    val stall  = Bool()
4349162c9aSGuanghui Cheng  })
4449162c9aSGuanghui Cheng  val toEncoder = Output(new Bundle {
453ad9f3ddSchengguanghui    val priv   = Priv()
463ad9f3ddSchengguanghui    val trap   = new Bundle{
4749162c9aSGuanghui Cheng      val cause = UInt(CauseWidth.W)
4849162c9aSGuanghui Cheng      val tval  = UInt(TvalWidth.W)
493ad9f3ddSchengguanghui    }
503ad9f3ddSchengguanghui    val groups = Vec(TraceGroupNum, ValidIO(new Bundle{
513ad9f3ddSchengguanghui      val iaddr     = UInt(IaddrWidth.W)
52*fd448a9dSchengguanghui      val ftqOffset = if (hasOffset)  Some(UInt(log2Up(PredictWidth).W)) else None
533ad9f3ddSchengguanghui      val itype     = UInt(ItypeWidth.W)
543ad9f3ddSchengguanghui      val iretire   = UInt(IretireWidthCompressed.W)
553ad9f3ddSchengguanghui      val ilastsize = UInt(IlastsizeWidth.W)
563ad9f3ddSchengguanghui    }))
5749162c9aSGuanghui Cheng  })
5849162c9aSGuanghui Cheng}
5949162c9aSGuanghui Cheng
6049162c9aSGuanghui Chengobject Itype extends NamedUInt(4) {
6149162c9aSGuanghui Cheng  def None                 = 0.U
6249162c9aSGuanghui Cheng  def Exception            = 1.U    //rob
6349162c9aSGuanghui Cheng  def Interrupt            = 2.U    //rob
6449162c9aSGuanghui Cheng  def ExpIntReturn         = 3.U    //rename
6549162c9aSGuanghui Cheng  def NonTaken             = 4.U    //commit
6649162c9aSGuanghui Cheng  def Taken                = 5.U    //commit
6749162c9aSGuanghui Cheng  def UninferableJump      = 6.U    //It's reserved when width of itype is 4.
6849162c9aSGuanghui Cheng  def reserved             = 7.U    //reserved
6949162c9aSGuanghui Cheng  def UninferableCall      = 8.U    //rename
7049162c9aSGuanghui Cheng  def InferableCall        = 9.U    //rename
7149162c9aSGuanghui Cheng  def UninferableTailCall  = 10.U   //rename
7249162c9aSGuanghui Cheng  def InferableTailCall    = 11.U   //rename
7349162c9aSGuanghui Cheng  def CoRoutineSwap        = 12.U   //rename
7449162c9aSGuanghui Cheng  def FunctionReturn       = 13.U   //rename
7549162c9aSGuanghui Cheng  def OtherUninferableJump = 14.U   //rename
7649162c9aSGuanghui Cheng  def OtherInferableJump   = 15.U   //rename
7749162c9aSGuanghui Cheng
78725e8ddcSchengguanghui  // Assuming the branchType is NonTaken here, it will be correctly modified after writeBack.
79725e8ddcSchengguanghui  def Branch = NonTaken
8049162c9aSGuanghui Cheng
8149162c9aSGuanghui Cheng  def jumpTypeGen(brType: UInt, rd: OpRegType, rs: OpRegType): UInt = {
8249162c9aSGuanghui Cheng
8349162c9aSGuanghui Cheng    val isEqualRdRs = rd === rs
8449162c9aSGuanghui Cheng    val isJal       = brType === BrType.jal
8549162c9aSGuanghui Cheng    val isJalr      = brType === BrType.jalr
8649162c9aSGuanghui Cheng    val isBranch    = brType === BrType.branch
8749162c9aSGuanghui Cheng
8849162c9aSGuanghui Cheng    // push to RAS when rd is link, pop from RAS when rs is link
8949162c9aSGuanghui Cheng    def isUninferableCall      = isJalr && rd.isLink && (!rs.isLink || rs.isLink && isEqualRdRs)  //8   push
9049162c9aSGuanghui Cheng    def isInferableCall        = isJal && rd.isLink                                               //9   push
9149162c9aSGuanghui Cheng    def isUninferableTailCall  = isJalr && rd.isX0 && !rs.isLink                                  //10  no op
9249162c9aSGuanghui Cheng    def isInferableTailCall    = isJal && rd.isX0                                                 //11  no op
9349162c9aSGuanghui Cheng    def isCoRoutineSwap        = isJalr && rd.isLink && rs.isLink && !isEqualRdRs                 //12  pop then push
9449162c9aSGuanghui Cheng    def isFunctionReturn       = isJalr && !rd.isLink && rs.isLink                                //13  pop
9549162c9aSGuanghui Cheng    def isOtherUninferableJump = isJalr && !rd.isLink && !rd.isX0 && !rs.isLink                   //14  no op
9649162c9aSGuanghui Cheng    def isOtherInferableJump   = isJal && !rd.isLink && !rd.isX0                                  //15  no op
9749162c9aSGuanghui Cheng
9849162c9aSGuanghui Cheng    val jumpType = Mux1H(
9949162c9aSGuanghui Cheng      Seq(
10049162c9aSGuanghui Cheng        isBranch,
10149162c9aSGuanghui Cheng        isUninferableCall,
10249162c9aSGuanghui Cheng        isInferableCall,
10349162c9aSGuanghui Cheng        isUninferableTailCall,
10449162c9aSGuanghui Cheng        isInferableTailCall,
10549162c9aSGuanghui Cheng        isCoRoutineSwap,
10649162c9aSGuanghui Cheng        isFunctionReturn,
10749162c9aSGuanghui Cheng        isOtherUninferableJump,
10849162c9aSGuanghui Cheng        isOtherInferableJump,
10949162c9aSGuanghui Cheng      ),
11049162c9aSGuanghui Cheng      Seq(
11149162c9aSGuanghui Cheng        Branch,
11249162c9aSGuanghui Cheng        UninferableCall,
11349162c9aSGuanghui Cheng        InferableCall,
11449162c9aSGuanghui Cheng        UninferableTailCall,
11549162c9aSGuanghui Cheng        InferableTailCall,
11649162c9aSGuanghui Cheng        CoRoutineSwap,
11749162c9aSGuanghui Cheng        FunctionReturn,
11849162c9aSGuanghui Cheng        OtherUninferableJump,
11949162c9aSGuanghui Cheng        OtherInferableJump,
12049162c9aSGuanghui Cheng      )
12149162c9aSGuanghui Cheng    )
12249162c9aSGuanghui Cheng
12349162c9aSGuanghui Cheng    Mux(isBranch || isJal || isJalr, jumpType, 0.U)
12449162c9aSGuanghui Cheng  }
12549162c9aSGuanghui Cheng
12649162c9aSGuanghui Cheng  def isTrap(itype: UInt) = Seq(Exception, Interrupt).map(_ === itype).reduce(_ || _)
12749162c9aSGuanghui Cheng
128c308d936Schengguanghui  def isTrapOrXret(itype: UInt) = Seq(Exception, Interrupt, ExpIntReturn).map(_ === itype).reduce(_ || _)
129c308d936Schengguanghui
13049162c9aSGuanghui Cheng  def isNotNone(itype: UInt) = itype =/= None
13149162c9aSGuanghui Cheng
13249162c9aSGuanghui Cheng  def isBranchType(itype: UInt) = itype === Branch
13349162c9aSGuanghui Cheng
13449162c9aSGuanghui Cheng  // supportSijump
13549162c9aSGuanghui Cheng  def isUninferable(itype: UInt) = Seq(UninferableCall, UninferableTailCall, CoRoutineSwap,
13649162c9aSGuanghui Cheng    UninferableTailCall, OtherUninferableJump).map(_ === itype).reduce(_ || _)
13749162c9aSGuanghui Cheng}
13849162c9aSGuanghui Cheng
13949162c9aSGuanghui Chengobject Ilastsize extends NamedUInt(1) {
14049162c9aSGuanghui Cheng  def HalfWord = 0.U
14149162c9aSGuanghui Cheng  def Word     = 1.U
14249162c9aSGuanghui Cheng}
14349162c9aSGuanghui Cheng
14449162c9aSGuanghui Chengobject Priv extends NamedUInt(3) {
14549162c9aSGuanghui Cheng  def HU = 0.U
14649162c9aSGuanghui Cheng  def HS = 1.U
14749162c9aSGuanghui Cheng  def M  = 3.U
14849162c9aSGuanghui Cheng  def D  = 4.U
14949162c9aSGuanghui Cheng  def VU = 5.U
15049162c9aSGuanghui Cheng  def VS = 6.U
15149162c9aSGuanghui Cheng}
15249162c9aSGuanghui Cheng
15349162c9aSGuanghui Chengclass OpRegType extends Bundle {
154725e8ddcSchengguanghui  val value = UInt(6.W)
15549162c9aSGuanghui Cheng  def isX0   = this.value === 0.U
15649162c9aSGuanghui Cheng  def isX1   = this.value === 1.U
15749162c9aSGuanghui Cheng  def isX5   = this.value === 5.U
158725e8ddcSchengguanghui  def isLink = Seq(isX1, isX5).reduce(_ || _)
15949162c9aSGuanghui Cheng}
160