1package xiangshan.backend.fu.NewCSR 2 3import chisel3._ 4import chisel3.util._ 5import org.chipsalliance.cde.config.Parameters 6import freechips.rocketchip.rocket.CSRs 7import utility.SignExt 8import utils.PerfEvent 9import xiangshan.backend.fu.NewCSR.CSRBundles._ 10import xiangshan.backend.fu.NewCSR.CSRDefines._ 11import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _} 12import xiangshan.backend.fu.NewCSR.CSREvents._ 13import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._ 14import xiangshan.backend.fu.NewCSR.ChiselRecordForField._ 15import xiangshan.backend.fu.PerfCounterIO 16import xiangshan.backend.fu.NewCSR.CSRConfig._ 17 18import scala.collection.immutable.SeqMap 19 20trait MachineLevel { self: NewCSR => 21 val mstatus = Module(new MstatusModule) 22 .setAddr(CSRs.mstatus) 23 24 val misa = Module(new CSRModule("Misa", new MisaBundle)) 25 .setAddr(CSRs.misa) 26 27 println(s"[CSR] supported isa ext: ${misa.bundle.getISAString}") 28 29 val medeleg = Module(new CSRModule("Medeleg", new MedelegBundle)) 30 .setAddr(CSRs.medeleg) 31 32 val mideleg = Module(new CSRModule("Mideleg", new MidelegBundle)) 33 .setAddr(CSRs.mideleg) 34 35 val mie = Module(new CSRModule("Mie", new MieBundle) with HasIpIeBundle { 36 val fromHie = IO(Flipped(new HieToMie)) 37 val fromSie = IO(Flipped(new SieToMie)) 38 val fromVSie = IO(Flipped(new VSieToMie)) 39 40 // bit 1 SSIE 41 when (fromSie.SSIE.valid) { 42 reg.SSIE := fromSie.SSIE.bits 43 } 44 45 // bit 2 VSSIE 46 when (fromHie.VSSIE.valid || fromVSie.VSSIE.valid) { 47 reg.VSSIE := Mux1H(Seq( 48 fromHie .VSSIE.valid -> fromHie .VSSIE.bits, 49 fromVSie.VSSIE.valid -> fromVSie.VSSIE.bits, 50 )) 51 } 52 53 // bit 5 STIE 54 when(fromSie.STIE.valid) { 55 reg.STIE := fromSie.STIE.bits 56 } 57 58 // bit 6 VSTIE 59 when(fromHie.VSTIE.valid || fromVSie.VSTIE.valid) { 60 reg.VSTIE := Mux1H(Seq( 61 fromHie .VSTIE.valid -> fromHie .VSTIE.bits, 62 fromVSie.VSTIE.valid -> fromVSie.VSTIE.bits, 63 )) 64 } 65 66 // bit 9 SEIE 67 when(fromSie.SEIE.valid) { 68 reg.SEIE := fromSie.SEIE.bits 69 } 70 71 // bit 10 VSEIE 72 when(fromHie.VSEIE.valid || fromVSie.VSEIE.valid) { 73 reg.VSEIE := Mux1H(Seq( 74 fromHie .VSEIE.valid -> fromHie .VSEIE.bits, 75 fromVSie.VSEIE.valid -> fromVSie.VSEIE.bits, 76 )) 77 } 78 79 // bit 12 SGEIE 80 when(fromHie.SGEIE.valid) { 81 reg.SGEIE := fromHie.SGEIE.bits 82 } 83 84 // bit 13~63 LCIP 85 reg.getLocal lazyZip fromSie.getLocal lazyZip fromVSie.getLocal foreach { case (rLCIE, sieLCIE, vsieLCIE) => 86 when (sieLCIE.valid || vsieLCIE.valid) { 87 rLCIE := Mux1H(Seq( 88 sieLCIE .valid -> sieLCIE .bits, 89 vsieLCIE.valid -> vsieLCIE.bits, 90 )) 91 } 92 } 93 94 // 14~63 read only 0 95 regOut.getLocal.filterNot(_.lsb == InterruptNO.COI).foreach(_ := 0.U) 96 }).setAddr(CSRs.mie) 97 98 val mtvec = Module(new CSRModule("Mtvec", new XtvecBundle)) 99 .setAddr(CSRs.mtvec) 100 101 // Todo: support "Stimecmp/Vstimecmp" Extension, Version 1.0.0 102 // Todo: support Sscounterenw Extension 103 val mcounteren = Module(new CSRModule("Mcounteren", new Counteren)) 104 .setAddr(CSRs.mcounteren) 105 106 val mvien = Module(new CSRModule("Mvien", new MvienBundle)) 107 .setAddr(CSRs.mvien) 108 109 val mvip = Module(new CSRModule("Mvip", new MvipBundle) 110 with HasIpIeBundle 111 with HasMachineEnvBundle 112 { 113 val toMip = IO(new MvipToMip).connectZeroNonRW 114 val fromMip = IO(Flipped(new MipToMvip)) 115 val fromSip = IO(Flipped(new SipToMvip)) 116 val fromVSip = IO(Flipped(new VSipToMvip)) 117 118 // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip. 119 // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP. 120 // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED. 121 // XiangShan will keep the value in mvip.SSIP when mvien.SSIE is changed from zero to one 122 reg.SSIP := Mux(wen && mvien.SSIE.asBool, wdata.SSIP, reg.SSIP) 123 regOut.SSIP := Mux(mvien.SSIE.asBool, reg.SSIP, mip.SSIP) 124 toMip.SSIP.valid := wen && !mvien.SSIE.asBool 125 toMip.SSIP.bits := wdata.SSIP 126 127 // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip. 128 // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero. 129 // Todo: check mip writable when menvcfg.STCE = 1 130 regOut.STIP := Mux(this.menvcfg.STCE.asBool, 0.U, mip.STIP.asBool) 131 // Don't update mip.STIP when menvcfg.STCE is 1 132 toMip.STIP.valid := wen && !this.menvcfg.STCE.asBool 133 toMip.STIP.bits := wdata.STIP 134 135 // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP). 136 // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP. 137 // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip. 138 toMip.SEIP.valid := wen && !mvien.SEIE.asUInt.asBool 139 toMip.SEIP.bits := wdata.SEIP 140 when (fromMip.SEIP.valid) { 141 reg.SEIP := fromMip.SEIP.bits 142 } 143 144 // write from sip 145 when (fromSip.SSIP.valid) { 146 reg.SSIP := fromSip.SSIP.bits 147 } 148 149 reg.getLocal lazyZip fromSip.getLocal lazyZip fromVSip.getLocal foreach { case (rLCIP, sipLCIP, vsipLCIP) => 150 // sip should assert valid when mideleg=0 && mvien=1 151 when (sipLCIP.valid || vsipLCIP.valid) { 152 rLCIP := Mux1H(Seq( 153 sipLCIP .valid -> sipLCIP .bits, 154 vsipLCIP.valid -> vsipLCIP.bits, 155 )) 156 } 157 } 158 }).setAddr(CSRs.mvip) 159 160 val menvcfg = Module(new CSRModule("Menvcfg", new MEnvCfg)) 161 .setAddr(CSRs.menvcfg) 162 163 val mcountinhibit = Module(new CSRModule("Mcountinhibit", new McountinhibitBundle)) 164 .setAddr(CSRs.mcountinhibit) 165 166 val mhpmevents: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 167 Module(new CSRModule(s"Mhpmevent$num") with HasPerfEventBundle { 168 regOut := perfEvents(num - 3) 169 }) 170 .setAddr(CSRs.mhpmevent3 - 3 + num) 171 ) 172 173 val mscratch = Module(new CSRModule("Mscratch")) 174 .setAddr(CSRs.mscratch) 175 176 val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle { 177 rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN) 178 }) 179 .setAddr(CSRs.mepc) 180 181 val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle) 182 .setAddr(CSRs.mcause) 183 184 val mtval = Module(new CSRModule("Mtval") with TrapEntryMEventSinkBundle) 185 .setAddr(CSRs.mtval) 186 187 val mip = Module(new CSRModule("Mip", new MipBundle) 188 with HasIpIeBundle 189 with HasExternalInterruptBundle 190 with HasMachineEnvBundle 191 { 192 // Alias write in 193 val fromMvip = IO(Flipped(new MvipToMip)) 194 val fromSip = IO(Flipped(new SipToMip)) 195 val fromVSip = IO(Flipped(new VSipToMip)) 196 // Alias write out 197 val toMvip = IO(new MipToMvip).connectZeroNonRW 198 val toHvip = IO(new MipToHvip).connectZeroNonRW 199 200 // bit 1 SSIP 201 when (fromMvip.SSIP.valid || fromSip.SSIP.valid) { 202 reg.SSIP := Mux1H(Seq( 203 fromMvip.SSIP.valid -> fromMvip.SSIP.bits, 204 fromSip .SSIP.valid -> fromSip .SSIP.bits, 205 )) 206 } 207 208 // bit 2 VSSIP reg in hvip 209 // alias of hvip.VSSIP 210 toHvip.VSSIP.valid := wen 211 toHvip.VSSIP.bits := wdata.VSSIP 212 regOut.VSSIP := hvip.VSSIP 213 214 // bit 3 MSIP is read-only in mip, and is written by accesses to memory-mapped control registers, 215 // which are used by remote harts to provide machine-level interprocessor interrupts. 216 regOut.MSIP := platformIRP.MSIP 217 218 // bit 5 STIP 219 // If the stimecmp (supervisor-mode timer compare) register is implemented(menvcfg.STCE=1), STIP is read-only in mip. 220 regOut.STIP := Mux(this.menvcfg.STCE.asBool, platformIRP.STIP, reg.STIP.asBool) 221 when ((wen || fromMvip.STIP.valid) && !this.menvcfg.STCE) { 222 reg.STIP := Mux1H(Seq( 223 wen -> wdata.STIP, 224 fromMvip.STIP.valid -> fromMvip.STIP.bits, 225 )) 226 } 227 228 // bit 6 VSTIP 229 regOut.VSTIP := hvip.VSTIP || platformIRP.VSTIP 230 231 // bit 7 MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register 232 regOut.MTIP := platformIRP.MTIP 233 234 // bit 9 SEIP 235 // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP. 236 // when bit 9 of mvien is one, bit SEIP in mip is read-only and does not include the value of bit 9 of mvip. 237 // 238 // As explained in this issue(https://github.com/riscv/riscv-aia/issues/64), 239 // when mvien[9]=0, mip.SEIP is a software-writable bit and is special in its read value, which is the logical-OR of 240 // mip.SEIP reg and other source from the interrupt controller. 241 // mvip.SEIP is alias of mip.SEIP's reg part, and is independent of the other source from the interrupt controller. 242 // 243 // mip.SEIP is implemented as the alias of mvip.SEIP when mvien=0 244 // the read valid of SEIP is ORed by mvip.SEIP and the other source from the interrupt controller. 245 246 toMvip.SEIP.valid := wen && !mvien.SSIE 247 toMvip.SEIP.bits := wdata.SEIP 248 // When mvien.SEIE = 0, mip.SEIP is alias of mvip.SEIP. 249 // Otherwise, mip.SEIP is read only 0 250 regOut.SEIP := Mux(!mvien.SEIE, mvip.SEIP.asUInt, 0.U) 251 rdataFields.SEIP := regOut.SEIP || platformIRP.SEIP 252 253 // bit 10 VSEIP 254 regOut.VSEIP := hvip.VSEIP || platformIRP.VSEIP || hgeip.ip.asUInt(hstatusVGEIN.asUInt) 255 256 // bit 11 MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller. 257 regOut.MEIP := platformIRP.MEIP 258 259 // bit 12 SGEIP 260 regOut.SGEIP := Cat(hgeip.asUInt & hgeie.asUInt).orR 261 262 // bit 13 LCOFIP 263 when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid) { 264 reg.LCOFIP := Mux1H(Seq( 265 fromSip.LCOFIP.valid -> fromSip.LCOFIP.bits, 266 fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits, 267 )) 268 } 269 }).setAddr(CSRs.mip) 270 271 val mtinst = Module(new CSRModule("Mtinst") with TrapEntryMEventSinkBundle) 272 .setAddr(CSRs.mtinst) 273 274 val mtval2 = Module(new CSRModule("Mtval2") with TrapEntryMEventSinkBundle) 275 .setAddr(CSRs.mtval2) 276 277 val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle { 278 val PMM = RO(33, 32) 279 val SSEED = RO( 9) 280 val USEED = RO( 8) 281 val RLB = RO( 2) 282 val MMWP = RO( 1) 283 val MML = RO( 0) 284 })).setAddr(CSRs.mseccfg) 285 286 val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle { 287 reg.ALL := Mux(!mcountinhibit.CY.asUInt.asBool, reg.ALL.asUInt + 1.U, reg.ALL.asUInt) 288 }).setAddr(CSRs.mcycle) 289 290 291 val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle { 292 reg.ALL := Mux(!mcountinhibit.IR.asUInt.asBool && robCommit.instNum.valid, reg.ALL.asUInt + robCommit.instNum.bits, reg.ALL.asUInt) 293 }).setAddr(CSRs.minstret) 294 295 // Todo: guarded by mcountinhibit 296 val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 297 Module(new CSRModule(s"Mhpmcounter$num") with HasMachineCounterControlBundle with HasPerfCounterBundle { 298 reg.ALL := Mux(mcountinhibit.asUInt(num) | perfEventscounten(num - 3), reg.ALL.asUInt, reg.ALL.asUInt + perf(num - 3).value) 299 }).setAddr(CSRs.mhpmcounter3 - 3 + num) 300 ) 301 302 val mvendorid = Module(new CSRModule("Mvendorid") { rdata := 0.U }) 303 .setAddr(CSRs.mvendorid) 304 305 // architecture id for XiangShan is 25 306 // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md 307 val marchid = Module(new CSRModule("Marchid", new CSRBundle { 308 val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid) 309 })).setAddr(CSRs.marchid) 310 311 val mimpid = Module(new CSRModule("Mimpid", new CSRBundle { 312 val ALL = RO(0).withReset(0.U) 313 })) 314 .setAddr(CSRs.mimpid) 315 316 val mhartid = Module(new CSRModule("Mhartid", new CSRBundle { 317 val ALL = RO(7, 0) 318 }) { 319 val hartid = IO(Input(UInt(hartIdLen.W))) 320 this.reg.ALL := RegEnable(hartid, reset.asBool) 321 }) 322 .setAddr(CSRs.mhartid) 323 324 val mconfigptr = Module(new CSRModule("Mconfigptr")) 325 .setAddr(CSRs.mconfigptr) 326 327 val machineLevelCSRMods: Seq[CSRModule[_]] = Seq( 328 mstatus, 329 misa, 330 medeleg, 331 mideleg, 332 mie, 333 mtvec, 334 mcounteren, 335 mvien, 336 mvip, 337 menvcfg, 338 mcountinhibit, 339 mscratch, 340 mepc, 341 mcause, 342 mtval, 343 mip, 344 mtinst, 345 mtval2, 346 mseccfg, 347 mcycle, 348 minstret, 349 mvendorid, 350 marchid, 351 mimpid, 352 mhartid, 353 mconfigptr, 354 ) ++ mhpmevents ++ mhpmcounters 355 356 val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = SeqMap.from( 357 machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 358 ) 359 360 val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 361 machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 362 ) 363 364 // perf tmp 365 val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 366 List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 367 List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 368 List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 369 370 mhpmevents.foreach { mod => 371 mod match { 372 case m: HasPerfEventBundle => 373 m.perfEvents := perfEvents 374 case _ => 375 } 376 } 377 378} 379 380class MstatusBundle extends CSRBundle { 381 382 val SIE = CSRRWField (1).withReset(0.U) 383 val MIE = CSRRWField (3).withReset(0.U) 384 val SPIE = CSRRWField (5).withReset(0.U) 385 val UBE = CSRROField (6).withReset(0.U) 386 val MPIE = CSRRWField (7).withReset(0.U) 387 val SPP = CSRRWField (8).withReset(0.U) 388 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 389 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 390 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 391 val XS = ContextStatusRO(16, 15).withReset(0.U) 392 val MPRV = CSRRWField (17).withReset(0.U) 393 val SUM = CSRRWField (18).withReset(0.U) 394 val MXR = CSRRWField (19).withReset(0.U) 395 val TVM = CSRRWField (20).withReset(0.U) 396 val TW = CSRRWField (21).withReset(0.U) 397 val TSR = CSRRWField (22).withReset(0.U) 398 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 399 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 400 val SBE = CSRROField (36).withReset(0.U) 401 val MBE = CSRROField (37).withReset(0.U) 402 val GVA = CSRRWField (38).withReset(0.U) 403 val MPV = VirtMode (39).withReset(0.U) 404 val SD = CSRROField (63, 405 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 406 ) 407} 408 409class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 410 with TrapEntryMEventSinkBundle 411 with TrapEntryHSEventSinkBundle 412 with DretEventSinkBundle 413 with MretEventSinkBundle 414 with SretEventSinkBundle 415 with HasRobCommitBundle 416{ 417 val mstatus = IO(Output(bundle)) 418 val sstatus = IO(Output(new SstatusBundle)) 419 420 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 421 422 // write connection 423 this.wfn(reg)(Seq(wAliasSstatus)) 424 425 when (robCommit.fsDirty) { 426 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 427 reg.FS := ContextStatus.Dirty 428 } 429 430 when (robCommit.vsDirty) { 431 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 432 reg.VS := ContextStatus.Dirty 433 } 434 435 // read connection 436 mstatus :|= reg 437 sstatus := mstatus 438 rdata := mstatus.asUInt 439} 440 441class MisaBundle extends CSRBundle { 442 // Todo: reset with ISA string 443 val A = RO( 0).withReset(1.U) // Atomic extension 444 val B = RO( 1).withReset(0.U) // Reserved 445 val C = RO( 2).withReset(1.U) // Compressed extension 446 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 447 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 448 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 449 val G = RO( 6).withReset(0.U) // Reserved 450 val H = RO( 7).withReset(1.U) // Hypervisor extension 451 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 452 val J = RO( 9).withReset(0.U) // Reserved 453 val K = RO(10).withReset(0.U) // Reserved 454 val L = RO(11).withReset(0.U) // Reserved 455 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 456 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 457 val O = RO(14).withReset(0.U) // Reserved 458 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 459 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 460 val R = RO(17).withReset(0.U) // Reserved 461 val S = RO(18).withReset(1.U) // Supervisor mode implemented 462 val T = RO(19).withReset(0.U) // Reserved 463 val U = RO(20).withReset(1.U) // User mode implemented 464 val V = RO(21).withReset(1.U) // Vector extension 465 val W = RO(22).withReset(0.U) // Reserved 466 val X = RO(23).withReset(0.U) // Non-standard extensions present 467 val Y = RO(24).withReset(0.U) // Reserved 468 val Z = RO(25).withReset(0.U) // Reserved 469 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 470 471 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 472} 473 474class MedelegBundle extends ExceptionBundle { 475 this.getALL.foreach(_.setRW().withReset(0.U)) 476 this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall 477 this.EX_BP.setRO().withReset(0.U) // Parter 5.4 in debug spec. tcontrol is implemented. medeleg [3] is hard-wired to 0. 478} 479 480class MidelegBundle extends InterruptBundle { 481 this.getALL.foreach(_.setRW().withReset(0.U)) 482 // Don't delegate Machine level interrupts 483 this.getM.foreach(_.setRO().withReset(0.U)) 484 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 485 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 486 // interrupts) are each read-only one. 487 this.getVS.foreach(_.setRO().withReset(1.U)) 488 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 489 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 490 this.SGEI.setRO().withReset(1.U) 491} 492 493class MieBundle extends InterruptEnableBundle { 494 this.getNonLocal.foreach(_.setRW().withReset(0.U)) 495} 496 497class MipBundle extends InterruptPendingBundle { 498 // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers 499 // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip 500 // 501 // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers, 502 // while these bits in hip are aliases for the same bits in mip. 503 // 504 // Ref: riscv interrupt spec - 2.1 Machine-level CSRs 505 // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes. 506 this.getHS.foreach(_.setRW().withReset(0.U)) 507 this.getVS.foreach(_.setRW().withReset(0.U)) 508 this.LCOFIP.setRW().withReset(0.U) 509} 510 511class MvienBundle extends InterruptEnableBundle { 512 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 513 // It is strongly recommended that bit 9 of mvien be writable. 514 // It is strongly recommended that bit 1 of mvien also be writable. 515 // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63. 516 this.SSIE.setRW().withReset(0.U) 517 this.SEIE.setRW().withReset(0.U) 518 this.getLocal.foreach(_.setRW().withReset(0.U)) 519} 520 521class MvipBundle extends InterruptPendingBundle { 522 this.getHS.foreach(_.setRW().withReset(0.U)) 523 this.getLocal.foreach(_.setRW().withReset(0.U)) 524} 525 526class Epc extends CSRBundle { 527 import CSRConfig._ 528 529 val epc = RW(VaddrMaxWidth - 1, 1) 530} 531 532class McountinhibitBundle extends CSRBundle { 533 val CY = RW(0) 534 val IR = RW(2) 535 val HPM3 = RW(31, 3) 536} 537 538class MEnvCfg extends EnvCfg { 539 if (CSRConfig.EXT_SSTC) { 540 this.STCE.setRW().withReset(1.U) 541 } 542} 543 544object MarchidField extends CSREnum with ROApply { 545 val XSArchid = Value(25.U) 546} 547 548class MieToHie extends Bundle { 549 val VSSIE = ValidIO(RW(0)) 550 val VSTIE = ValidIO(RW(0)) 551 val VSEIE = ValidIO(RW(0)) 552 val SGEIE = ValidIO(RW(0)) 553} 554 555class MvipToMip extends IpValidBundle { 556 this.getHS.foreach(_.bits.setRW()) 557} 558 559class HipToMip extends IpValidBundle { 560 // Only hip.VSSIP is writable 561 this.VSSIP.bits.setRW() 562} 563 564class VSipToMip extends IpValidBundle { 565 this.LCOFIP.bits.setRW() 566} 567 568class MipToHvip extends IpValidBundle { 569 this.VSSIP.bits.setRW() 570} 571 572class MipToMvip extends IpValidBundle { 573 this.SEIP.bits.setRW() 574} 575 576trait HasMipToAlias { self: CSRModule[_] => 577 val mipAlias = Output(new MipBundle) 578} 579 580trait HasMachineDelegBundle { self: CSRModule[_] => 581 val mideleg = IO(Input(new MidelegBundle)) 582 val medeleg = IO(Input(new MedelegBundle)) 583} 584 585trait HasExternalInterruptBundle { 586 val platformIRP = IO(new Bundle { 587 val MEIP = Input(Bool()) 588 val MTIP = Input(Bool()) 589 val MSIP = Input(Bool()) 590 val SEIP = Input(Bool()) 591 val STIP = Input(Bool()) 592 val VSEIP = Input(Bool()) 593 val VSTIP = Input(Bool()) 594 // debug interrupt from debug module 595 val debugIP = Input(Bool()) 596 }) 597} 598 599trait HasMachineCounterControlBundle { self: CSRModule[_] => 600 val mcountinhibit = IO(Input(new McountinhibitBundle)) 601} 602 603trait HasRobCommitBundle { self: CSRModule[_] => 604 val robCommit = IO(Input(new RobCommitCSR)) 605} 606 607trait HasMachineEnvBundle { self: CSRModule[_] => 608 val menvcfg = IO(Input(new MEnvCfg)) 609} 610 611trait HasPerfCounterBundle { self: CSRModule[_] => 612 val perfEventscounten = IO(Input(Vec(perfCntNum, Bool()))) 613 val perf = IO(Input(Vec(perfCntNum, new PerfEvent))) 614} 615 616trait HasPerfEventBundle { self: CSRModule[_] => 617 val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W)))) 618}