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