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