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