xref: /XiangShan/src/main/scala/xiangshan/backend/trace/Interface.scala (revision c308d936f44c54b0ad91eb0e5a5257eec33d88a3)
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
10*c308d936Schengguanghuiclass TraceCSR(implicit val p: Parameters) extends Bundle with HasXSParameter {
114907ec88Schengguanghui  val cause = UInt(CauseWidth.W)
124907ec88Schengguanghui  val tval  = UInt(TvalWidth.W)
13*c308d936Schengguanghui  val lastPriv    = Priv()
14*c308d936Schengguanghui  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
3949162c9aSGuanghui Chengclass TraceCoreInterface(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 {
4549162c9aSGuanghui Cheng    val cause     = UInt(CauseWidth.W)
4649162c9aSGuanghui Cheng    val tval      = UInt(TvalWidth.W)
4749162c9aSGuanghui Cheng    val priv      = UInt(PrivWidth.W)
484907ec88Schengguanghui    val iaddr     = UInt((TraceGroupNum * IaddrWidth).W)
494907ec88Schengguanghui    val itype     = UInt((TraceGroupNum * ItypeWidth).W)
504907ec88Schengguanghui    val iretire   = UInt((TraceGroupNum * IretireWidthCompressed).W)
514907ec88Schengguanghui    val ilastsize = UInt((TraceGroupNum * IlastsizeWidth).W)
5249162c9aSGuanghui Cheng  })
5349162c9aSGuanghui Cheng}
5449162c9aSGuanghui Cheng
5549162c9aSGuanghui Chengobject Itype extends NamedUInt(4) {
5649162c9aSGuanghui Cheng  def None                 = 0.U
5749162c9aSGuanghui Cheng  def Exception            = 1.U    //rob
5849162c9aSGuanghui Cheng  def Interrupt            = 2.U    //rob
5949162c9aSGuanghui Cheng  def ExpIntReturn         = 3.U    //rename
6049162c9aSGuanghui Cheng  def NonTaken             = 4.U    //commit
6149162c9aSGuanghui Cheng  def Taken                = 5.U    //commit
6249162c9aSGuanghui Cheng  def UninferableJump      = 6.U    //It's reserved when width of itype is 4.
6349162c9aSGuanghui Cheng  def reserved             = 7.U    //reserved
6449162c9aSGuanghui Cheng  def UninferableCall      = 8.U    //rename
6549162c9aSGuanghui Cheng  def InferableCall        = 9.U    //rename
6649162c9aSGuanghui Cheng  def UninferableTailCall  = 10.U   //rename
6749162c9aSGuanghui Cheng  def InferableTailCall    = 11.U   //rename
6849162c9aSGuanghui Cheng  def CoRoutineSwap        = 12.U   //rename
6949162c9aSGuanghui Cheng  def FunctionReturn       = 13.U   //rename
7049162c9aSGuanghui Cheng  def OtherUninferableJump = 14.U   //rename
7149162c9aSGuanghui Cheng  def OtherInferableJump   = 15.U   //rename
7249162c9aSGuanghui Cheng
73725e8ddcSchengguanghui  // Assuming the branchType is NonTaken here, it will be correctly modified after writeBack.
74725e8ddcSchengguanghui  def Branch = NonTaken
7549162c9aSGuanghui Cheng
7649162c9aSGuanghui Cheng  def jumpTypeGen(brType: UInt, rd: OpRegType, rs: OpRegType): UInt = {
7749162c9aSGuanghui Cheng
7849162c9aSGuanghui Cheng    val isEqualRdRs = rd === rs
7949162c9aSGuanghui Cheng    val isJal       = brType === BrType.jal
8049162c9aSGuanghui Cheng    val isJalr      = brType === BrType.jalr
8149162c9aSGuanghui Cheng    val isBranch    = brType === BrType.branch
8249162c9aSGuanghui Cheng
8349162c9aSGuanghui Cheng    // push to RAS when rd is link, pop from RAS when rs is link
8449162c9aSGuanghui Cheng    def isUninferableCall      = isJalr && rd.isLink && (!rs.isLink || rs.isLink && isEqualRdRs)  //8   push
8549162c9aSGuanghui Cheng    def isInferableCall        = isJal && rd.isLink                                               //9   push
8649162c9aSGuanghui Cheng    def isUninferableTailCall  = isJalr && rd.isX0 && !rs.isLink                                  //10  no op
8749162c9aSGuanghui Cheng    def isInferableTailCall    = isJal && rd.isX0                                                 //11  no op
8849162c9aSGuanghui Cheng    def isCoRoutineSwap        = isJalr && rd.isLink && rs.isLink && !isEqualRdRs                 //12  pop then push
8949162c9aSGuanghui Cheng    def isFunctionReturn       = isJalr && !rd.isLink && rs.isLink                                //13  pop
9049162c9aSGuanghui Cheng    def isOtherUninferableJump = isJalr && !rd.isLink && !rd.isX0 && !rs.isLink                   //14  no op
9149162c9aSGuanghui Cheng    def isOtherInferableJump   = isJal && !rd.isLink && !rd.isX0                                  //15  no op
9249162c9aSGuanghui Cheng
9349162c9aSGuanghui Cheng    val jumpType = Mux1H(
9449162c9aSGuanghui Cheng      Seq(
9549162c9aSGuanghui Cheng        isBranch,
9649162c9aSGuanghui Cheng        isUninferableCall,
9749162c9aSGuanghui Cheng        isInferableCall,
9849162c9aSGuanghui Cheng        isUninferableTailCall,
9949162c9aSGuanghui Cheng        isInferableTailCall,
10049162c9aSGuanghui Cheng        isCoRoutineSwap,
10149162c9aSGuanghui Cheng        isFunctionReturn,
10249162c9aSGuanghui Cheng        isOtherUninferableJump,
10349162c9aSGuanghui Cheng        isOtherInferableJump,
10449162c9aSGuanghui Cheng      ),
10549162c9aSGuanghui Cheng      Seq(
10649162c9aSGuanghui Cheng        Branch,
10749162c9aSGuanghui Cheng        UninferableCall,
10849162c9aSGuanghui Cheng        InferableCall,
10949162c9aSGuanghui Cheng        UninferableTailCall,
11049162c9aSGuanghui Cheng        InferableTailCall,
11149162c9aSGuanghui Cheng        CoRoutineSwap,
11249162c9aSGuanghui Cheng        FunctionReturn,
11349162c9aSGuanghui Cheng        OtherUninferableJump,
11449162c9aSGuanghui Cheng        OtherInferableJump,
11549162c9aSGuanghui Cheng      )
11649162c9aSGuanghui Cheng    )
11749162c9aSGuanghui Cheng
11849162c9aSGuanghui Cheng    Mux(isBranch || isJal || isJalr, jumpType, 0.U)
11949162c9aSGuanghui Cheng  }
12049162c9aSGuanghui Cheng
12149162c9aSGuanghui Cheng  def isTrap(itype: UInt) = Seq(Exception, Interrupt).map(_ === itype).reduce(_ || _)
12249162c9aSGuanghui Cheng
123*c308d936Schengguanghui  def isTrapOrXret(itype: UInt) = Seq(Exception, Interrupt, ExpIntReturn).map(_ === itype).reduce(_ || _)
124*c308d936Schengguanghui
12549162c9aSGuanghui Cheng  def isNotNone(itype: UInt) = itype =/= None
12649162c9aSGuanghui Cheng
12749162c9aSGuanghui Cheng  def isBranchType(itype: UInt) = itype === Branch
12849162c9aSGuanghui Cheng
12949162c9aSGuanghui Cheng  // supportSijump
13049162c9aSGuanghui Cheng  def isUninferable(itype: UInt) = Seq(UninferableCall, UninferableTailCall, CoRoutineSwap,
13149162c9aSGuanghui Cheng    UninferableTailCall, OtherUninferableJump).map(_ === itype).reduce(_ || _)
13249162c9aSGuanghui Cheng}
13349162c9aSGuanghui Cheng
13449162c9aSGuanghui Chengobject Ilastsize extends NamedUInt(1) {
13549162c9aSGuanghui Cheng  def HalfWord = 0.U
13649162c9aSGuanghui Cheng  def Word     = 1.U
13749162c9aSGuanghui Cheng}
13849162c9aSGuanghui Cheng
13949162c9aSGuanghui Chengobject Priv extends NamedUInt(3) {
14049162c9aSGuanghui Cheng  def HU = 0.U
14149162c9aSGuanghui Cheng  def HS = 1.U
14249162c9aSGuanghui Cheng  def M  = 3.U
14349162c9aSGuanghui Cheng  def D  = 4.U
14449162c9aSGuanghui Cheng  def VU = 5.U
14549162c9aSGuanghui Cheng  def VS = 6.U
14649162c9aSGuanghui Cheng}
14749162c9aSGuanghui Cheng
14849162c9aSGuanghui Chengclass OpRegType extends Bundle {
149725e8ddcSchengguanghui  val value = UInt(6.W)
15049162c9aSGuanghui Cheng  def isX0   = this.value === 0.U
15149162c9aSGuanghui Cheng  def isX1   = this.value === 1.U
15249162c9aSGuanghui Cheng  def isX5   = this.value === 5.U
153725e8ddcSchengguanghui  def isLink = Seq(isX1, isX5).reduce(_ || _)
15449162c9aSGuanghui Cheng}
155