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