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