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