1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.experimental.SourceInfo 5import chisel3.util.{Cat, Fill} 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 suppressEnumCastWarning { 41 for (field <- fields) { 42 field := field.factory.apply(that(field.lsb + field.getWidth - 1, field.lsb)) 43 } 44 } 45 } 46 47 @inline 48 def init: this.type = { 49 val init = Wire(this) 50 suppressEnumCastWarning { 51 init.elements.foreach { case (str, field: CSREnumType) => 52 field := (if (field.init != null) field.factory(field.init.asUInt) else field.factory(0.U)) 53 } 54 } 55 init.asInstanceOf[this.type] 56 } 57 58 /** 59 * filtered read connection 60 * 61 * CSRBundle will be filtered by CSRFields' read filter function. 62 */ 63 def :|= [T <: CSRBundle](that: T): Unit = { 64 if (this.getClass != that.getClass) { 65 throw MonoConnectException(s"Type miss match! (sink :|= source) " + 66 s"sink type: ${this.getClass}, " + 67 s"source type: ${that.getClass}") 68 } 69 70 for ((sink: CSREnumType, source: CSREnumType) <- this.getFields.zip(that.getFields)) { 71 if (sink.rfn == null) 72 sink := source // .factory.apply(sink.rfn(source.asUInt, Seq())) 73 else 74 sink := sink.factory(sink.rfn(source.asUInt, Seq())) 75 } 76 } 77 78 def getFields: Seq[CSREnumType] = this.getElements.map(_.asInstanceOf[CSREnumType]) 79 80 def needReset: Boolean = this.getFields.exists(_.needReset) 81 82 // used by event bundle to filter the fields need to update 83 def addInEvent(fieldFns: (this.type => CSREnumType)*): this.type = { 84 this.eventFields ++= fieldFns.map(fn => fn(this)) 85 this 86 } 87 88 override def cloneType: CSRBundle.this.type = { 89 val ret = super.cloneType 90 // 91 (ret.getFields zip this.getFields).foreach { case (l, r) => 92 if (this.eventFields.contains(r)) { 93 ret.eventFields += l 94 } 95 } 96 ret 97 } 98 99 def & (that: CSRBundle): UInt = { 100 this.asUInt & that.asUInt 101 } 102 103 def & (that: UInt): UInt = { 104 require(this.asUInt.getWidth == that.getWidth, 105 s"The width between left $this(${this.getWidth}) and right $that(${that.getWidth}) should be equal.") 106 this.asUInt & that 107 } 108 109 def | (that: CSRBundle): UInt = { 110 this.asUInt | that.asUInt 111 } 112 113 def | (that: UInt): UInt = { 114 require(this.getWidth == that.getWidth) 115 this.asUInt | that 116 } 117 118 def unary_~ : UInt = { 119 (~this.asUInt).asUInt 120 } 121 122 def apply(num: Int) : CSREnumType = { 123 this.getFields.find(x => x.lsb == num && x.msb == num).get 124 } 125 126 def apply(str: String) : CSREnumType = { 127 elements(str).asInstanceOf[CSREnumType] 128 } 129} 130 131object CSRBundleImplicitCast { 132 class UIntField(val value: UInt) { 133 def &[T <: CSRBundle] (field: T): UInt = { 134 this.value & field.asUInt 135 } 136 137 def |[T <: CSRBundle] (field: T): UInt = { 138 this.value | field.asUInt 139 } 140 141 def &>(that: Bool): UInt = { 142 require(value.widthKnown, "The width of the left operand should be known when using >& operator") 143 this.value & Fill(value.getWidth, that) 144 } 145 146 def |>(that: Bool): UInt = { 147 require(value.widthKnown, "The width of the left operand should be known when using >| operator") 148 this.value | Fill(value.getWidth, that) 149 } 150 } 151 152 import scala.language.implicitConversions 153 implicit def UIntToUIntField(uint: UInt): UIntField = new UIntField(uint) 154} 155 156object ChiselRecordForField { 157 implicit class AddRecordSpecifyFields[T <: Record](val x: T) { 158 def specifyField(elemFns: (T => Unit)*): Unit = { 159 elemFns.foreach(_.apply(x)) 160 } 161 } 162} 163