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