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