xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRFields.scala (revision cb36ac0f37d64c496ebf443ea86082c516f12938)
1039cdc35SXuan Hupackage xiangshan.backend.fu.NewCSR
2039cdc35SXuan Hu
3039cdc35SXuan Huimport chisel3._
41d192ad8SXuan Huimport chisel3.util.Fill
5039cdc35SXuan Huimport xiangshan.backend.fu.NewCSR.CSRFunc._
6*cb36ac0fSXuan Huimport scala.collection.mutable
7039cdc35SXuan Hu
81d192ad8SXuan Huimport scala.language.implicitConversions
91d192ad8SXuan Hu
10039cdc35SXuan Huabstract class CSRRWType {
11039cdc35SXuan Hu  val wfn: CSRWfnType
12946f0090SXuan Hu  var rfn: CSRRfnType
13039cdc35SXuan Hu  val ref: Option[CSREnumType] = None
14039cdc35SXuan Hu
15039cdc35SXuan Hu  def isRO: Boolean = this.isInstanceOf[ROType] || this.isInstanceOf[RefROType]
16039cdc35SXuan Hu
17039cdc35SXuan Hu  def isRW: Boolean = this.isInstanceOf[RWType] || this.isInstanceOf[RefRWType]
18039cdc35SXuan Hu
19039cdc35SXuan Hu  def isWARL: Boolean = this.isInstanceOf[WARLType] || this.isInstanceOf[RefWARLType]
20039cdc35SXuan Hu
21039cdc35SXuan Hu  def isWLRL: Boolean = this.isInstanceOf[WLRLType] || this.isInstanceOf[RefWLRLType]
22039cdc35SXuan Hu
23039cdc35SXuan Hu  def isRef: Boolean = this.isInstanceOf[RefROType] || this.isInstanceOf[RefRWType] || this.isInstanceOf[RefWARLType] ||
24039cdc35SXuan Hu    this.isInstanceOf[RefWLRLType]
25039cdc35SXuan Hu
26039cdc35SXuan Hu  override def toString: String = {
27039cdc35SXuan Hu    val typeString = this match {
28039cdc35SXuan Hu      case WARLType(_, _) => "WARL"
29039cdc35SXuan Hu      case ROType(_)      => "RO"
30039cdc35SXuan Hu      case WLRLType(_, _) => "WLRL"
31039cdc35SXuan Hu      case RWType()       => "RW"
32039cdc35SXuan Hu    }
33039cdc35SXuan Hu    typeString + (if (isRef) " Ref" else "")
34039cdc35SXuan Hu  }
35039cdc35SXuan Hu}
36039cdc35SXuan Hu
37039cdc35SXuan Hucase class WARLType(
38039cdc35SXuan Hu  override val wfn: CSRWfnType,
39946f0090SXuan Hu  override var rfn: CSRRfnType = null,
40039cdc35SXuan Hu) extends CSRRWType
41039cdc35SXuan Hu
42039cdc35SXuan Hucase class ROType(
43946f0090SXuan Hu  override var rfn: CSRRfnType = null,
44039cdc35SXuan Hu) extends CSRRWType {
45039cdc35SXuan Hu  override final val wfn: CSRWfnType = wNoEffect
46946f0090SXuan Hu  var isHardWired = false
47946f0090SXuan Hu  var hardWiredValue = 0.U
48946f0090SXuan Hu
49946f0090SXuan Hu  def setHardWired(value: UInt): Unit = {
50946f0090SXuan Hu    this.isHardWired = true
51946f0090SXuan Hu    this.hardWiredValue = value
52946f0090SXuan Hu  }
53039cdc35SXuan Hu}
54039cdc35SXuan Hu
55039cdc35SXuan Hucase class WLRLType(
56039cdc35SXuan Hu  override val wfn: CSRWfnType,
57946f0090SXuan Hu  override var rfn: CSRRfnType,
58039cdc35SXuan Hu) extends CSRRWType
59039cdc35SXuan Hu
60039cdc35SXuan Hucase class RWType() extends CSRRWType {
61039cdc35SXuan Hu  override final val wfn: CSRWfnType = wNoFilter
62946f0090SXuan Hu  override final var rfn: CSRRfnType = null
63039cdc35SXuan Hu}
64039cdc35SXuan Hu
65039cdc35SXuan Hutrait CheckRef { self: CSRRWType =>
66039cdc35SXuan Hu  require(ref.nonEmpty)
67039cdc35SXuan Hu}
68039cdc35SXuan Hu
69039cdc35SXuan Hucase class RefWARLType(
70039cdc35SXuan Hu  override val ref: Option[CSREnumType],
71039cdc35SXuan Hu  override val wfn: CSRWfnType,
72946f0090SXuan Hu  override var rfn: CSRRfnType = null,
73039cdc35SXuan Hu) extends CSRRWType with CheckRef
74039cdc35SXuan Hu
75039cdc35SXuan Hucase class RefROType(
76039cdc35SXuan Hu  override val ref: Option[CSREnumType],
77946f0090SXuan Hu  override var rfn: CSRRfnType = null,
78039cdc35SXuan Hu) extends CSRRWType with CheckRef {
79039cdc35SXuan Hu  override final val wfn: CSRWfnType = wNoEffect
80039cdc35SXuan Hu}
81039cdc35SXuan Hu
82039cdc35SXuan Hucase class RefWLRLType(
83039cdc35SXuan Hu  override val ref: Option[CSREnumType],
84039cdc35SXuan Hu  override val wfn: CSRWfnType,
85946f0090SXuan Hu  override var rfn: CSRRfnType,
86039cdc35SXuan Hu) extends CSRRWType with CheckRef
87039cdc35SXuan Hu
88039cdc35SXuan Hucase class RefRWType(
89039cdc35SXuan Hu  override val ref: Option[CSREnumType],
90039cdc35SXuan Hu) extends CSRRWType with CheckRef {
91039cdc35SXuan Hu  override final val wfn: CSRWfnType = wNoFilter
92946f0090SXuan Hu  override final var rfn: CSRRfnType = null
93039cdc35SXuan Hu}
94039cdc35SXuan Hu
95039cdc35SXuan Huobject CSRFunc {
96039cdc35SXuan Hu  type CSRWfnType = (UInt, UInt, Seq[Data]) => UInt
97039cdc35SXuan Hu
98039cdc35SXuan Hu  def wNoFilter: CSRWfnType =
99039cdc35SXuan Hu    (newV: UInt, oldV: UInt, _: Seq[Data]) => newV
100039cdc35SXuan Hu
101039cdc35SXuan Hu  def wNoEffectWhen(keepCond: UInt => Bool): CSRWfnType =
102039cdc35SXuan Hu    (newV: UInt, oldV: UInt, _: Seq[Data]) => {
103039cdc35SXuan Hu      Mux(keepCond(newV), oldV, newV)
104039cdc35SXuan Hu    }
105039cdc35SXuan Hu
106039cdc35SXuan Hu  def wNoEffect: CSRWfnType =
107039cdc35SXuan Hu    (_: UInt, oldV: UInt, _: Seq[Data]) => { oldV }
108039cdc35SXuan Hu
109039cdc35SXuan Hu  type CSRRfnType = (UInt, Seq[Data]) => UInt
110039cdc35SXuan Hu
111039cdc35SXuan Hu  def rNoFilter: CSRRfnType = null
112039cdc35SXuan Hu
113039cdc35SXuan Hu  def rWithFilter(rFilter: (UInt, Seq[Data]) => UInt): CSRRfnType =
114039cdc35SXuan Hu    (oriV: UInt, seq: Seq[Data]) => rFilter(oriV, seq)
115039cdc35SXuan Hu
116039cdc35SXuan Hu  def rFixValue(value: UInt): CSRRfnType = {
117039cdc35SXuan Hu    (_, _) => value
118039cdc35SXuan Hu  }
119039cdc35SXuan Hu}
120039cdc35SXuan Hu
121039cdc35SXuan Huclass CSREnumType(
122039cdc35SXuan Hu  val msb: Int,
123039cdc35SXuan Hu  val lsb: Int,
124039cdc35SXuan Hu)(
125039cdc35SXuan Hu  var rwType: CSRRWType,
12625dc4a82SXuan Hu  var init: Data = null
127039cdc35SXuan Hu)(
128039cdc35SXuan Hu  override val factory: ChiselEnum
129039cdc35SXuan Hu) extends EnumType(factory) {
130039cdc35SXuan Hu
131*cb36ac0fSXuan Hu  var otherUpdateSeq: mutable.Seq[Tuple2[Bool, Data]] = mutable.Seq()
132*cb36ac0fSXuan Hu
13325dc4a82SXuan Hu  if (factory.all.isEmpty) {
134039cdc35SXuan Hu    factory.asInstanceOf[CSREnum].addMinValue
135039cdc35SXuan Hu  }
136039cdc35SXuan Hu
13701cdded8SXuan Hu  if (this.init != null && !factory.all.exists(_.litValue == this.init.litValue)) {
13825dc4a82SXuan Hu    factory.asInstanceOf[CSREnum].addNewValue(init.asUInt)
13925dc4a82SXuan Hu  }
14025dc4a82SXuan Hu
141039cdc35SXuan Hu  if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) {
142039cdc35SXuan Hu    factory.asInstanceOf[CSREnum].addMaxValue
143039cdc35SXuan Hu  }
144039cdc35SXuan Hu
145039cdc35SXuan Hu  if (msb - lsb + 1 > this.getWidth)
146039cdc35SXuan Hu    println(
147039cdc35SXuan Hu      s"[CSRInfo] $this: " +
148039cdc35SXuan Hu      s"the setting range($msb, $lsb) of bitfield is widen than EnumType's width(${this.getWidth}), " +
149039cdc35SXuan Hu      s"the higher bits will be optimized"
150039cdc35SXuan Hu    )
151039cdc35SXuan Hu
152039cdc35SXuan Hu  def isRef = this.rwType.isRef
153039cdc35SXuan Hu
154039cdc35SXuan Hu  def isRO = this.rwType.isRO
155039cdc35SXuan Hu
1561d192ad8SXuan Hu  def isRW = this.rwType.isRW
1571d192ad8SXuan Hu
158039cdc35SXuan Hu  def isWARL = this.rwType.isWARL
159039cdc35SXuan Hu
160946f0090SXuan Hu  def isHardWired = this.isRO && this.rwType.asInstanceOf[ROType].isHardWired
161946f0090SXuan Hu
162946f0090SXuan Hu  def getHardWireValue: UInt = this.rwType.asInstanceOf[ROType].hardWiredValue
163946f0090SXuan Hu
164039cdc35SXuan Hu  // Check if the write data is legal that can update the regfield.
165039cdc35SXuan Hu  // Also check if the write field is not Read Only.
166039cdc35SXuan Hu  def isLegal: Bool = this.factory.asInstanceOf[CSREnum].isLegal(this) && (!this.isRO).B
167039cdc35SXuan Hu
168a7a6d0a6Schengguanghui  def isLegal(dmode: Bool): Bool = this.factory.asInstanceOf[CSREnum].isLegal(this, dmode) && (!this.isRO).B
169a7a6d0a6Schengguanghui
170a7a6d0a6Schengguanghui  // make the illegal wdata legalize
171a7a6d0a6Schengguanghui  def legalize: CSREnumType = this.factory.asInstanceOf[CSREnum].legalize(this)
172a7a6d0a6Schengguanghui
173a7a6d0a6Schengguanghui  def legalize(dmode: Bool): CSREnumType = this.factory.asInstanceOf[CSREnum].legalize(this, dmode)
174a7a6d0a6Schengguanghui
17525dc4a82SXuan Hu  def needReset: Boolean = init != null
176039cdc35SXuan Hu
177039cdc35SXuan Hu  def rfn: CSRRfnType = rwType.rfn
178039cdc35SXuan Hu
179039cdc35SXuan Hu  def wfn: CSRWfnType = rwType.wfn
180039cdc35SXuan Hu
18125dc4a82SXuan Hu  // Check if reset with a enum value in factory.all
18225dc4a82SXuan Hu  protected def resetCheck[T <: EnumType](init: T): Unit = {
18325dc4a82SXuan Hu    resetCheckRWType
18425dc4a82SXuan Hu    require(this.factory.all.contains(init),
18525dc4a82SXuan Hu      s"""
18625dc4a82SXuan Hu      | The value ${init.litValue} is NOT in ${factory.all}.
18725dc4a82SXuan Hu      | Please check if $init is the enum in the $factory")
18825dc4a82SXuan Hu      """.stripMargin
18925dc4a82SXuan Hu    )
19025dc4a82SXuan Hu  }
19125dc4a82SXuan Hu
19225dc4a82SXuan Hu  // Check if reset with a enum value in factory.all
19325dc4a82SXuan Hu  protected def resetCheck(init: UInt): Unit = {
19425dc4a82SXuan Hu    resetCheckRWType
19525dc4a82SXuan Hu    require(this.factory.all.exists(_.litValue == init.litValue),
19625dc4a82SXuan Hu      s"""
19725dc4a82SXuan Hu      |The value ${init.litValue} is not in ${factory.all}.
19825dc4a82SXuan Hu      |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.
19925dc4a82SXuan Hu      |                                                ^              ^
20025dc4a82SXuan Hu      |""".stripMargin
20125dc4a82SXuan Hu    )
20225dc4a82SXuan Hu  }
20325dc4a82SXuan Hu
20425dc4a82SXuan Hu  protected def resetCheckRWType: Unit = {
205039cdc35SXuan Hu    rwType match {
206039cdc35SXuan Hu      case ROType(rfn) => require(rfn == null)
207039cdc35SXuan Hu      case _ =>
208039cdc35SXuan Hu    }
209039cdc35SXuan Hu  }
210039cdc35SXuan Hu
211039cdc35SXuan Hu  def withReset[T <: EnumType](init: T): this.type = {
21225dc4a82SXuan Hu    resetCheck(init)
21325dc4a82SXuan Hu    this.init = init
21425dc4a82SXuan Hu    if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) {
21525dc4a82SXuan Hu      factory.asInstanceOf[CSREnum].addMaxValue
21625dc4a82SXuan Hu    }
217039cdc35SXuan Hu    this
218039cdc35SXuan Hu  }
219039cdc35SXuan Hu
220039cdc35SXuan Hu  def withReset(init: UInt): this.type = {
22125dc4a82SXuan Hu    resetCheck(init)
22225dc4a82SXuan Hu    this.init = this.factory(init)
22325dc4a82SXuan Hu    if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) {
22425dc4a82SXuan Hu      factory.asInstanceOf[CSREnum].addMaxValue
22525dc4a82SXuan Hu    }
22625dc4a82SXuan Hu    this
22725dc4a82SXuan Hu  }
22825dc4a82SXuan Hu
22925dc4a82SXuan Hu  // Reset using the value not in factory.all
23025dc4a82SXuan Hu  def withNonEnumReset(init: UInt): this.type = {
23125dc4a82SXuan Hu    resetCheckRWType
23225dc4a82SXuan Hu    if (!this.factory.all.exists(_.litValue == init.litValue)) {
23325dc4a82SXuan Hu      this.factory.asInstanceOf[CSREnum].addNewValue(init)
23425dc4a82SXuan Hu      println(s"[CSR-info] add reset value ${init.litValue} into $this")
23525dc4a82SXuan Hu    }
23625dc4a82SXuan Hu    if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) {
23725dc4a82SXuan Hu      factory.asInstanceOf[CSREnum].addMaxValue
23825dc4a82SXuan Hu    }
239039cdc35SXuan Hu    this
240039cdc35SXuan Hu  }
241039cdc35SXuan Hu
242039cdc35SXuan Hu  def := (that: UInt): Unit = {
2439a28ebd4SXuan Hu    suppressEnumCastWarning {
244039cdc35SXuan Hu      this := this.factory(that)
245039cdc35SXuan Hu    }
2469a28ebd4SXuan Hu  }
247039cdc35SXuan Hu
248039cdc35SXuan Hu  def dumpName = {
249039cdc35SXuan Hu    s"${chisel3.reflect.DataMirror.queryNameGuess(this)} ${rwType} [$msb, $lsb] reset($init)"
250039cdc35SXuan Hu  }
251039cdc35SXuan Hu
252039cdc35SXuan Hu  def asBool: Bool = {
253039cdc35SXuan Hu    this.asUInt.asBool
254039cdc35SXuan Hu  }
255039cdc35SXuan Hu
256039cdc35SXuan Hu  private def setRwType(newType: CSRRWType): this.type = {
257039cdc35SXuan Hu    this.rwType = newType
258039cdc35SXuan Hu    this
259039cdc35SXuan Hu  }
260039cdc35SXuan Hu
261039cdc35SXuan Hu  def setRO(rfn: CSRRfnType = null): this.type = {
262039cdc35SXuan Hu    this.setRwType(ROType(rfn))
263039cdc35SXuan Hu  }
264039cdc35SXuan Hu
265946f0090SXuan Hu  def setHardWired(value: UInt): this.type = {
266946f0090SXuan Hu    require(this.isRO)
267946f0090SXuan Hu    this.rwType.asInstanceOf[ROType].setHardWired(value)
268946f0090SXuan Hu    this
269946f0090SXuan Hu  }
270946f0090SXuan Hu
271039cdc35SXuan Hu  def setRW(): this.type = {
272039cdc35SXuan Hu    this.setRwType(RWType())
273039cdc35SXuan Hu  }
274039cdc35SXuan Hu
275039cdc35SXuan Hu  def setWARL(wfn: CSRWfnType): this.type = {
276039cdc35SXuan Hu    this.setRwType(WARLType(wfn))
277039cdc35SXuan Hu  }
278039cdc35SXuan Hu
27902a84a36SXuan Hu  def ||(that: Bool): Bool = {
28002a84a36SXuan Hu    require(this.getWidth == 1, s"Only 1 bit field can use operator ||. The width of left operand is ${this.getWidth}")
28102a84a36SXuan Hu    this.asBool || that
28202a84a36SXuan Hu  }
28302a84a36SXuan Hu
28402a84a36SXuan Hu  def ||(that: CSREnumType): Bool = {
28502a84a36SXuan Hu    require(this.getWidth == 1, s"Only 1 bit field can use operator ||. The width of left operand is ${this.getWidth}")
28602a84a36SXuan Hu    require(that.getWidth == 1, s"Only 1 bit field can use operator ||. The width of right operand is ${that.getWidth}")
28702a84a36SXuan Hu    this.asBool || that.asBool
28802a84a36SXuan Hu  }
28902a84a36SXuan Hu
290423dd365SXuan Hu  def &&(that: Bool): Bool = {
291423dd365SXuan Hu    require(this.getWidth == 1, s"Only 1 bit field can use operator &&. The width of left operand is ${this.getWidth}")
292423dd365SXuan Hu    this.asBool && that
293423dd365SXuan Hu  }
294423dd365SXuan Hu
295423dd365SXuan Hu  def &&(that: CSREnumType): Bool = {
296423dd365SXuan Hu    require(this.getWidth == 1, s"Only 1 bit field can use operator &&. The width of left operand is ${this.getWidth}")
297423dd365SXuan Hu    require(that.getWidth == 1, s"Only 1 bit field can use operator &&. The width of right operand is ${that.getWidth}")
298423dd365SXuan Hu    this.asBool && that.asBool
299423dd365SXuan Hu  }
300423dd365SXuan Hu
3011d192ad8SXuan Hu  def unary_! : Bool = {
3021d192ad8SXuan Hu    require(this.getWidth == 1, s"Only 1 bit field can use operator &&. The width of left operand is ${this.getWidth}")
3031d192ad8SXuan Hu    !this.asBool
3041d192ad8SXuan Hu  }
3051d192ad8SXuan Hu
3061d192ad8SXuan Hu  def & (that: UInt): UInt = {
3071d192ad8SXuan Hu    require(this.getWidth == that.getWidth || !that.widthKnown)
3081d192ad8SXuan Hu    this.asUInt & that
3091d192ad8SXuan Hu  }
3101d192ad8SXuan Hu
3111d192ad8SXuan Hu  def &> (that: Bool): UInt = {
3121d192ad8SXuan Hu    this.asUInt & Fill(this.getWidth, that)
3131d192ad8SXuan Hu  }
3141d192ad8SXuan Hu
3151d192ad8SXuan Hu  def |> (that: Bool): UInt = {
3161d192ad8SXuan Hu    this.asUInt | Fill(this.getWidth, that)
3171d192ad8SXuan Hu  }
3181d192ad8SXuan Hu
319*cb36ac0fSXuan Hu  def addOtherUpdate(cond: Bool, value: CSREnumType): this.type = {
320*cb36ac0fSXuan Hu    this.otherUpdateSeq :+= (cond, value)
321*cb36ac0fSXuan Hu    this
322*cb36ac0fSXuan Hu  }
323*cb36ac0fSXuan Hu
324039cdc35SXuan Hu  // override cloneType to make ValidIO etc function return CSREnumType not EnumType
3251d192ad8SXuan Hu  override def cloneType: this.type = factory.asInstanceOf[CSREnum].makeType.asInstanceOf[this.type].setRwType(this.rwType)
326039cdc35SXuan Hu}
327039cdc35SXuan Hu
328436f48ccSXuan Huclass CSREnum extends ChiselEnum {
329d0b87b97SXuan Hu  protected def apply(rwType: CSRRWType)(msb: Int, lsb: Int)(factory: ChiselEnum): CSREnumType = {
330039cdc35SXuan Hu    this.msb = msb
331039cdc35SXuan Hu    this.lsb = lsb
332d0b87b97SXuan Hu    new CSREnumType(msb, lsb)(rwType, null)(factory)
333039cdc35SXuan Hu  }
334039cdc35SXuan Hu
335039cdc35SXuan Hu  var msb, lsb: Int = 0
336039cdc35SXuan Hu
337237d4cfdSXuan Hu  def makeType: CSREnumType = {
338039cdc35SXuan Hu    new CSREnumType(msb, lsb)(RWType())(this)
339039cdc35SXuan Hu  }
340039cdc35SXuan Hu
341039cdc35SXuan Hu  /**
342039cdc35SXuan Hu   * Used to allow 0.U.asTypeOf(CSREnumInstance) convertion
343039cdc35SXuan Hu   */
344039cdc35SXuan Hu  def addMinValue: Unit = {
345039cdc35SXuan Hu    Value(0.U)
346039cdc35SXuan Hu  }
347039cdc35SXuan Hu
348039cdc35SXuan Hu  /**
349039cdc35SXuan Hu   * A trick to expand the width of Enum to (msb - lsb + 1)
350039cdc35SXuan Hu   */
351039cdc35SXuan Hu  def addMaxValue: Unit = {
352039cdc35SXuan Hu    Value(((BigInt(1) << (msb - lsb + 1)) - 1).U)
353039cdc35SXuan Hu  }
354039cdc35SXuan Hu
35525dc4a82SXuan Hu  /**
35625dc4a82SXuan Hu   *
35725dc4a82SXuan Hu   * @param value: A new value need to add in Enum set
35825dc4a82SXuan Hu   * @return this
35925dc4a82SXuan Hu   */
36025dc4a82SXuan Hu  def addNewValue(value: UInt): this.type = {
36125dc4a82SXuan Hu    Value(value)
36225dc4a82SXuan Hu    this
36325dc4a82SXuan Hu  }
36425dc4a82SXuan Hu
365e3da8badSTang Haojin  def isLegal(enumeration: CSREnumType): Bool = true.B
366039cdc35SXuan Hu
367e3da8badSTang Haojin  def isLegal(enumeration: CSREnumType, dmode: Bool): Bool = true.B
368a7a6d0a6Schengguanghui
369e3da8badSTang Haojin  def legalize(enumeration: CSREnumType): CSREnumType = makeType
370a7a6d0a6Schengguanghui
371e3da8badSTang Haojin  def legalize(enumeration: CSREnumType, dmode: Bool): CSREnumType = makeType
372039cdc35SXuan Hu}
373039cdc35SXuan Hu
374436f48ccSXuan Hutrait RWApply { self: CSREnum =>
375436f48ccSXuan Hu  def apply(msb: Int, lsb: Int): CSREnumType = self
376436f48ccSXuan Hu    .apply(RWType())(msb, lsb)(this)
377436f48ccSXuan Hu
378436f48ccSXuan Hu  def apply(bit: Int): CSREnumType = apply(bit, bit)
379436f48ccSXuan Hu}
380436f48ccSXuan Hu
381436f48ccSXuan Hutrait ROApply { self: CSREnum =>
382039cdc35SXuan Hu  def apply(msb: Int, lsb: Int): CSREnumType = self
383039cdc35SXuan Hu    .apply(ROType())(msb, lsb)(this)
384039cdc35SXuan Hu}
385039cdc35SXuan Hu
386436f48ccSXuan Hutrait WARLApply { self: CSREnum =>
387039cdc35SXuan Hu  def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
388039cdc35SXuan Hu    .apply(WARLType(wfn, rfn))(msb, lsb)(this)
389039cdc35SXuan Hu
390039cdc35SXuan Hu  def apply(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self
391039cdc35SXuan Hu    .apply(WARLType(wfn))(msb, lsb)(this)
3929ff1c68fSsinceforYy
3939ff1c68fSsinceforYy  def apply(bit: Int, wfn: CSRWfnType): CSREnumType = apply(bit, bit, wfn)
394039cdc35SXuan Hu}
395039cdc35SXuan Hu
396436f48ccSXuan Hutrait WLRLApply { self: CSREnum =>
397039cdc35SXuan Hu  def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
398039cdc35SXuan Hu    .apply(WLRLType(wfn, rfn))(msb, lsb)(this)
399039cdc35SXuan Hu}
400039cdc35SXuan Hu
401039cdc35SXuan Hutrait CSRMacroApply { self: CSREnum =>
402d0b87b97SXuan Hu  def RO(msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self
403d0b87b97SXuan Hu    .apply(ROType(rfn))(msb, lsb)(this)
404039cdc35SXuan Hu
405d0b87b97SXuan Hu  def RW(msb: Int, lsb: Int): CSREnumType = self
406d0b87b97SXuan Hu    .apply(RWType())(msb, lsb)(this)
407039cdc35SXuan Hu
408039cdc35SXuan Hu  def WARL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
409039cdc35SXuan Hu    .apply(WARLType(wfn, rfn))(msb, lsb)(this)
410039cdc35SXuan Hu
411039cdc35SXuan Hu  def WLRL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
412039cdc35SXuan Hu    .apply(WLRLType(wfn, rfn))(msb, lsb)(this)
413039cdc35SXuan Hu
414039cdc35SXuan Hu  def RefRO(ref: CSREnumType, msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self
415039cdc35SXuan Hu    .apply(RefROType(Some(ref) ,rfn))(msb, lsb)(ref.factory)
416039cdc35SXuan Hu
417039cdc35SXuan Hu  def RefRO(ref: CSREnumType, msb: Int, lsb: Int): CSREnumType = self
418039cdc35SXuan Hu    .apply(RefROType(Some(ref)))(msb, lsb)(ref.factory)
419039cdc35SXuan Hu
420039cdc35SXuan Hu  def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
421039cdc35SXuan Hu    .apply(RefWARLType(Some(ref), wfn, rfn))(msb, lsb)(ref.factory)
422039cdc35SXuan Hu
423039cdc35SXuan Hu  def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self
424039cdc35SXuan Hu    .apply(RefWARLType(Some(ref), wfn))(msb, lsb)(ref.factory)
425039cdc35SXuan Hu}
426039cdc35SXuan Hu
427039cdc35SXuan Huobject CSREnumTypeImplicitCast {
428039cdc35SXuan Hu  class BoolField(val value: Bool) {
429039cdc35SXuan Hu    def && (field: CSREnumType): Bool = {
430039cdc35SXuan Hu      this.value && field.asBool
431039cdc35SXuan Hu    }
432039cdc35SXuan Hu
433039cdc35SXuan Hu    def || (field: CSREnumType): Bool = {
434039cdc35SXuan Hu      this.value || field.asBool
435039cdc35SXuan Hu    }
4361d192ad8SXuan Hu
4371d192ad8SXuan Hu    def &<(that: UInt): UInt = {
4381d192ad8SXuan Hu      require(that.widthKnown, "The width of the right operand should be known when using &< operator")
4391d192ad8SXuan Hu      Fill(that.getWidth, this.value) & that
4401d192ad8SXuan Hu    }
4411d192ad8SXuan Hu
4421d192ad8SXuan Hu    def &<(that: CSREnumType): UInt = {
4431d192ad8SXuan Hu      this &< that.asUInt
4441d192ad8SXuan Hu    }
4451d192ad8SXuan Hu
4461d192ad8SXuan Hu    def |<(that: UInt): UInt = {
4471d192ad8SXuan Hu      require(that.widthKnown, "The width of the right operand should be known when using |< operator")
4481d192ad8SXuan Hu      Fill(that.getWidth, this.value) | that
4491d192ad8SXuan Hu    }
4501d192ad8SXuan Hu
4511d192ad8SXuan Hu    def |<(that: CSREnumType): UInt = {
4521d192ad8SXuan Hu      this |< that.asUInt
4531d192ad8SXuan Hu    }
454039cdc35SXuan Hu  }
455039cdc35SXuan Hu
456039cdc35SXuan Hu  implicit def BoolToBoolField(bool: Bool): BoolField = new BoolField(bool)
457039cdc35SXuan Hu}
458039cdc35SXuan Hu
459