xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRBundle.scala (revision 039cdc35f5f3b68b6295ec5ace90f22a77322e02)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.experimental.SourceInfo
5import chisel3.util.Cat
6
7import scala.language.experimental.macros
8
9
10abstract class CSRBundle extends Bundle {
11  val len: Int = 64
12
13  override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = {
14    val fields = this.getFields
15    var paddedFields: Seq[Data] = Seq()
16    var lsb = len
17
18    for (field <- fields) {
19      val diffWidth = lsb - field.lsb - field.getWidth
20      if (diffWidth > 0)
21        paddedFields :+= 0.U((diffWidth).W)
22      paddedFields :+= field
23      lsb = field.lsb
24    }
25
26    if (fields.last.lsb > 0) {
27      paddedFields :+= 0.U(fields.last.lsb.W)
28    }
29
30    Cat(paddedFields.map(x => x.asUInt))
31  }
32
33  def := (that: UInt): Unit = {
34    val fields = this.getFields
35
36    for (field <- fields) {
37      field := field.factory.apply(that(field.lsb + field.getWidth - 1, field.lsb))
38    }
39  }
40
41  @inline
42  def init: this.type = {
43    val init = Wire(this)
44    init.elements.foreach { case (str, field: CSREnumType) =>
45      field := (if (field.init.nonEmpty) field.init.get else field.factory(0.U))
46    }
47    init.asInstanceOf[this.type]
48  }
49
50  /**
51   * filtered read connection
52   *
53   * CSRBundle will be filtered by CSRFields' read filter function.
54   */
55  def :|= [T <: CSRBundle](that: T): Unit = {
56    if (this.getClass != that.getClass) {
57      throw MonoConnectException(s"Type miss match! (sink :|= source) " +
58        s"sink type: ${this.getClass}, " +
59        s"source type: ${that.getClass}")
60    }
61
62    for ((sink: CSREnumType, source: CSREnumType)  <- this.getFields.zip(that.getFields)) {
63      if (sink.rfn == null)
64        sink := source // .factory.apply(sink.rfn(source.asUInt, Seq()))
65      else
66        sink := sink.factory(sink.rfn(source.asUInt, Seq()))
67    }
68  }
69
70  def getFields: Seq[CSREnumType] = this.getElements.map(_.asInstanceOf[CSREnumType])
71
72  def needReset: Boolean = this.getFields.exists(_.needReset)
73}
74