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