xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRFields.scala (revision 436f48ccfcd02c61399e6e1438befbbea3b32986)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4
5import xiangshan.backend.fu.NewCSR.CSRFunc._
6
7abstract class CSRRWType {
8  val wfn: CSRWfnType
9  val rfn: CSRRfnType
10  val ref: Option[CSREnumType] = None
11
12  def isRO: Boolean = this.isInstanceOf[ROType] || this.isInstanceOf[RefROType]
13
14  def isRW: Boolean = this.isInstanceOf[RWType] || this.isInstanceOf[RefRWType]
15
16  def isWARL: Boolean = this.isInstanceOf[WARLType] || this.isInstanceOf[RefWARLType]
17
18  def isWLRL: Boolean = this.isInstanceOf[WLRLType] || this.isInstanceOf[RefWLRLType]
19
20  def isRef: Boolean = this.isInstanceOf[RefROType] || this.isInstanceOf[RefRWType] || this.isInstanceOf[RefWARLType] ||
21    this.isInstanceOf[RefWLRLType]
22
23  override def toString: String = {
24    val typeString = this match {
25      case WARLType(_, _) => "WARL"
26      case ROType(_)      => "RO"
27      case WLRLType(_, _) => "WLRL"
28      case RWType()       => "RW"
29    }
30    typeString + (if (isRef) " Ref" else "")
31  }
32}
33
34case class WARLType(
35  override val wfn: CSRWfnType,
36  override val rfn: CSRRfnType = null,
37) extends CSRRWType
38
39case class ROType(
40  override val rfn: CSRRfnType = null,
41) extends CSRRWType {
42  override final val wfn: CSRWfnType = wNoEffect
43}
44
45case class WLRLType(
46  override val wfn: CSRWfnType,
47  override val rfn: CSRRfnType,
48) extends CSRRWType
49
50case class RWType() extends CSRRWType {
51  override final val wfn: CSRWfnType = wNoFilter
52  override final val rfn: CSRRfnType = null
53}
54
55trait CheckRef { self: CSRRWType =>
56  require(ref.nonEmpty)
57}
58
59case class RefWARLType(
60  override val ref: Option[CSREnumType],
61  override val wfn: CSRWfnType,
62  override val rfn: CSRRfnType = null,
63) extends CSRRWType with CheckRef
64
65case class RefROType(
66  override val ref: Option[CSREnumType],
67  override val rfn: CSRRfnType = null,
68) extends CSRRWType with CheckRef {
69  override final val wfn: CSRWfnType = wNoEffect
70}
71
72case class RefWLRLType(
73  override val ref: Option[CSREnumType],
74  override val wfn: CSRWfnType,
75  override val rfn: CSRRfnType,
76) extends CSRRWType with CheckRef
77
78case class RefRWType(
79  override val ref: Option[CSREnumType],
80) extends CSRRWType with CheckRef {
81  override final val wfn: CSRWfnType = wNoFilter
82  override final val rfn: CSRRfnType = null
83}
84
85object CSRFunc {
86  type CSRWfnType = (UInt, UInt, Seq[Data]) => UInt
87
88  def wNoFilter: CSRWfnType =
89    (newV: UInt, oldV: UInt, _: Seq[Data]) => newV
90
91  def wNoEffectWhen(keepCond: UInt => Bool): CSRWfnType =
92    (newV: UInt, oldV: UInt, _: Seq[Data]) => {
93      Mux(keepCond(newV), oldV, newV)
94    }
95
96  def wNoEffect: CSRWfnType =
97    (_: UInt, oldV: UInt, _: Seq[Data]) => { oldV }
98
99  type CSRRfnType = (UInt, Seq[Data]) => UInt
100
101  def rNoFilter: CSRRfnType = null
102
103  def rWithFilter(rFilter: (UInt, Seq[Data]) => UInt): CSRRfnType =
104    (oriV: UInt, seq: Seq[Data]) => rFilter(oriV, seq)
105
106  def rFixValue(value: UInt): CSRRfnType = {
107    (_, _) => value
108  }
109}
110
111class CSREnumType(
112  val msb: Int,
113  val lsb: Int,
114)(
115  var rwType: CSRRWType,
116)(
117  override val factory: ChiselEnum
118) extends EnumType(factory) {
119  var init: Option[EnumType] = None
120
121  if (factory.all.size == 0) {
122    factory.asInstanceOf[CSREnum].addMinValue
123  }
124
125  if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) {
126    factory.asInstanceOf[CSREnum].addMaxValue
127  }
128
129  if (msb - lsb + 1 > this.getWidth)
130    println(
131      s"[CSRInfo] $this: " +
132      s"the setting range($msb, $lsb) of bitfield is widen than EnumType's width(${this.getWidth}), " +
133      s"the higher bits will be optimized"
134    )
135
136  def isRef = this.rwType.isRef
137
138  def isRO = this.rwType.isRO
139
140  def isWARL = this.rwType.isWARL
141
142  // Check if the write data is legal that can update the regfield.
143  // Also check if the write field is not Read Only.
144  def isLegal: Bool = this.factory.asInstanceOf[CSREnum].isLegal(this) && (!this.isRO).B
145
146  def needReset: Boolean = init.nonEmpty
147
148  def rfn: CSRRfnType = rwType.rfn
149
150  def wfn: CSRWfnType = rwType.wfn
151
152  protected def resetCheck: Unit = {
153    rwType match {
154      case ROType(rfn) => require(rfn == null)
155      case _ =>
156    }
157  }
158
159  def withReset[T <: EnumType](init: T): this.type = {
160    resetCheck
161    this.init = Some(init)
162    this
163  }
164
165  def withReset(init: UInt): this.type = {
166    resetCheck
167    this.init = Some(this.factory(init))
168    this
169  }
170
171  def := (that: UInt): Unit = {
172    this := this.factory(that)
173  }
174
175  def dumpName = {
176    s"${chisel3.reflect.DataMirror.queryNameGuess(this)} ${rwType} [$msb, $lsb] reset($init)"
177  }
178
179  def asBool: Bool = {
180    this.asUInt.asBool
181  }
182
183  private def setRwType(newType: CSRRWType): this.type = {
184    this.rwType = newType
185    this
186  }
187
188  def setRO(rfn: CSRRfnType = null): this.type = {
189    this.setRwType(ROType(rfn))
190  }
191
192  def setRW(): this.type = {
193    this.setRwType(RWType())
194  }
195
196  def setWARL(wfn: CSRWfnType): this.type = {
197    this.setRwType(WARLType(wfn))
198  }
199
200  // override cloneType to make ValidIO etc function return CSREnumType not EnumType
201  override def cloneType: this.type = factory.asInstanceOf[CSREnum].makeType.asInstanceOf[this.type]
202}
203
204class CSREnum extends ChiselEnum {
205  protected def apply(rwType: CSRRWType)(msb: Int, lsb: Int)(factory: ChiselEnum): CSREnumType = {
206    this.msb = msb
207    this.lsb = lsb
208    new CSREnumType(msb, lsb)(rwType)(factory)
209  }
210
211  var msb, lsb: Int = 0
212
213  def makeType: CSREnumType = {
214    new CSREnumType(msb, lsb)(RWType())(this)
215  }
216
217  /**
218   * Used to allow 0.U.asTypeOf(CSREnumInstance) convertion
219   */
220  def addMinValue: Unit = {
221    Value(0.U)
222  }
223
224  /**
225   * A trick to expand the width of Enum to (msb - lsb + 1)
226   */
227  def addMaxValue: Unit = {
228    Value(((BigInt(1) << (msb - lsb + 1)) - 1).U)
229  }
230
231  def isLegal(enum: CSREnumType): Bool = true.B
232
233  println(s"A new CSREnum is created, factory: $this")
234}
235
236trait RWApply { self: CSREnum =>
237  def apply(msb: Int, lsb: Int): CSREnumType = self
238    .apply(RWType())(msb, lsb)(this)
239
240  def apply(bit: Int): CSREnumType = apply(bit, bit)
241}
242
243trait ROApply { self: CSREnum =>
244  def apply(msb: Int, lsb: Int): CSREnumType = self
245    .apply(ROType())(msb, lsb)(this)
246}
247
248trait WARLApply { self: CSREnum =>
249  def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
250    .apply(WARLType(wfn, rfn))(msb, lsb)(this)
251
252  def apply(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self
253    .apply(WARLType(wfn))(msb, lsb)(this)
254}
255
256trait WLRLApply { self: CSREnum =>
257  def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
258    .apply(WLRLType(wfn, rfn))(msb, lsb)(this)
259}
260
261trait CSRMacroApply { self: CSREnum =>
262  def RO(msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self
263    .apply(ROType(rfn))(msb, lsb)(this)
264
265  def RO(msb: Int, lsb: Int): CSREnumType = self
266    .apply(ROType())(msb, lsb)(this)
267
268  def RW(msb: Int, lsb: Int): CSREnumType = self
269    .apply(RWType())(msb, lsb)(this)
270
271  def WARL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
272    .apply(WARLType(wfn, rfn))(msb, lsb)(this)
273
274  def WARL(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self
275    .apply(WARLType(wfn))(msb, lsb)(this)
276
277  def WLRL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
278    .apply(WLRLType(wfn, rfn))(msb, lsb)(this)
279
280  def RefRO(ref: CSREnumType, msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self
281    .apply(RefROType(Some(ref) ,rfn))(msb, lsb)(ref.factory)
282
283  def RefRO(ref: CSREnumType, msb: Int, lsb: Int): CSREnumType = self
284    .apply(RefROType(Some(ref)))(msb, lsb)(ref.factory)
285
286  def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self
287    .apply(RefWARLType(Some(ref), wfn, rfn))(msb, lsb)(ref.factory)
288
289  def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self
290    .apply(RefWARLType(Some(ref), wfn))(msb, lsb)(ref.factory)
291}
292
293object CSREnumTypeImplicitCast {
294  implicit def CSREnumTypeToUInt(field: CSREnumType): UInt = {
295    field.asUInt
296  }
297
298  class BoolField(val value: Bool) {
299    def && (field: CSREnumType): Bool = {
300      this.value && field.asBool
301    }
302
303    def || (field: CSREnumType): Bool = {
304      this.value || field.asBool
305    }
306  }
307
308  implicit def BoolToBoolField(bool: Bool): BoolField = new BoolField(bool)
309}
310
311