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