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