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