1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util.Fill 5import xiangshan.backend.fu.NewCSR.CSRFunc._ 6 7import scala.language.implicitConversions 8 9abstract class CSRRWType { 10 val wfn: CSRWfnType 11 val rfn: CSRRfnType 12 val ref: Option[CSREnumType] = None 13 14 def isRO: Boolean = this.isInstanceOf[ROType] || this.isInstanceOf[RefROType] 15 16 def isRW: Boolean = this.isInstanceOf[RWType] || this.isInstanceOf[RefRWType] 17 18 def isWARL: Boolean = this.isInstanceOf[WARLType] || this.isInstanceOf[RefWARLType] 19 20 def isWLRL: Boolean = this.isInstanceOf[WLRLType] || this.isInstanceOf[RefWLRLType] 21 22 def isRef: Boolean = this.isInstanceOf[RefROType] || this.isInstanceOf[RefRWType] || this.isInstanceOf[RefWARLType] || 23 this.isInstanceOf[RefWLRLType] 24 25 override def toString: String = { 26 val typeString = this match { 27 case WARLType(_, _) => "WARL" 28 case ROType(_) => "RO" 29 case WLRLType(_, _) => "WLRL" 30 case RWType() => "RW" 31 } 32 typeString + (if (isRef) " Ref" else "") 33 } 34} 35 36case class WARLType( 37 override val wfn: CSRWfnType, 38 override val rfn: CSRRfnType = null, 39) extends CSRRWType 40 41case class ROType( 42 override val rfn: CSRRfnType = null, 43) extends CSRRWType { 44 override final val wfn: CSRWfnType = wNoEffect 45} 46 47case class WLRLType( 48 override val wfn: CSRWfnType, 49 override val rfn: CSRRfnType, 50) extends CSRRWType 51 52case class RWType() extends CSRRWType { 53 override final val wfn: CSRWfnType = wNoFilter 54 override final val rfn: CSRRfnType = null 55} 56 57trait CheckRef { self: CSRRWType => 58 require(ref.nonEmpty) 59} 60 61case class RefWARLType( 62 override val ref: Option[CSREnumType], 63 override val wfn: CSRWfnType, 64 override val rfn: CSRRfnType = null, 65) extends CSRRWType with CheckRef 66 67case class RefROType( 68 override val ref: Option[CSREnumType], 69 override val rfn: CSRRfnType = null, 70) extends CSRRWType with CheckRef { 71 override final val wfn: CSRWfnType = wNoEffect 72} 73 74case class RefWLRLType( 75 override val ref: Option[CSREnumType], 76 override val wfn: CSRWfnType, 77 override val rfn: CSRRfnType, 78) extends CSRRWType with CheckRef 79 80case class RefRWType( 81 override val ref: Option[CSREnumType], 82) extends CSRRWType with CheckRef { 83 override final val wfn: CSRWfnType = wNoFilter 84 override final val rfn: CSRRfnType = null 85} 86 87object CSRFunc { 88 type CSRWfnType = (UInt, UInt, Seq[Data]) => UInt 89 90 def wNoFilter: CSRWfnType = 91 (newV: UInt, oldV: UInt, _: Seq[Data]) => newV 92 93 def wNoEffectWhen(keepCond: UInt => Bool): CSRWfnType = 94 (newV: UInt, oldV: UInt, _: Seq[Data]) => { 95 Mux(keepCond(newV), oldV, newV) 96 } 97 98 def wNoEffect: CSRWfnType = 99 (_: UInt, oldV: UInt, _: Seq[Data]) => { oldV } 100 101 type CSRRfnType = (UInt, Seq[Data]) => UInt 102 103 def rNoFilter: CSRRfnType = null 104 105 def rWithFilter(rFilter: (UInt, Seq[Data]) => UInt): CSRRfnType = 106 (oriV: UInt, seq: Seq[Data]) => rFilter(oriV, seq) 107 108 def rFixValue(value: UInt): CSRRfnType = { 109 (_, _) => value 110 } 111} 112 113class CSREnumType( 114 val msb: Int, 115 val lsb: Int, 116)( 117 var rwType: CSRRWType, 118 var init: Data = null 119)( 120 override val factory: ChiselEnum 121) extends EnumType(factory) { 122 123 if (factory.all.isEmpty) { 124 factory.asInstanceOf[CSREnum].addMinValue 125 } 126 127 if (this.init != null && !factory.all.exists(_.litValue == this.init.litValue)) { 128 factory.asInstanceOf[CSREnum].addNewValue(init.asUInt) 129 } 130 131 if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) { 132 factory.asInstanceOf[CSREnum].addMaxValue 133 } 134 135 if (msb - lsb + 1 > this.getWidth) 136 println( 137 s"[CSRInfo] $this: " + 138 s"the setting range($msb, $lsb) of bitfield is widen than EnumType's width(${this.getWidth}), " + 139 s"the higher bits will be optimized" 140 ) 141 142 def isRef = this.rwType.isRef 143 144 def isRO = this.rwType.isRO 145 146 def isRW = this.rwType.isRW 147 148 def isWARL = this.rwType.isWARL 149 150 // Check if the write data is legal that can update the regfield. 151 // Also check if the write field is not Read Only. 152 def isLegal: Bool = this.factory.asInstanceOf[CSREnum].isLegal(this) && (!this.isRO).B 153 154 def isLegal(dmode: Bool): Bool = this.factory.asInstanceOf[CSREnum].isLegal(this, dmode) && (!this.isRO).B 155 156 // make the illegal wdata legalize 157 def legalize: CSREnumType = this.factory.asInstanceOf[CSREnum].legalize(this) 158 159 def legalize(dmode: Bool): CSREnumType = this.factory.asInstanceOf[CSREnum].legalize(this, dmode) 160 161 def needReset: Boolean = init != null 162 163 def rfn: CSRRfnType = rwType.rfn 164 165 def wfn: CSRWfnType = rwType.wfn 166 167 // Check if reset with a enum value in factory.all 168 protected def resetCheck[T <: EnumType](init: T): Unit = { 169 resetCheckRWType 170 require(this.factory.all.contains(init), 171 s""" 172 | The value ${init.litValue} is NOT in ${factory.all}. 173 | Please check if $init is the enum in the $factory") 174 """.stripMargin 175 ) 176 } 177 178 // Check if reset with a enum value in factory.all 179 protected def resetCheck(init: UInt): Unit = { 180 resetCheckRWType 181 require(this.factory.all.exists(_.litValue == init.litValue), 182 s""" 183 |The value ${init.litValue} is not in ${factory.all}. 184 |Please add reset value as the tail of (msb,lsb, HERE) or (bit, HERE), If you need reset field with the value NOT in enum set. 185 | ^ ^ 186 |""".stripMargin 187 ) 188 } 189 190 protected def resetCheckRWType: Unit = { 191 rwType match { 192 case ROType(rfn) => require(rfn == null) 193 case _ => 194 } 195 } 196 197 def withReset[T <: EnumType](init: T): this.type = { 198 resetCheck(init) 199 this.init = init 200 if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) { 201 factory.asInstanceOf[CSREnum].addMaxValue 202 } 203 this 204 } 205 206 def withReset(init: UInt): this.type = { 207 resetCheck(init) 208 this.init = this.factory(init) 209 if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) { 210 factory.asInstanceOf[CSREnum].addMaxValue 211 } 212 this 213 } 214 215 // Reset using the value not in factory.all 216 def withNonEnumReset(init: UInt): this.type = { 217 resetCheckRWType 218 if (!this.factory.all.exists(_.litValue == init.litValue)) { 219 this.factory.asInstanceOf[CSREnum].addNewValue(init) 220 println(s"[CSR-info] add reset value ${init.litValue} into $this") 221 } 222 if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) { 223 factory.asInstanceOf[CSREnum].addMaxValue 224 } 225 this 226 } 227 228 def := (that: UInt): Unit = { 229 this := this.factory(that) 230 } 231 232 def dumpName = { 233 s"${chisel3.reflect.DataMirror.queryNameGuess(this)} ${rwType} [$msb, $lsb] reset($init)" 234 } 235 236 def asBool: Bool = { 237 this.asUInt.asBool 238 } 239 240 private def setRwType(newType: CSRRWType): this.type = { 241 this.rwType = newType 242 this 243 } 244 245 def setRO(rfn: CSRRfnType = null): this.type = { 246 this.setRwType(ROType(rfn)) 247 } 248 249 def setRW(): this.type = { 250 this.setRwType(RWType()) 251 } 252 253 def setWARL(wfn: CSRWfnType): this.type = { 254 this.setRwType(WARLType(wfn)) 255 } 256 257 def ||(that: Bool): Bool = { 258 require(this.getWidth == 1, s"Only 1 bit field can use operator ||. The width of left operand is ${this.getWidth}") 259 this.asBool || that 260 } 261 262 def ||(that: CSREnumType): Bool = { 263 require(this.getWidth == 1, s"Only 1 bit field can use operator ||. The width of left operand is ${this.getWidth}") 264 require(that.getWidth == 1, s"Only 1 bit field can use operator ||. The width of right operand is ${that.getWidth}") 265 this.asBool || that.asBool 266 } 267 268 def &&(that: Bool): Bool = { 269 require(this.getWidth == 1, s"Only 1 bit field can use operator &&. The width of left operand is ${this.getWidth}") 270 this.asBool && that 271 } 272 273 def &&(that: CSREnumType): Bool = { 274 require(this.getWidth == 1, s"Only 1 bit field can use operator &&. The width of left operand is ${this.getWidth}") 275 require(that.getWidth == 1, s"Only 1 bit field can use operator &&. The width of right operand is ${that.getWidth}") 276 this.asBool && that.asBool 277 } 278 279 def unary_! : Bool = { 280 require(this.getWidth == 1, s"Only 1 bit field can use operator &&. The width of left operand is ${this.getWidth}") 281 !this.asBool 282 } 283 284 def & (that: UInt): UInt = { 285 require(this.getWidth == that.getWidth || !that.widthKnown) 286 this.asUInt & that 287 } 288 289 def &> (that: Bool): UInt = { 290 this.asUInt & Fill(this.getWidth, that) 291 } 292 293 def |> (that: Bool): UInt = { 294 this.asUInt | Fill(this.getWidth, that) 295 } 296 297 // override cloneType to make ValidIO etc function return CSREnumType not EnumType 298 override def cloneType: this.type = factory.asInstanceOf[CSREnum].makeType.asInstanceOf[this.type].setRwType(this.rwType) 299} 300 301class CSREnum extends ChiselEnum { 302 protected def apply(rwType: CSRRWType, init: Data = null)(msb: Int, lsb: Int)(factory: ChiselEnum): CSREnumType = { 303 this.msb = msb 304 this.lsb = lsb 305 new CSREnumType(msb, lsb)(rwType, init)(factory) 306 } 307 308 var msb, lsb: Int = 0 309 310 def makeType: CSREnumType = { 311 new CSREnumType(msb, lsb)(RWType())(this) 312 } 313 314 /** 315 * Used to allow 0.U.asTypeOf(CSREnumInstance) convertion 316 */ 317 def addMinValue: Unit = { 318 Value(0.U) 319 } 320 321 /** 322 * A trick to expand the width of Enum to (msb - lsb + 1) 323 */ 324 def addMaxValue: Unit = { 325 Value(((BigInt(1) << (msb - lsb + 1)) - 1).U) 326 } 327 328 /** 329 * 330 * @param value: A new value need to add in Enum set 331 * @return this 332 */ 333 def addNewValue(value: UInt): this.type = { 334 Value(value) 335 this 336 } 337 338 def isLegal(enum: CSREnumType): Bool = true.B 339 340 def isLegal(enum: CSREnumType, dmode: Bool): Bool = true.B 341 342 def legalize(enum: CSREnumType): CSREnumType = makeType 343 344 def legalize(enum: CSREnumType, dmode: Bool): CSREnumType = makeType 345 346 println(s"A new CSREnum is created, factory: $this") 347} 348 349trait RWApply { self: CSREnum => 350 def apply(msb: Int, lsb: Int): CSREnumType = self 351 .apply(RWType())(msb, lsb)(this) 352 353 def apply(bit: Int): CSREnumType = apply(bit, bit) 354} 355 356trait ROApply { self: CSREnum => 357 def apply(msb: Int, lsb: Int): CSREnumType = self 358 .apply(ROType())(msb, lsb)(this) 359} 360 361trait WARLApply { self: CSREnum => 362 def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 363 .apply(WARLType(wfn, rfn))(msb, lsb)(this) 364 365 def apply(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self 366 .apply(WARLType(wfn))(msb, lsb)(this) 367 368 def apply(bit: Int, wfn: CSRWfnType): CSREnumType = apply(bit, bit, wfn) 369} 370 371trait WLRLApply { self: CSREnum => 372 def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 373 .apply(WLRLType(wfn, rfn))(msb, lsb)(this) 374} 375 376trait CSRMacroApply { self: CSREnum => 377 def RO(msb: Int, lsb: Int, rfn: CSRRfnType, resetVal: Data = null): CSREnumType = self 378 .apply(ROType(rfn), resetVal)(msb, lsb)(this) 379 380 def RO(msb: Int, lsb: Int): CSREnumType = self 381 .apply(ROType())(msb, lsb)(this) 382 383 def RW(msb: Int, lsb: Int, resetVal: Data = null): CSREnumType = self 384 .apply(RWType(), resetVal)(msb, lsb)(this) 385 386 def WARL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 387 .apply(WARLType(wfn, rfn))(msb, lsb)(this) 388 389 def WARL(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self 390 .apply(WARLType(wfn))(msb, lsb)(this) 391 392 def WLRL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 393 .apply(WLRLType(wfn, rfn))(msb, lsb)(this) 394 395 def RefRO(ref: CSREnumType, msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self 396 .apply(RefROType(Some(ref) ,rfn))(msb, lsb)(ref.factory) 397 398 def RefRO(ref: CSREnumType, msb: Int, lsb: Int): CSREnumType = self 399 .apply(RefROType(Some(ref)))(msb, lsb)(ref.factory) 400 401 def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 402 .apply(RefWARLType(Some(ref), wfn, rfn))(msb, lsb)(ref.factory) 403 404 def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self 405 .apply(RefWARLType(Some(ref), wfn))(msb, lsb)(ref.factory) 406} 407 408object CSREnumTypeImplicitCast { 409 class BoolField(val value: Bool) { 410 def && (field: CSREnumType): Bool = { 411 this.value && field.asBool 412 } 413 414 def || (field: CSREnumType): Bool = { 415 this.value || field.asBool 416 } 417 418 def &<(that: UInt): UInt = { 419 require(that.widthKnown, "The width of the right operand should be known when using &< operator") 420 Fill(that.getWidth, this.value) & that 421 } 422 423 def &<(that: CSREnumType): UInt = { 424 this &< that.asUInt 425 } 426 427 def |<(that: UInt): UInt = { 428 require(that.widthKnown, "The width of the right operand should be known when using |< operator") 429 Fill(that.getWidth, this.value) | that 430 } 431 432 def |<(that: CSREnumType): UInt = { 433 this |< that.asUInt 434 } 435 } 436 437 implicit def BoolToBoolField(bool: Bool): BoolField = new BoolField(bool) 438} 439 440