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