xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRFields.scala (revision 039cdc35f5f3b68b6295ec5ace90f22a77322e02)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4
5import xiangshan.backend.fu.NewCSR.CSRFunc._
6
7import scala.language.experimental.macros
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)(
119  override val factory: ChiselEnum
120) extends EnumType(factory) {
121  var init: Option[EnumType] = None
122
123  if (factory.all.size == 0) {
124    factory.asInstanceOf[CSREnum].addMinValue
125  }
126
127  if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) {
128    factory.asInstanceOf[CSREnum].addMaxValue
129  }
130
131  if (msb - lsb + 1 > this.getWidth)
132    println(
133      s"[CSRInfo] $this: " +
134      s"the setting range($msb, $lsb) of bitfield is widen than EnumType's width(${this.getWidth}), " +
135      s"the higher bits will be optimized"
136    )
137
138  def isRef = this.rwType.isRef
139
140  def isRO = this.rwType.isRO
141
142  def isWARL = this.rwType.isWARL
143
144  // Check if the write data is legal that can update the regfield.
145  // Also check if the write field is not Read Only.
146  def isLegal: Bool = this.factory.asInstanceOf[CSREnum].isLegal(this) && (!this.isRO).B
147
148  def needReset: Boolean = init.nonEmpty
149
150  def rfn: CSRRfnType = rwType.rfn
151
152  def wfn: CSRWfnType = rwType.wfn
153
154  protected def resetCheck: Unit = {
155    rwType match {
156      case ROType(rfn) => require(rfn == null)
157      case _ =>
158    }
159  }
160
161  def withReset[T <: EnumType](init: T): this.type = {
162    resetCheck
163    this.init = Some(init)
164    this
165  }
166
167  def withReset(init: UInt): this.type = {
168    resetCheck
169    this.init = Some(this.factory(init))
170    this
171  }
172
173  def := (that: UInt): Unit = {
174    this := this.factory(that)
175  }
176
177  def dumpName = {
178    s"${chisel3.reflect.DataMirror.queryNameGuess(this)} ${rwType} [$msb, $lsb] reset($init)"
179  }
180
181  def asBool: Bool = {
182    this.asUInt.asBool
183  }
184
185  private def setRwType(newType: CSRRWType): this.type = {
186    this.rwType = newType
187    this
188  }
189
190  def setRO(rfn: CSRRfnType = null): this.type = {
191    this.setRwType(ROType(rfn))
192  }
193
194  def setRW(): this.type = {
195    this.setRwType(RWType())
196  }
197
198  def setWARL(wfn: CSRWfnType): this.type = {
199    this.setRwType(WARLType(wfn))
200  }
201
202  // override cloneType to make ValidIO etc function return CSREnumType not EnumType
203  override def cloneType: this.type = factory.asInstanceOf[CSREnum].makeType.asInstanceOf[this.type]
204}
205
206abstract class CSREnum extends ChiselEnum {
207  type Type = CSREnumType
208
209  protected def apply(rwType: CSRRWType)(msb: Int, lsb: Int)(factory: ChiselEnum): CSREnumType = {
210    this.msb = msb
211    this.lsb = lsb
212    new CSREnumType(msb, lsb)(rwType)(factory)
213  }
214
215  var msb, lsb: Int = 0
216
217  def makeType: Type = {
218    new CSREnumType(msb, lsb)(RWType())(this)
219  }
220
221  /**
222   * Used to allow 0.U.asTypeOf(CSREnumInstance) convertion
223   */
224  def addMinValue: Unit = {
225    Value(0.U)
226  }
227
228  /**
229   * A trick to expand the width of Enum to (msb - lsb + 1)
230   */
231  def addMaxValue: Unit = {
232    Value(((BigInt(1) << (msb - lsb + 1)) - 1).U)
233  }
234
235  def isLegal(enum: CSREnumType): Bool = true.B
236
237  println(s"A new CSREnum is created, factory: $this")
238}
239
240trait CSRROApply { self: CSREnum =>
241  def apply(msb: Int, lsb: Int): CSREnumType = self
242    .apply(ROType())(msb, lsb)(this)
243}
244
245trait CSRRWApply { self: CSREnum =>
246  def apply(msb: Int, lsb: Int): CSREnumType = self
247    .apply(RWType())(msb, lsb)(this)
248}
249
250trait CSRWARLApply { self: CSREnum =>
251  def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
252    .apply(WARLType(wfn, rfn))(msb, lsb)(this)
253
254  def apply(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self
255    .apply(WARLType(wfn))(msb, lsb)(this)
256}
257
258trait CSRWLRLApply { self: CSREnum =>
259  def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
260    .apply(WLRLType(wfn, rfn))(msb, lsb)(this)
261}
262
263trait CSRMacroApply { self: CSREnum =>
264  def RO(msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self
265    .apply(ROType(rfn))(msb, lsb)(this)
266
267  def RO(msb: Int, lsb: Int): CSREnumType = self
268    .apply(ROType())(msb, lsb)(this)
269
270  def RW(msb: Int, lsb: Int): CSREnumType = self
271    .apply(RWType())(msb, lsb)(this)
272
273  def WARL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
274    .apply(WARLType(wfn, rfn))(msb, lsb)(this)
275
276  def WARL(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self
277    .apply(WARLType(wfn))(msb, lsb)(this)
278
279  def WLRL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
280    .apply(WLRLType(wfn, rfn))(msb, lsb)(this)
281
282  def RefRO(ref: CSREnumType, msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self
283    .apply(RefROType(Some(ref) ,rfn))(msb, lsb)(ref.factory)
284
285  def RefRO(ref: CSREnumType, msb: Int, lsb: Int): CSREnumType = self
286    .apply(RefROType(Some(ref)))(msb, lsb)(ref.factory)
287
288  def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
289    .apply(RefWARLType(Some(ref), wfn, rfn))(msb, lsb)(ref.factory)
290
291  def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self
292    .apply(RefWARLType(Some(ref), wfn))(msb, lsb)(ref.factory)
293}
294
295object CSREnumTypeImplicitCast {
296  implicit def CSREnumTypeToUInt(field: CSREnumType): UInt = {
297    field.asUInt
298  }
299
300  class BoolField(val value: Bool) {
301    def && (field: CSREnumType): Bool = {
302      this.value && field.asBool
303    }
304
305    def || (field: CSREnumType): Bool = {
306      this.value || field.asBool
307    }
308  }
309
310  implicit def BoolToBoolField(bool: Bool): BoolField = new BoolField(bool)
311}
312
313