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