1f7af4c74Schengguanghuipackage xiangshan.backend.fu.util 2f7af4c74Schengguanghui 3f7af4c74Schengguanghuiimport chisel3._ 4f7af4c74Schengguanghuiimport chisel3.util._ 547e7896cSchengguanghuiimport xiangshan.{XSBundle, HasXSParameter} 6f7af4c74Schengguanghuiimport org.chipsalliance.cde.config.Parameters 7f7af4c74Schengguanghuiimport utils.ConsecutiveOnes 8f7af4c74Schengguanghui 947e7896cSchengguanghuitrait SdtrigExt extends HasXSParameter{ 10f7af4c74Schengguanghui implicit val p: Parameters 11f7af4c74Schengguanghui class TDataRegs extends XSBundle { 12f7af4c74Schengguanghui val tdata1 = UInt(XLEN.W) 13f7af4c74Schengguanghui val tdata2 = UInt(XLEN.W) 14f7af4c74Schengguanghui } 15f7af4c74Schengguanghui object TDataRegs extends TDataRegs { 16f7af4c74Schengguanghui def apply() = new TDataRegs 17f7af4c74Schengguanghui } 18f7af4c74Schengguanghui 19f7af4c74Schengguanghui class Tdata1Bundle extends XSBundle { 20f7af4c74Schengguanghui val type_ = TrigTypeEnum() // [XLEN-1: XLEN-4] 21f7af4c74Schengguanghui val dmode = Bool() // [XLEN-5] 22f7af4c74Schengguanghui val data = new Tdata1Data // [XLEN-6, 0] 23f7af4c74Schengguanghui require(this.getWidth == XLEN) 24f7af4c74Schengguanghui def getTriggerAction : TrigActionEnum = { 25f7af4c74Schengguanghui this.data.asTypeOf(new MControlData).action 26f7af4c74Schengguanghui } 27f7af4c74Schengguanghui def getTriggerChain: Bool = { 28f7af4c74Schengguanghui this.data.asTypeOf(new MControlData).chain 29f7af4c74Schengguanghui } 30f7af4c74Schengguanghui def getTiming: Bool = { 31f7af4c74Schengguanghui this.data.asTypeOf(new MControlData).timing 32f7af4c74Schengguanghui } 33f7af4c74Schengguanghui } 34f7af4c74Schengguanghui object Tdata1Bundle extends Tdata1Bundle { 35f7af4c74Schengguanghui def apply(): Tdata1Bundle = new Tdata1Bundle 36f7af4c74Schengguanghui def Read(rdata: UInt) : UInt = rdata 37f7af4c74Schengguanghui def Write(wdata: UInt, tdata1: UInt, chainable: Bool, debug_mode: Bool) : UInt = { 38f7af4c74Schengguanghui val tdata1_old = WireInit(tdata1.asTypeOf(new Tdata1Bundle)) 39f7af4c74Schengguanghui val tdata1_new = Wire(new Tdata1Bundle) 40f7af4c74Schengguanghui val wdata_new = WireInit(wdata.asTypeOf(new Tdata1Bundle)) 41f7af4c74Schengguanghui tdata1_new.type_ := wdata_new.type_.legalize 42f7af4c74Schengguanghui tdata1_new.dmode := wdata_new.dmode && debug_mode // dmode only support write in debug mode 43f7af4c74Schengguanghui when (wdata_new.type_.asUInt === TrigTypeEnum.MCONTROL) { 44f7af4c74Schengguanghui tdata1_new.data.value := MControlData.Write(wdata_new.asUInt, tdata1_old.data.asUInt, chainable) 45f7af4c74Schengguanghui }.otherwise { 46f7af4c74Schengguanghui tdata1_new.data.value := 0.U 47f7af4c74Schengguanghui } 48f7af4c74Schengguanghui tdata1_new.asUInt 49f7af4c74Schengguanghui } 50f7af4c74Schengguanghui def default : UInt = { 51f7af4c74Schengguanghui (TrigTypeEnum.disabled.litValue << (XLEN - 4)).U 52f7af4c74Schengguanghui } 53f7af4c74Schengguanghui } 54f7af4c74Schengguanghui 55f7af4c74Schengguanghui class TrigTypeEnum extends Bundle { 56f7af4c74Schengguanghui val value = UInt(4.W) 57f7af4c74Schengguanghui def NONE = 0.U 58f7af4c74Schengguanghui def LEGACY = 1.U 59f7af4c74Schengguanghui def MCONTROL = 2.U 60f7af4c74Schengguanghui def ICOUNT = 3.U 61f7af4c74Schengguanghui def ITRIGGER = 4.U 62f7af4c74Schengguanghui def ETRIGGER = 5.U 63f7af4c74Schengguanghui def MCONTROL6 = 6.U 64f7af4c74Schengguanghui def TMEXTTRIGGER = 7.U 65f7af4c74Schengguanghui def disabled = 15.U 66f7af4c74Schengguanghui /** 67f7af4c74Schengguanghui * XS supports part of trigger type of Sdtrig extension 68f7af4c74Schengguanghui * @param data trigger type checked 69f7af4c74Schengguanghui * @return true.B, If XS support this trigger type 70f7af4c74Schengguanghui */ 71f7af4c74Schengguanghui def isLegal : Bool = { 72f7af4c74Schengguanghui this.asUInt === this.MCONTROL 73f7af4c74Schengguanghui } 74f7af4c74Schengguanghui def legalize : TrigTypeEnum = { 75f7af4c74Schengguanghui Mux(this.isLegal, this.asUInt, this.disabled).asTypeOf(new TrigTypeEnum) 76f7af4c74Schengguanghui } 77f7af4c74Schengguanghui } 78f7af4c74Schengguanghui object TrigTypeEnum extends TrigTypeEnum { 79f7af4c74Schengguanghui def apply() = new TrigTypeEnum 80f7af4c74Schengguanghui } 81f7af4c74Schengguanghui 82f7af4c74Schengguanghui protected class Tdata1Data extends XSBundle { 83f7af4c74Schengguanghui val value = UInt((XLEN-5).W) 84f7af4c74Schengguanghui } 85f7af4c74Schengguanghui 86f7af4c74Schengguanghui class MControlData extends Tdata1Data { 87f7af4c74Schengguanghui override val value = null 88f7af4c74Schengguanghui val maskmax = UInt(6.W) // [XLEN-6: XLEN-11] 89f7af4c74Schengguanghui val zero1 = if (XLEN==64) UInt(30.W) else null // [XLEN-12: 23] 90f7af4c74Schengguanghui val sizehi = if (XLEN==64) UInt(2.W) else null // [22:21] 91f7af4c74Schengguanghui val hit = Bool() // [20] 92f7af4c74Schengguanghui val select = Bool() // [19] 93f7af4c74Schengguanghui val timing = Bool() // [18] 94f7af4c74Schengguanghui val sizelo = UInt(2.W) // [17:16] 95f7af4c74Schengguanghui val action = TrigActionEnum() // [15:12] 96f7af4c74Schengguanghui val chain = Bool() // [11] 97f7af4c74Schengguanghui val match_ = TrigMatchEnum() // [10:7] 98f7af4c74Schengguanghui val m = Bool() // [6] 99f7af4c74Schengguanghui val zero2 = Bool() // [5] 100f7af4c74Schengguanghui val s = Bool() // [4] 101f7af4c74Schengguanghui val u = Bool() // [3] 102f7af4c74Schengguanghui val execute = Bool() // [2] 103f7af4c74Schengguanghui val store = Bool() // [1] 104f7af4c74Schengguanghui val load = Bool() // [0] 105f7af4c74Schengguanghui require(this.getWidth == (new Tdata1Data).getWidth) 106f7af4c74Schengguanghui 107f7af4c74Schengguanghui def isFetchTrigger: Bool = this.execute 108f7af4c74Schengguanghui def isMemAccTrigger: Bool = this.store || this.load 109f7af4c74Schengguanghui } 110f7af4c74Schengguanghui object MControlData { 111f7af4c74Schengguanghui def Read(rdata: UInt) : UInt = rdata 112f7af4c74Schengguanghui def Write(wdata: UInt, tdata1data: UInt, chainable: Bool) : UInt = { 113f7af4c74Schengguanghui val mcontrol_old = WireInit(tdata1data.asTypeOf(new MControlData)) 114f7af4c74Schengguanghui val tdata1_new = WireInit(wdata.asTypeOf(new Tdata1Bundle)) 115f7af4c74Schengguanghui val mcontrol_new = WireInit(tdata1_new.data.asTypeOf(new MControlData)) 116f7af4c74Schengguanghui val wdata_new = WireInit(wdata.asTypeOf(new MControlData)) 117f7af4c74Schengguanghui mcontrol_new.maskmax := 0.U 118f7af4c74Schengguanghui mcontrol_new.zero1 := 0.U 119f7af4c74Schengguanghui mcontrol_new.sizehi := 0.U 120f7af4c74Schengguanghui mcontrol_new.hit := false.B 121f7af4c74Schengguanghui mcontrol_new.select := wdata_new.execute && wdata_new.select // not support rdata/wdata trigger 122f7af4c74Schengguanghui mcontrol_new.timing := false.B // only support trigger fires before its execution 123f7af4c74Schengguanghui mcontrol_new.sizelo := 0.U 124f7af4c74Schengguanghui mcontrol_new.action := wdata_new.action.legalize(tdata1_new.dmode) 125f7af4c74Schengguanghui mcontrol_new.chain := chainable && wdata_new.chain 126f7af4c74Schengguanghui mcontrol_new.match_ := wdata_new.match_.legalize 127f7af4c74Schengguanghui mcontrol_new.zero2 := 0.U 128f7af4c74Schengguanghui mcontrol_new.asUInt 129f7af4c74Schengguanghui } 130f7af4c74Schengguanghui } 131f7af4c74Schengguanghui 132f7af4c74Schengguanghui class TrigActionEnum extends Bundle { 133f7af4c74Schengguanghui val value = UInt(4.W) 134f7af4c74Schengguanghui def BKPT_EXCPT = 0.U // raise breakpoint exception 135f7af4c74Schengguanghui def DEBUG_MODE = 1.U // enter debug mode 136f7af4c74Schengguanghui def TRACE_ON = 2.U 137f7af4c74Schengguanghui def TRACE_OFF = 3.U 138f7af4c74Schengguanghui def TRACE_NOTIFY= 4.U 139f7af4c74Schengguanghui def default = this.BKPT_EXCPT 140f7af4c74Schengguanghui /** 141f7af4c74Schengguanghui * XS supports part of trigger action type of Sdtrig extension 142f7af4c74Schengguanghui * @param data action checked 143f7af4c74Schengguanghui * @return true.B, If XS support such trigger action type 144f7af4c74Schengguanghui */ 145f7af4c74Schengguanghui def isLegal(dmode: Bool) : Bool = { 146f7af4c74Schengguanghui this.asUInt === this.BKPT_EXCPT || this.asUInt === this.DEBUG_MODE && dmode 147f7af4c74Schengguanghui } 148f7af4c74Schengguanghui def legalize(dmode: Bool) : TrigActionEnum = { 149f7af4c74Schengguanghui Mux(this.isLegal(dmode), this.asUInt, this.default).asTypeOf(new TrigActionEnum) 150f7af4c74Schengguanghui } 151f7af4c74Schengguanghui } 152f7af4c74Schengguanghui object TrigActionEnum extends TrigActionEnum { 153f7af4c74Schengguanghui def apply() = new TrigActionEnum 154f7af4c74Schengguanghui } 155f7af4c74Schengguanghui 156f7af4c74Schengguanghui class TrigMatchEnum extends Bundle { 157f7af4c74Schengguanghui val value = UInt(4.W) 158f7af4c74Schengguanghui private def not_bit = 8.U 159f7af4c74Schengguanghui def EQ = 0.U 160f7af4c74Schengguanghui def NAPOT = 1.U 161f7af4c74Schengguanghui def GE = 2.U 162f7af4c74Schengguanghui def LT = 3.U 163f7af4c74Schengguanghui def MASK_LO = 4.U 164f7af4c74Schengguanghui def MASK_HI = 5.U 165f7af4c74Schengguanghui def NE = EQ | this.not_bit // not eq 166f7af4c74Schengguanghui def NNAPOT = NAPOT | this.not_bit // not napot 167f7af4c74Schengguanghui def NMASK_LO = MASK_LO | this.not_bit // not mask low 168f7af4c74Schengguanghui def NMASK_HI = MASK_HI | this.not_bit // not mask high 169f7af4c74Schengguanghui def default = this.EQ 170f7af4c74Schengguanghui def isRVSpecLegal : Bool = { 171f7af4c74Schengguanghui this.asUInt === this.EQ || this.asUInt === this.NAPOT || 172f7af4c74Schengguanghui this.asUInt === this.GE || this.asUInt === this.LT || 173f7af4c74Schengguanghui this.asUInt === this.MASK_LO || this.asUInt === this.MASK_HI || 174f7af4c74Schengguanghui this.asUInt === this.NE || this.asUInt === this.NNAPOT || 175f7af4c74Schengguanghui this.asUInt === this.NMASK_LO || this.asUInt === this.NMASK_HI 176f7af4c74Schengguanghui } 177f7af4c74Schengguanghui 178f7af4c74Schengguanghui /** 179f7af4c74Schengguanghui * XS supports part of trigger match type of Sdtrig extension 180f7af4c74Schengguanghui * @param data match type checked 181f7af4c74Schengguanghui * @return true.B, If XS support such trigger match type 182f7af4c74Schengguanghui */ 183f7af4c74Schengguanghui def isLegal : Bool = { 184f7af4c74Schengguanghui this.asUInt === this.EQ || this.asUInt === this.GE || this.asUInt === this.LT 185f7af4c74Schengguanghui } 186f7af4c74Schengguanghui def legalize : TrigMatchEnum = { 187f7af4c74Schengguanghui Mux(this.isLegal, this.asUInt, this.default).asTypeOf(new TrigMatchEnum) 188f7af4c74Schengguanghui } 189f7af4c74Schengguanghui } 190f7af4c74Schengguanghui object TrigMatchEnum extends TrigMatchEnum { 191f7af4c74Schengguanghui def apply() = new TrigMatchEnum 192f7af4c74Schengguanghui } 193f7af4c74Schengguanghui 194f7af4c74Schengguanghui /** 195f7af4c74Schengguanghui * Check if triggers can fire 196f7af4c74Schengguanghui * @param triggerNum 197f7af4c74Schengguanghui * @param canFireVec 198f7af4c74Schengguanghui * @param hitVec 199f7af4c74Schengguanghui * @param timingVec 200f7af4c74Schengguanghui * @param chainVec 201f7af4c74Schengguanghui */ 202f7af4c74Schengguanghui def TriggerCheckCanFire(triggerNum: Int, canFireVec: Vec[Bool], hitVec: Vec[Bool], timingVec: Vec[Bool], chainVec: Vec[Bool]): Unit = { 203f7af4c74Schengguanghui val trigger2ChainVec = WireInit(VecInit(Seq.fill(triggerNum)(false.B))) 204f7af4c74Schengguanghui val trigger2TimingSameVec = WireInit(VecInit(Seq.fill(triggerNum)(true.B))) 205f7af4c74Schengguanghui val trigger2TimingOkVec = WireInit(VecInit(Seq.fill(triggerNum)(true.B))) 206f7af4c74Schengguanghui val trigger2ChainOkVec = WireInit(VecInit(Seq.fill(triggerNum)(true.B))) 207f7af4c74Schengguanghui for (i <- 1 until triggerNum) { // the 0th trigger always chain ok 208f7af4c74Schengguanghui trigger2ChainOkVec(i) := chainVec(i - 1) && hitVec(i - 1) || !chainVec(i - 1) 209f7af4c74Schengguanghui } 210f7af4c74Schengguanghui 211f7af4c74Schengguanghui for (i <- 1 until triggerNum) { // the 0th trigger always timing same, not chain, timing ok 212f7af4c74Schengguanghui trigger2TimingSameVec(i) := timingVec(i - 1) === timingVec(i) 213f7af4c74Schengguanghui trigger2ChainVec(i) := chainVec(i - 1) && !chainVec(i) 214f7af4c74Schengguanghui trigger2TimingOkVec(i) := trigger2ChainVec(i) && trigger2TimingSameVec(i) || !chainVec(i - 1) 215f7af4c74Schengguanghui } 216f7af4c74Schengguanghui canFireVec.zipWithIndex.foreach { 217f7af4c74Schengguanghui case (canFire, i) => canFire := trigger2ChainOkVec(i) && trigger2TimingOkVec(i) && hitVec(i) && !chainVec(i) 218f7af4c74Schengguanghui } 219f7af4c74Schengguanghui } 220f7af4c74Schengguanghui 221f7af4c74Schengguanghui /** 222f7af4c74Schengguanghui * Check if chain vector is legal 223f7af4c74Schengguanghui * @param chainVec 224f7af4c74Schengguanghui * @param chainLen 225f7af4c74Schengguanghui * @return true.B if the max length of chain don't exceed the permitted length 226f7af4c74Schengguanghui */ 227f7af4c74Schengguanghui def TriggerCheckChainLegal(chainVec: Seq[Bool], chainLen: Int): Bool = { 228f7af4c74Schengguanghui !ConsecutiveOnes(chainVec, chainLen) 229f7af4c74Schengguanghui } 230f7af4c74Schengguanghui 231f7af4c74Schengguanghui /** 232f7af4c74Schengguanghui * Compare data with trigger data 233f7af4c74Schengguanghui * @param data data compared 234f7af4c74Schengguanghui * @param tdata data from trigger 235f7af4c74Schengguanghui * @param matchType trigger match type in UInt 236f7af4c74Schengguanghui * @param enable if the trigger is enabled 237f7af4c74Schengguanghui * @return true.B if data meet the trigger match condition 238f7af4c74Schengguanghui */ 239f7af4c74Schengguanghui def TriggerCmp(data: UInt, tdata: UInt, matchType: UInt, enable: Bool): Bool = { 24047e7896cSchengguanghui val eq = data(VAddrBits - 1, 0) === tdata(VAddrBits - 1, 0) 24147e7896cSchengguanghui val ge = data(VAddrBits - 1, 0) >= tdata(VAddrBits - 1, 0) 24247e7896cSchengguanghui val lt = data(VAddrBits - 1, 0) < tdata(VAddrBits - 1, 0) 24367d06f87SXuan Hu val res = MuxLookup(matchType, false.B)(Seq( 244f7af4c74Schengguanghui TrigMatchEnum.EQ -> eq, 245f7af4c74Schengguanghui TrigMatchEnum.GE -> ge, 246f7af4c74Schengguanghui TrigMatchEnum.LT -> lt 247f7af4c74Schengguanghui )) 248f7af4c74Schengguanghui res && enable 249f7af4c74Schengguanghui } 25047e7896cSchengguanghui 25147e7896cSchengguanghui /** 25247e7896cSchengguanghui * author @Guokai Chen 25347e7896cSchengguanghui * compare between Consecutive pc and tdada2 25447e7896cSchengguanghui */ 255a7a6d0a6Schengguanghui def TriggerCmpConsecutive(pcVec: Vec[UInt], tdata: UInt, matchType: UInt, enable: Bool) : Vec[Bool] = { 25647e7896cSchengguanghui // opt: only compare two possible high bits: orig and orig+1 257a7a6d0a6Schengguanghui val pcVecWidth = pcVec.length 258a7a6d0a6Schengguanghui // also take care of that triggerMatch is less 259a7a6d0a6Schengguanghui val highPos = log2Up(pcVecWidth) + 1 260a7a6d0a6Schengguanghui 261a7a6d0a6Schengguanghui val lowPCVec = Wire(Vec(pcVecWidth, UInt(highPos.W))) 262a7a6d0a6Schengguanghui lowPCVec.zipWithIndex.map{case (h, i) => h := pcVec(i)(highPos - 1, 0)} 263a7a6d0a6Schengguanghui val highPC = pcVec(0)(VAddrBits - 1, highPos) 264a7a6d0a6Schengguanghui val highPC1 = pcVec(0)(VAddrBits - 1, highPos) + 1.U 265a7a6d0a6Schengguanghui 266a7a6d0a6Schengguanghui val lowTdata = tdata(highPos - 1, 0) 26747e7896cSchengguanghui val highTdata = tdata(VAddrBits - 1, highPos) 26847e7896cSchengguanghui 26947e7896cSchengguanghui val highPCEqual = highPC === highTdata 27047e7896cSchengguanghui val highPC1Equal = highPC1 === highTdata 271a7a6d0a6Schengguanghui val highPCGreater = highPC > highTdata 272a7a6d0a6Schengguanghui val highPC1Greater = highPC1 > highTdata 273a7a6d0a6Schengguanghui val highPCLess = highPC < highTdata 274a7a6d0a6Schengguanghui val highPC1Less = highPC1 < highTdata 27547e7896cSchengguanghui 276a7a6d0a6Schengguanghui val carry = Wire(Vec(pcVecWidth, Bool())) 277a7a6d0a6Schengguanghui carry.zipWithIndex.map{case (c, i) => c := pcVec(i)(highPos) =/= pcVec(0)(highPos)} 27847e7896cSchengguanghui 279a7a6d0a6Schengguanghui val lowPCEqual = Wire(Vec(pcVecWidth, Bool())) 280a7a6d0a6Schengguanghui val lowPCGreater = Wire(Vec(pcVecWidth, Bool())) 281a7a6d0a6Schengguanghui val lowPCLess = Wire(Vec(pcVecWidth, Bool())) 28247e7896cSchengguanghui 283a7a6d0a6Schengguanghui lowPCEqual.zipWithIndex.map{case (l, i) => l := lowPCVec(i) === lowTdata } 284a7a6d0a6Schengguanghui lowPCGreater.zipWithIndex.map{case (l, i) => l := lowPCVec(i) >= lowTdata } 285a7a6d0a6Schengguanghui lowPCLess.zipWithIndex.map{case (l, i) => l := lowPCVec(i) < lowTdata } 28647e7896cSchengguanghui 287a7a6d0a6Schengguanghui val overallEqual = Wire(Vec(pcVecWidth, Bool())) 288a7a6d0a6Schengguanghui val overallGreater = Wire(Vec(pcVecWidth, Bool())) 289a7a6d0a6Schengguanghui val overallLess = Wire(Vec(pcVecWidth, Bool())) 29047e7896cSchengguanghui 291a7a6d0a6Schengguanghui overallEqual.zipWithIndex.map{case (o, i) => o := 292*db3923feSGuanghui Cheng !carry(i) && highPCEqual && lowPCEqual(i) || 293a7a6d0a6Schengguanghui carry(i) && highPC1Equal && lowPCEqual(i) 294a7a6d0a6Schengguanghui } 29547e7896cSchengguanghui 296a7a6d0a6Schengguanghui // [left : greater 1. nonCarry 2. carry 297a7a6d0a6Schengguanghui overallGreater.zipWithIndex.map { case (o, i) => o := 298*db3923feSGuanghui Cheng !carry(i) && (highPCGreater || highPCEqual && (lowPCEqual(i) || lowPCGreater(i))) || 299*db3923feSGuanghui Cheng carry(i) && (highPC1Greater || highPC1Equal && (lowPCEqual(i) || lowPCGreater(i))) 300a7a6d0a6Schengguanghui } 30147e7896cSchengguanghui 302*db3923feSGuanghui Cheng // right) : less 1. nonCarry 2. carry 303a7a6d0a6Schengguanghui overallLess.zipWithIndex.map { case (o, i) => o := 304*db3923feSGuanghui Cheng !carry(i) && (highPCLess || highPCEqual && lowPCLess(i)) || 305*db3923feSGuanghui Cheng carry(i) && (highPC1Less || highPC1Equal && lowPCLess(i)) 306a7a6d0a6Schengguanghui } 30747e7896cSchengguanghui 308a7a6d0a6Schengguanghui val ret = Wire(Vec(pcVecWidth, Bool())) 30947e7896cSchengguanghui ret.zipWithIndex.map{case (r, i) => r := MuxLookup(matchType, false.B)( 310e3da8badSTang Haojin Seq( 31147e7896cSchengguanghui TrigMatchEnum.EQ -> overallEqual(i), 31247e7896cSchengguanghui TrigMatchEnum.GE -> overallGreater(i), 31347e7896cSchengguanghui TrigMatchEnum.LT -> overallLess(i))) && enable} 31447e7896cSchengguanghui ret 31547e7896cSchengguanghui } 316f7af4c74Schengguanghui} 317