1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.experimental.SourceInfo 5import chisel3.util.Cat 6 7import scala.language.experimental.macros 8 9 10abstract class CSRBundle extends Bundle { 11 val len: Int = 64 12 13 override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = { 14 val fields = this.getFields 15 var paddedFields: Seq[Data] = Seq() 16 var lsb = len 17 18 for (field <- fields) { 19 val diffWidth = lsb - field.lsb - field.getWidth 20 if (diffWidth > 0) 21 paddedFields :+= 0.U((diffWidth).W) 22 paddedFields :+= field 23 lsb = field.lsb 24 } 25 26 if (fields.last.lsb > 0) { 27 paddedFields :+= 0.U(fields.last.lsb.W) 28 } 29 30 Cat(paddedFields.map(x => x.asUInt)) 31 } 32 33 def := (that: UInt): Unit = { 34 val fields = this.getFields 35 36 for (field <- fields) { 37 field := field.factory.apply(that(field.lsb + field.getWidth - 1, field.lsb)) 38 } 39 } 40 41 @inline 42 def init: this.type = { 43 val init = Wire(this) 44 init.elements.foreach { case (str, field: CSREnumType) => 45 field := (if (field.init.nonEmpty) field.init.get else field.factory(0.U)) 46 } 47 init.asInstanceOf[this.type] 48 } 49 50 /** 51 * filtered read connection 52 * 53 * CSRBundle will be filtered by CSRFields' read filter function. 54 */ 55 def :|= [T <: CSRBundle](that: T): Unit = { 56 if (this.getClass != that.getClass) { 57 throw MonoConnectException(s"Type miss match! (sink :|= source) " + 58 s"sink type: ${this.getClass}, " + 59 s"source type: ${that.getClass}") 60 } 61 62 for ((sink: CSREnumType, source: CSREnumType) <- this.getFields.zip(that.getFields)) { 63 if (sink.rfn == null) 64 sink := source // .factory.apply(sink.rfn(source.asUInt, Seq())) 65 else 66 sink := sink.factory(sink.rfn(source.asUInt, Seq())) 67 } 68 } 69 70 def getFields: Seq[CSREnumType] = this.getElements.map(_.asInstanceOf[CSREnumType]) 71 72 def needReset: Boolean = this.getFields.exists(_.needReset) 73} 74