1039cdc35SXuan Hupackage xiangshan.backend.fu.NewCSR 2039cdc35SXuan Hu 3039cdc35SXuan Huimport chisel3._ 4039cdc35SXuan Huimport chisel3.experimental.SourceInfo 51d192ad8SXuan Huimport chisel3.util.{Cat, Fill} 6237d4cfdSXuan Huimport chisel3.experimental.BundleLiterals._ 7039cdc35SXuan Hu 8039cdc35SXuan Huimport scala.language.experimental.macros 9039cdc35SXuan Hu 10039cdc35SXuan Hu 11039cdc35SXuan Huabstract class CSRBundle extends Bundle { 12039cdc35SXuan Hu val len: Int = 64 13039cdc35SXuan Hu 14237d4cfdSXuan Hu var eventFields: Set[CSREnumType] = Set() 15237d4cfdSXuan Hu 16039cdc35SXuan Hu override def do_asUInt(implicit sourceInfo: SourceInfo): UInt = { 1738e7849bSXuan Hu // sorted from msb to lsb 1838e7849bSXuan Hu val fields = this.getFields.sortWith((l, r) => l.lsb > r.lsb) 19039cdc35SXuan Hu var paddedFields: Seq[Data] = Seq() 20039cdc35SXuan Hu var lsb = len 21039cdc35SXuan Hu 22039cdc35SXuan Hu for (field <- fields) { 23039cdc35SXuan Hu val diffWidth = lsb - field.lsb - field.getWidth 24039cdc35SXuan Hu if (diffWidth > 0) 25039cdc35SXuan Hu paddedFields :+= 0.U((diffWidth).W) 26039cdc35SXuan Hu paddedFields :+= field 27039cdc35SXuan Hu lsb = field.lsb 28039cdc35SXuan Hu } 29039cdc35SXuan Hu 30039cdc35SXuan Hu if (fields.last.lsb > 0) { 31039cdc35SXuan Hu paddedFields :+= 0.U(fields.last.lsb.W) 32039cdc35SXuan Hu } 33039cdc35SXuan Hu 34039cdc35SXuan Hu Cat(paddedFields.map(x => x.asUInt)) 35039cdc35SXuan Hu } 36039cdc35SXuan Hu 37039cdc35SXuan Hu def := (that: UInt): Unit = { 38039cdc35SXuan Hu val fields = this.getFields 39039cdc35SXuan Hu 409a28ebd4SXuan Hu suppressEnumCastWarning { 41039cdc35SXuan Hu for (field <- fields) { 42039cdc35SXuan Hu field := field.factory.apply(that(field.lsb + field.getWidth - 1, field.lsb)) 43039cdc35SXuan Hu } 44039cdc35SXuan Hu } 459a28ebd4SXuan Hu } 46039cdc35SXuan Hu 47039cdc35SXuan Hu @inline 48039cdc35SXuan Hu def init: this.type = { 49039cdc35SXuan Hu val init = Wire(this) 509a28ebd4SXuan Hu suppressEnumCastWarning { 51039cdc35SXuan Hu init.elements.foreach { case (str, field: CSREnumType) => 5201cdded8SXuan Hu field := (if (field.init != null) field.factory(field.init.asUInt) else field.factory(0.U)) 53039cdc35SXuan Hu } 549a28ebd4SXuan Hu } 55039cdc35SXuan Hu init.asInstanceOf[this.type] 56039cdc35SXuan Hu } 57039cdc35SXuan Hu 58039cdc35SXuan Hu /** 59039cdc35SXuan Hu * filtered read connection 60039cdc35SXuan Hu * 61039cdc35SXuan Hu * CSRBundle will be filtered by CSRFields' read filter function. 62039cdc35SXuan Hu */ 63039cdc35SXuan Hu def :|= [T <: CSRBundle](that: T): Unit = { 64039cdc35SXuan Hu if (this.getClass != that.getClass) { 65039cdc35SXuan Hu throw MonoConnectException(s"Type miss match! (sink :|= source) " + 66039cdc35SXuan Hu s"sink type: ${this.getClass}, " + 67039cdc35SXuan Hu s"source type: ${that.getClass}") 68039cdc35SXuan Hu } 69039cdc35SXuan Hu 70039cdc35SXuan Hu for ((sink: CSREnumType, source: CSREnumType) <- this.getFields.zip(that.getFields)) { 71039cdc35SXuan Hu if (sink.rfn == null) 72039cdc35SXuan Hu sink := source // .factory.apply(sink.rfn(source.asUInt, Seq())) 73039cdc35SXuan Hu else 74039cdc35SXuan Hu sink := sink.factory(sink.rfn(source.asUInt, Seq())) 75039cdc35SXuan Hu } 76039cdc35SXuan Hu } 77039cdc35SXuan Hu 78039cdc35SXuan Hu def getFields: Seq[CSREnumType] = this.getElements.map(_.asInstanceOf[CSREnumType]) 79039cdc35SXuan Hu 80039cdc35SXuan Hu def needReset: Boolean = this.getFields.exists(_.needReset) 81237d4cfdSXuan Hu 82237d4cfdSXuan Hu // used by event bundle to filter the fields need to update 83237d4cfdSXuan Hu def addInEvent(fieldFns: (this.type => CSREnumType)*): this.type = { 84237d4cfdSXuan Hu this.eventFields ++= fieldFns.map(fn => fn(this)) 85237d4cfdSXuan Hu this 86237d4cfdSXuan Hu } 87237d4cfdSXuan Hu 88237d4cfdSXuan Hu override def cloneType: CSRBundle.this.type = { 89237d4cfdSXuan Hu val ret = super.cloneType 90237d4cfdSXuan Hu // 91237d4cfdSXuan Hu (ret.getFields zip this.getFields).foreach { case (l, r) => 92237d4cfdSXuan Hu if (this.eventFields.contains(r)) { 93237d4cfdSXuan Hu ret.eventFields += l 94237d4cfdSXuan Hu } 95237d4cfdSXuan Hu } 96237d4cfdSXuan Hu ret 97237d4cfdSXuan Hu } 981d192ad8SXuan Hu 991d192ad8SXuan Hu def & (that: CSRBundle): UInt = { 1001d192ad8SXuan Hu this.asUInt & that.asUInt 1011d192ad8SXuan Hu } 1021d192ad8SXuan Hu 1031d192ad8SXuan Hu def & (that: UInt): UInt = { 1041d192ad8SXuan Hu require(this.asUInt.getWidth == that.getWidth, 1051d192ad8SXuan Hu s"The width between left $this(${this.getWidth}) and right $that(${that.getWidth}) should be equal.") 1061d192ad8SXuan Hu this.asUInt & that 1071d192ad8SXuan Hu } 1081d192ad8SXuan Hu 1091d192ad8SXuan Hu def | (that: CSRBundle): UInt = { 1101d192ad8SXuan Hu this.asUInt | that.asUInt 1111d192ad8SXuan Hu } 1121d192ad8SXuan Hu 1131d192ad8SXuan Hu def | (that: UInt): UInt = { 1141d192ad8SXuan Hu require(this.getWidth == that.getWidth) 1151d192ad8SXuan Hu this.asUInt | that 1161d192ad8SXuan Hu } 1171d192ad8SXuan Hu 1181d192ad8SXuan Hu def unary_~ : UInt = { 1191d192ad8SXuan Hu (~this.asUInt).asUInt 1201d192ad8SXuan Hu } 1211d192ad8SXuan Hu 1221d192ad8SXuan Hu def apply(num: Int) : CSREnumType = { 1231d192ad8SXuan Hu this.getFields.find(x => x.lsb == num && x.msb == num).get 1241d192ad8SXuan Hu } 1251d192ad8SXuan Hu 1261d192ad8SXuan Hu def apply(str: String) : CSREnumType = { 1271d192ad8SXuan Hu elements(str).asInstanceOf[CSREnumType] 1281d192ad8SXuan Hu } 1291d192ad8SXuan Hu} 1301d192ad8SXuan Hu 1311d192ad8SXuan Huobject CSRBundleImplicitCast { 1321d192ad8SXuan Hu class UIntField(val value: UInt) { 1331d192ad8SXuan Hu def &[T <: CSRBundle] (field: T): UInt = { 1341d192ad8SXuan Hu this.value & field.asUInt 1351d192ad8SXuan Hu } 1361d192ad8SXuan Hu 1371d192ad8SXuan Hu def |[T <: CSRBundle] (field: T): UInt = { 1381d192ad8SXuan Hu this.value | field.asUInt 1391d192ad8SXuan Hu } 1401d192ad8SXuan Hu 1411d192ad8SXuan Hu def &>(that: Bool): UInt = { 1421d192ad8SXuan Hu require(value.widthKnown, "The width of the left operand should be known when using >& operator") 1431d192ad8SXuan Hu this.value & Fill(value.getWidth, that) 1441d192ad8SXuan Hu } 1451d192ad8SXuan Hu 1461d192ad8SXuan Hu def |>(that: Bool): UInt = { 1471d192ad8SXuan Hu require(value.widthKnown, "The width of the left operand should be known when using >| operator") 1481d192ad8SXuan Hu this.value | Fill(value.getWidth, that) 1491d192ad8SXuan Hu } 1501d192ad8SXuan Hu } 1511d192ad8SXuan Hu 152*e3da8badSTang Haojin import scala.language.implicitConversions 1531d192ad8SXuan Hu implicit def UIntToUIntField(uint: UInt): UIntField = new UIntField(uint) 1541d192ad8SXuan Hu} 1551d192ad8SXuan Hu 1561d192ad8SXuan Huobject ChiselRecordForField { 1571d192ad8SXuan Hu implicit class AddRecordSpecifyFields[T <: Record](val x: T) { 1581d192ad8SXuan Hu def specifyField(elemFns: (T => Unit)*): Unit = { 1591d192ad8SXuan Hu elemFns.foreach(_.apply(x)) 1601d192ad8SXuan Hu } 1611d192ad8SXuan Hu } 162039cdc35SXuan Hu} 163