1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4 5import xiangshan.backend.fu.NewCSR.CSRFunc._ 6 7import scala.language.experimental.macros 8 9abstract class CSRRWType { 10 val wfn: CSRWfnType 11 val rfn: CSRRfnType 12 val ref: Option[CSREnumType] = None 13 14 def isRO: Boolean = this.isInstanceOf[ROType] || this.isInstanceOf[RefROType] 15 16 def isRW: Boolean = this.isInstanceOf[RWType] || this.isInstanceOf[RefRWType] 17 18 def isWARL: Boolean = this.isInstanceOf[WARLType] || this.isInstanceOf[RefWARLType] 19 20 def isWLRL: Boolean = this.isInstanceOf[WLRLType] || this.isInstanceOf[RefWLRLType] 21 22 def isRef: Boolean = this.isInstanceOf[RefROType] || this.isInstanceOf[RefRWType] || this.isInstanceOf[RefWARLType] || 23 this.isInstanceOf[RefWLRLType] 24 25 override def toString: String = { 26 val typeString = this match { 27 case WARLType(_, _) => "WARL" 28 case ROType(_) => "RO" 29 case WLRLType(_, _) => "WLRL" 30 case RWType() => "RW" 31 } 32 typeString + (if (isRef) " Ref" else "") 33 } 34} 35 36case class WARLType( 37 override val wfn: CSRWfnType, 38 override val rfn: CSRRfnType = null, 39) extends CSRRWType 40 41case class ROType( 42 override val rfn: CSRRfnType = null, 43) extends CSRRWType { 44 override final val wfn: CSRWfnType = wNoEffect 45} 46 47case class WLRLType( 48 override val wfn: CSRWfnType, 49 override val rfn: CSRRfnType, 50) extends CSRRWType 51 52case class RWType() extends CSRRWType { 53 override final val wfn: CSRWfnType = wNoFilter 54 override final val rfn: CSRRfnType = null 55} 56 57trait CheckRef { self: CSRRWType => 58 require(ref.nonEmpty) 59} 60 61case class RefWARLType( 62 override val ref: Option[CSREnumType], 63 override val wfn: CSRWfnType, 64 override val rfn: CSRRfnType = null, 65) extends CSRRWType with CheckRef 66 67case class RefROType( 68 override val ref: Option[CSREnumType], 69 override val rfn: CSRRfnType = null, 70) extends CSRRWType with CheckRef { 71 override final val wfn: CSRWfnType = wNoEffect 72} 73 74case class RefWLRLType( 75 override val ref: Option[CSREnumType], 76 override val wfn: CSRWfnType, 77 override val rfn: CSRRfnType, 78) extends CSRRWType with CheckRef 79 80case class RefRWType( 81 override val ref: Option[CSREnumType], 82) extends CSRRWType with CheckRef { 83 override final val wfn: CSRWfnType = wNoFilter 84 override final val rfn: CSRRfnType = null 85} 86 87object CSRFunc { 88 type CSRWfnType = (UInt, UInt, Seq[Data]) => UInt 89 90 def wNoFilter: CSRWfnType = 91 (newV: UInt, oldV: UInt, _: Seq[Data]) => newV 92 93 def wNoEffectWhen(keepCond: UInt => Bool): CSRWfnType = 94 (newV: UInt, oldV: UInt, _: Seq[Data]) => { 95 Mux(keepCond(newV), oldV, newV) 96 } 97 98 def wNoEffect: CSRWfnType = 99 (_: UInt, oldV: UInt, _: Seq[Data]) => { oldV } 100 101 type CSRRfnType = (UInt, Seq[Data]) => UInt 102 103 def rNoFilter: CSRRfnType = null 104 105 def rWithFilter(rFilter: (UInt, Seq[Data]) => UInt): CSRRfnType = 106 (oriV: UInt, seq: Seq[Data]) => rFilter(oriV, seq) 107 108 def rFixValue(value: UInt): CSRRfnType = { 109 (_, _) => value 110 } 111} 112 113class CSREnumType( 114 val msb: Int, 115 val lsb: Int, 116)( 117 var rwType: CSRRWType, 118)( 119 override val factory: ChiselEnum 120) extends EnumType(factory) { 121 var init: Option[EnumType] = None 122 123 if (factory.all.size == 0) { 124 factory.asInstanceOf[CSREnum].addMinValue 125 } 126 127 if (!factory.all.exists(_.litValue == ((BigInt(1) << (msb - lsb + 1)) - 1))) { 128 factory.asInstanceOf[CSREnum].addMaxValue 129 } 130 131 if (msb - lsb + 1 > this.getWidth) 132 println( 133 s"[CSRInfo] $this: " + 134 s"the setting range($msb, $lsb) of bitfield is widen than EnumType's width(${this.getWidth}), " + 135 s"the higher bits will be optimized" 136 ) 137 138 def isRef = this.rwType.isRef 139 140 def isRO = this.rwType.isRO 141 142 def isWARL = this.rwType.isWARL 143 144 // Check if the write data is legal that can update the regfield. 145 // Also check if the write field is not Read Only. 146 def isLegal: Bool = this.factory.asInstanceOf[CSREnum].isLegal(this) && (!this.isRO).B 147 148 def needReset: Boolean = init.nonEmpty 149 150 def rfn: CSRRfnType = rwType.rfn 151 152 def wfn: CSRWfnType = rwType.wfn 153 154 protected def resetCheck: Unit = { 155 rwType match { 156 case ROType(rfn) => require(rfn == null) 157 case _ => 158 } 159 } 160 161 def withReset[T <: EnumType](init: T): this.type = { 162 resetCheck 163 this.init = Some(init) 164 this 165 } 166 167 def withReset(init: UInt): this.type = { 168 resetCheck 169 this.init = Some(this.factory(init)) 170 this 171 } 172 173 def := (that: UInt): Unit = { 174 this := this.factory(that) 175 } 176 177 def dumpName = { 178 s"${chisel3.reflect.DataMirror.queryNameGuess(this)} ${rwType} [$msb, $lsb] reset($init)" 179 } 180 181 def asBool: Bool = { 182 this.asUInt.asBool 183 } 184 185 private def setRwType(newType: CSRRWType): this.type = { 186 this.rwType = newType 187 this 188 } 189 190 def setRO(rfn: CSRRfnType = null): this.type = { 191 this.setRwType(ROType(rfn)) 192 } 193 194 def setRW(): this.type = { 195 this.setRwType(RWType()) 196 } 197 198 def setWARL(wfn: CSRWfnType): this.type = { 199 this.setRwType(WARLType(wfn)) 200 } 201 202 // override cloneType to make ValidIO etc function return CSREnumType not EnumType 203 override def cloneType: this.type = factory.asInstanceOf[CSREnum].makeType.asInstanceOf[this.type] 204} 205 206abstract class CSREnum extends ChiselEnum { 207 type Type = CSREnumType 208 209 protected def apply(rwType: CSRRWType)(msb: Int, lsb: Int)(factory: ChiselEnum): CSREnumType = { 210 this.msb = msb 211 this.lsb = lsb 212 new CSREnumType(msb, lsb)(rwType)(factory) 213 } 214 215 var msb, lsb: Int = 0 216 217 def makeType: Type = { 218 new CSREnumType(msb, lsb)(RWType())(this) 219 } 220 221 /** 222 * Used to allow 0.U.asTypeOf(CSREnumInstance) convertion 223 */ 224 def addMinValue: Unit = { 225 Value(0.U) 226 } 227 228 /** 229 * A trick to expand the width of Enum to (msb - lsb + 1) 230 */ 231 def addMaxValue: Unit = { 232 Value(((BigInt(1) << (msb - lsb + 1)) - 1).U) 233 } 234 235 def isLegal(enum: CSREnumType): Bool = true.B 236 237 println(s"A new CSREnum is created, factory: $this") 238} 239 240trait CSRROApply { self: CSREnum => 241 def apply(msb: Int, lsb: Int): CSREnumType = self 242 .apply(ROType())(msb, lsb)(this) 243} 244 245trait CSRRWApply { self: CSREnum => 246 def apply(msb: Int, lsb: Int): CSREnumType = self 247 .apply(RWType())(msb, lsb)(this) 248} 249 250trait CSRWARLApply { self: CSREnum => 251 def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 252 .apply(WARLType(wfn, rfn))(msb, lsb)(this) 253 254 def apply(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self 255 .apply(WARLType(wfn))(msb, lsb)(this) 256} 257 258trait CSRWLRLApply { self: CSREnum => 259 def apply(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 260 .apply(WLRLType(wfn, rfn))(msb, lsb)(this) 261} 262 263trait CSRMacroApply { self: CSREnum => 264 def RO(msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self 265 .apply(ROType(rfn))(msb, lsb)(this) 266 267 def RO(msb: Int, lsb: Int): CSREnumType = self 268 .apply(ROType())(msb, lsb)(this) 269 270 def RW(msb: Int, lsb: Int): CSREnumType = self 271 .apply(RWType())(msb, lsb)(this) 272 273 def WARL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 274 .apply(WARLType(wfn, rfn))(msb, lsb)(this) 275 276 def WARL(msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self 277 .apply(WARLType(wfn))(msb, lsb)(this) 278 279 def WLRL(msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 280 .apply(WLRLType(wfn, rfn))(msb, lsb)(this) 281 282 def RefRO(ref: CSREnumType, msb: Int, lsb: Int, rfn: CSRRfnType): CSREnumType = self 283 .apply(RefROType(Some(ref) ,rfn))(msb, lsb)(ref.factory) 284 285 def RefRO(ref: CSREnumType, msb: Int, lsb: Int): CSREnumType = self 286 .apply(RefROType(Some(ref)))(msb, lsb)(ref.factory) 287 288 def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType, rfn: CSRRfnType): CSREnumType = self 289 .apply(RefWARLType(Some(ref), wfn, rfn))(msb, lsb)(ref.factory) 290 291 def RefWARL(ref: CSREnumType, msb: Int, lsb: Int, wfn: CSRWfnType): CSREnumType = self 292 .apply(RefWARLType(Some(ref), wfn))(msb, lsb)(ref.factory) 293} 294 295object CSREnumTypeImplicitCast { 296 implicit def CSREnumTypeToUInt(field: CSREnumType): UInt = { 297 field.asUInt 298 } 299 300 class BoolField(val value: Bool) { 301 def && (field: CSREnumType): Bool = { 302 this.value && field.asBool 303 } 304 305 def || (field: CSREnumType): Bool = { 306 this.value || field.asBool 307 } 308 } 309 310 implicit def BoolToBoolField(bool: Bool): BoolField = new BoolField(bool) 311} 312 313