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