1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import freechips.rocketchip.rocket.CSRs 6import CSRConfig._ 7import xiangshan.backend.fu.NewCSR.CSRBundles.PrivState 8import xiangshan.backend.fu.NewCSR.CSRConfig._ 9import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _} 10 11import scala.collection.immutable.SeqMap 12 13trait CSRAIA { self: NewCSR with HypervisorLevel => 14 val miselect = Module(new CSRModule("Miselect", new MISelectBundle) with HasISelectBundle { 15 private val value = reg.ALL.asUInt 16 inIMSICRange := value >= 0x70.U && value < 0x100.U && value(0) =/= 1.U 17 isIllegal := 18 value < 0x30.U || 19 value >= 0x40.U && value < 0x70.U || 20 value >= 0x100.U || 21 value(0) === 1.U 22 }) 23 .setAddr(CSRs.miselect) 24 25 val mireg = Module(new CSRModule("Mireg") with HasIregSink { 26 rdata := iregRead.mireg 27 }) 28 .setAddr(CSRs.mireg) 29 30 val mtopei = Module(new CSRModule("Mtopei", new TopEIBundle) with HasAIABundle { 31 regOut := aiaToCSR.mtopei 32 }) 33 .setAddr(CSRs.mtopei) 34 35 val mtopi = Module(new CSRModule("Mtopi", new TopIBundle) with HasInterruptFilterSink { 36 regOut.IID := topIR.mtopi.IID 37 regOut.IPRIO := topIR.mtopi.IPRIO 38 }) 39 .setAddr(CSRs.mtopi) 40 41 val siselect = Module(new CSRModule("Siselect", new SISelectBundle) with HasISelectBundle { 42 private val value = reg.ALL.asUInt 43 inIMSICRange := value >= 0x70.U && value < 0x100.U && value(0) =/= 1.U 44 isIllegal := 45 value < 0x30.U || 46 value >= 0x40.U && value < 0x70.U || 47 value >= 0x100.U || 48 value(0) === 1.U 49 }) 50 .setAddr(CSRs.siselect) 51 52 val sireg = Module(new CSRModule("Sireg") with HasIregSink { 53 rdata := iregRead.sireg 54 }) 55 .setAddr(CSRs.sireg) 56 57 val stopei = Module(new CSRModule("Stopei", new TopEIBundle) with HasAIABundle { 58 regOut := aiaToCSR.stopei 59 }) 60 .setAddr(CSRs.stopei) 61 62 val stopi = Module(new CSRModule("Stopi", new TopIBundle) with HasInterruptFilterSink { 63 regOut.IID := topIR.stopi.IID 64 regOut.IPRIO := topIR.stopi.IPRIO 65 }) 66 .setAddr(CSRs.stopi) 67 68 val vsiselect = Module(new CSRModule("VSiselect", new VSISelectBundle) with HasISelectBundle { 69 private val value = reg.ALL.asUInt 70 inIMSICRange := value >= 0x70.U && value < 0x100.U && value(0) =/= 1.U 71 isIllegal := 72 value < 0x70.U || 73 value >= 0x100.U || 74 value(0) === 1.U 75 }) 76 .setAddr(CSRs.vsiselect) 77 78 val vsireg = Module(new CSRModule("VSireg") with HasIregSink { 79 rdata := iregRead.sireg 80 }) 81 .setAddr(CSRs.vsireg) 82 83 val vstopei = Module(new CSRModule("VStopei", new TopEIBundle) with HasAIABundle { 84 regOut := aiaToCSR.vstopei 85 }) 86 .setAddr(CSRs.vstopei) 87 88 val vstopi = Module(new CSRModule("VStopi", new TopIBundle) with HasInterruptFilterSink { 89 regOut.IID := topIR.vstopi.IID 90 regOut.IPRIO := topIR.vstopi.IPRIO 91 }) 92 .setAddr(CSRs.vstopi) 93 94 val miprio0 = Module(new CSRModule(s"Iprio0", new Iprio0Bundle)) 95 .setAddr(0x30) 96 97 val miprio2 = Module(new CSRModule(s"Iprio2", new Iprio2Bundle)) 98 .setAddr(0x32) 99 100 val miprio4 = Module(new CSRModule(s"Iprio4", new IprioBundle)) 101 .setAddr(0x34) 102 103 val miprio6 = Module(new CSRModule(s"Iprio6", new IprioBundle)) 104 .setAddr(0x36) 105 106 val miprio8 = Module(new CSRModule(s"Iprio8", new Iprio8Bundle)) 107 .setAddr(0x38) 108 109 val miprio10 = Module(new CSRModule(s"Iprio10", new Iprio10Bundle)) 110 .setAddr(0x3A) 111 112 val miprio12 = Module(new CSRModule(s"Iprio12", new IprioBundle)) 113 .setAddr(0x3C) 114 115 val miprio14 = Module(new CSRModule(s"Iprio14", new IprioBundle)) 116 .setAddr(0x3E) 117 118 val siprio0 = Module(new CSRModule(s"Iprio0", new Iprio0Bundle)) 119 .setAddr(0x30) 120 121 val siprio2 = Module(new CSRModule(s"Iprio2", new Iprio2Bundle)) 122 .setAddr(0x32) 123 124 val siprio4 = Module(new CSRModule(s"Iprio4", new IprioBundle)) 125 .setAddr(0x34) 126 127 val siprio6 = Module(new CSRModule(s"Iprio6", new IprioBundle)) 128 .setAddr(0x36) 129 130 val siprio8 = Module(new CSRModule(s"Iprio8", new Iprio8Bundle)) 131 .setAddr(0x38) 132 133 val siprio10 = Module(new CSRModule(s"Iprio10", new Iprio10Bundle)) 134 .setAddr(0x3A) 135 136 val siprio12 = Module(new CSRModule(s"Iprio12", new IprioBundle)) 137 .setAddr(0x3C) 138 139 val siprio14 = Module(new CSRModule(s"Iprio14", new IprioBundle)) 140 .setAddr(0x3E) 141 142 val miregiprios: Seq[CSRModule[_]] = Seq(miprio0, miprio2, miprio4, miprio6, miprio8, miprio10, miprio12, miprio14) 143 144 val siregiprios: Seq[CSRModule[_]] = Seq(siprio0, siprio2, siprio4, siprio6, siprio8, siprio10, siprio12, siprio14) 145 146 val aiaCSRMods = Seq( 147 miselect, 148 mireg, 149 mtopei, 150 mtopi, 151 siselect, 152 sireg, 153 stopei, 154 stopi, 155 vsiselect, 156 vsireg, 157 vstopi, 158 vstopei, 159 ) 160 161 val aiaSkipCSRs = Seq( 162 mtopei, 163 mtopi, 164 stopei, 165 stopi, 166 vstopi, 167 vstopei, 168 ) 169 170 val aiaCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 171 aiaCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 172 ) 173 174 val aiaCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 175 aiaCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 176 ) 177 178 private val miregRData: UInt = Mux1H( 179 miregiprios.map(prio => (miselect.rdata.asUInt === prio.addr.U) -> prio.rdata) 180 ) 181 182 private val siregRData: UInt = Mux1H( 183 siregiprios.map(prio => (siselect.rdata.asUInt === prio.addr.U) -> prio.rdata) 184 ) 185 186 aiaCSRMods.foreach { mod => 187 mod match { 188 case m: HasIregSink => 189 m.iregRead.mireg := miregRData 190 m.iregRead.sireg := siregRData 191 m.iregRead.vsireg := 0.U // Todo: IMSIC 192 case _ => 193 } 194 } 195} 196 197class ISelectField(final val maxValue: Int, reserved: Seq[Range]) extends CSREnum with WARLApply { 198 override def isLegal(enumeration: CSREnumType): Bool = enumeration.asUInt <= maxValue.U 199} 200 201object VSISelectField extends ISelectField( 202 0x1FF, 203 reserved = Seq( 204 Range.inclusive(0x000, 0x02F), 205 Range.inclusive(0x040, 0x06F), 206 Range.inclusive(0x100, 0x1FF), 207 ), 208) 209 210object MISelectField extends ISelectField( 211 maxValue = 0xFF, 212 reserved = Seq( 213 Range.inclusive(0x00, 0x2F), 214 Range.inclusive(0x40, 0x6F), 215 ), 216) 217 218object SISelectField extends ISelectField( 219 maxValue = 0xFF, 220 reserved = Seq( 221 Range.inclusive(0x00, 0x2F), 222 Range.inclusive(0x40, 0x6F), 223 ), 224) 225 226class VSISelectBundle extends CSRBundle { 227 val ALL = VSISelectField(log2Up(0x1FF), 0, null) 228} 229 230class MISelectBundle extends CSRBundle { 231 val ALL = MISelectField(log2Up(0xFF), 0, null) 232} 233 234class SISelectBundle extends CSRBundle { 235 val ALL = SISelectField(log2Up(0xFF), 0, null) 236} 237 238class TopIBundle extends CSRBundle { 239 val IID = RO(27, 16) 240 val IPRIO = RO(7, 0) 241} 242 243class TopEIBundle extends CSRBundle { 244 val IID = RW(26, 16) 245 val IPRIO = RW(10, 0) 246} 247 248class IprioBundle extends CSRBundle { 249 val ALL = RO(63, 0).withReset(0.U) 250} 251 252class Iprio0Bundle extends CSRBundle { 253 val PrioSSI = RW(15, 8).withReset(0.U) 254 val PrioVSSI = RW(23, 16).withReset(0.U) 255 val PrioMSI = RW(31, 24).withReset(0.U) 256 val PrioSTI = RW(47, 40).withReset(0.U) 257 val PrioVSTI = RW(55, 48).withReset(0.U) 258 val PrioMTI = RW(63, 56).withReset(0.U) 259} 260 261class Iprio2Bundle extends CSRBundle { 262 val PrioSEI = RW(15, 8).withReset(0.U) 263 val PrioVSEI = RW(23, 16).withReset(0.U) 264 val PrioMEI = RW(31, 24).withReset(0.U) 265 val PrioSGEI = RW(39, 32).withReset(0.U) 266 val PrioCOI = RW(47, 40).withReset(0.U) 267} 268 269class Iprio8Bundle extends CSRBundle { 270 val PrioLPRASEI = RW(31, 24).withReset(0.U) 271} 272 273class Iprio10Bundle extends CSRBundle { 274 val PrioHPRASEI = RW(31, 24).withReset(0.U) 275} 276 277class CSRToAIABundle extends Bundle { 278 private final val AddrWidth = 12 279 280 val addr = ValidIO(new Bundle { 281 val addr = UInt(AddrWidth.W) 282 val v = VirtMode() 283 val prvm = PrivMode() 284 }) 285 286 val vgein = UInt(VGEINWidth.W) 287 288 val wdata = ValidIO(new Bundle { 289 val op = UInt(2.W) 290 val data = UInt(XLEN.W) 291 }) 292 293 val mClaim = Bool() 294 val sClaim = Bool() 295 val vsClaim = Bool() 296} 297 298class AIAToCSRBundle extends Bundle { 299 private val NumVSIRFiles = 63 300 val rdata = ValidIO(new Bundle { 301 val data = UInt(XLEN.W) 302 val illegal = Bool() 303 }) 304 val meip = Bool() 305 val seip = Bool() 306 val vseip = UInt(NumVSIRFiles.W) 307 val mtopei = new TopEIBundle 308 val stopei = new TopEIBundle 309 val vstopei = new TopEIBundle 310} 311 312trait HasAIABundle { self: CSRModule[_] => 313 val aiaToCSR = IO(Input(new AIAToCSRBundle)) 314} 315 316trait HasInterruptFilterSink { self: CSRModule[_] => 317 val topIR = IO(new Bundle { 318 val mtopi = Input(new TopIBundle) 319 val stopi = Input(new TopIBundle) 320 val vstopi = Input(new TopIBundle) 321 }) 322} 323 324trait HasISelectBundle { self: CSRModule[_] => 325 val inIMSICRange = IO(Output(Bool())) 326 val isIllegal = IO(Output(Bool())) 327} 328 329trait HasIregSink { self: CSRModule[_] => 330 val iregRead = IO(Input(new Bundle { 331 val mireg = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width 332 val sireg = UInt(XLEN.W) 333 val vsireg = UInt(XLEN.W) 334 })) 335} 336