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 TraceTrap(implicit val p: Parameters) extends Bundle with HasXSParameter { 11 val cause = UInt(CauseWidth.W) 12 val tval = UInt(TvalWidth.W) 13 val priv = Priv() 14} 15 16class TracePipe(iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter { 17 val itype = Itype() 18 val iretire = UInt(iretireWidth.W) 19 val ilastsize = Ilastsize() 20} 21 22class TraceBlock(hasIaddr: Boolean, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter { 23 val iaddr = if (hasIaddr) Some(UInt(IaddrWidth.W)) else None 24 val ftqIdx = if (!hasIaddr) Some(new FtqPtr) else None 25 val ftqOffset = if (!hasIaddr) Some(UInt(log2Up(PredictWidth).W)) else None 26 val tracePipe = new TracePipe(iretireWidth) 27} 28 29class TraceBundle(hasIaddr: Boolean, blockSize: Int, iretireWidth: Int)(implicit val p: Parameters) extends Bundle with HasXSParameter { 30 val trap = Output(new TraceTrap) 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 isNotNone(itype: UInt) = itype =/= None 124 125 def isBranchType(itype: UInt) = itype === Branch 126 127 // supportSijump 128 def isUninferable(itype: UInt) = Seq(UninferableCall, UninferableTailCall, CoRoutineSwap, 129 UninferableTailCall, OtherUninferableJump).map(_ === itype).reduce(_ || _) 130} 131 132object Ilastsize extends NamedUInt(1) { 133 def HalfWord = 0.U 134 def Word = 1.U 135} 136 137object Priv extends NamedUInt(3) { 138 def HU = 0.U 139 def HS = 1.U 140 def M = 3.U 141 def D = 4.U 142 def VU = 5.U 143 def VS = 6.U 144} 145 146class OpRegType extends Bundle { 147 val value = UInt(6.W) 148 def isX0 = this.value === 0.U 149 def isX1 = this.value === 1.U 150 def isX5 = this.value === 5.U 151 def isLink = Seq(isX1, isX5).reduce(_ || _) 152} 153