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