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 with HasLocalInterruptReqBundle 192 { 193 // Alias write in 194 val fromMvip = IO(Flipped(new MvipToMip)) 195 val fromSip = IO(Flipped(new SipToMip)) 196 val fromVSip = IO(Flipped(new VSipToMip)) 197 // Alias write out 198 val toMvip = IO(new MipToMvip).connectZeroNonRW 199 val toHvip = IO(new MipToHvip).connectZeroNonRW 200 201 // bit 1 SSIP 202 when (fromMvip.SSIP.valid || fromSip.SSIP.valid) { 203 reg.SSIP := Mux1H(Seq( 204 fromMvip.SSIP.valid -> fromMvip.SSIP.bits, 205 fromSip .SSIP.valid -> fromSip .SSIP.bits, 206 )) 207 } 208 209 // bit 2 VSSIP reg in hvip 210 // alias of hvip.VSSIP 211 toHvip.VSSIP.valid := wen 212 toHvip.VSSIP.bits := wdata.VSSIP 213 regOut.VSSIP := hvip.VSSIP 214 215 // bit 3 MSIP is read-only in mip, and is written by accesses to memory-mapped control registers, 216 // which are used by remote harts to provide machine-level interprocessor interrupts. 217 regOut.MSIP := platformIRP.MSIP 218 219 // bit 5 STIP 220 // If the stimecmp (supervisor-mode timer compare) register is implemented(menvcfg.STCE=1), STIP is read-only in mip. 221 regOut.STIP := Mux(this.menvcfg.STCE.asBool, platformIRP.STIP, reg.STIP.asBool) 222 when ((wen || fromMvip.STIP.valid) && !this.menvcfg.STCE) { 223 reg.STIP := Mux1H(Seq( 224 wen -> wdata.STIP, 225 fromMvip.STIP.valid -> fromMvip.STIP.bits, 226 )) 227 } 228 229 // bit 6 VSTIP 230 regOut.VSTIP := hvip.VSTIP || platformIRP.VSTIP 231 232 // bit 7 MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register 233 regOut.MTIP := platformIRP.MTIP 234 235 // bit 9 SEIP 236 // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP. 237 // 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. 238 // 239 // As explained in this issue(https://github.com/riscv/riscv-aia/issues/64), 240 // when mvien[9]=0, mip.SEIP is a software-writable bit and is special in its read value, which is the logical-OR of 241 // mip.SEIP reg and other source from the interrupt controller. 242 // mvip.SEIP is alias of mip.SEIP's reg part, and is independent of the other source from the interrupt controller. 243 // 244 // mip.SEIP is implemented as the alias of mvip.SEIP when mvien=0 245 // the read valid of SEIP is ORed by mvip.SEIP and the other source from the interrupt controller. 246 247 toMvip.SEIP.valid := wen && !mvien.SSIE 248 toMvip.SEIP.bits := wdata.SEIP 249 // When mvien.SEIE = 0, mip.SEIP is alias of mvip.SEIP. 250 // Otherwise, mip.SEIP is read only 0 251 regOut.SEIP := Mux(!mvien.SEIE, mvip.SEIP.asUInt, 0.U) 252 rdataFields.SEIP := regOut.SEIP || platformIRP.SEIP 253 254 // bit 10 VSEIP 255 regOut.VSEIP := hvip.VSEIP || platformIRP.VSEIP || hgeip.ip.asUInt(hstatusVGEIN.asUInt) 256 257 // bit 11 MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller. 258 regOut.MEIP := platformIRP.MEIP 259 260 // bit 12 SGEIP 261 regOut.SGEIP := Cat(hgeip.asUInt & hgeie.asUInt).orR 262 263 // bit 13 LCOFIP 264 reg.LCOFIP := lcofiReq 265 when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid) { 266 reg.LCOFIP := Mux1H(Seq( 267 fromSip.LCOFIP.valid -> fromSip.LCOFIP.bits, 268 fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits, 269 )) 270 } 271 }).setAddr(CSRs.mip) 272 273 val mtinst = Module(new CSRModule("Mtinst") with TrapEntryMEventSinkBundle) 274 .setAddr(CSRs.mtinst) 275 276 val mtval2 = Module(new CSRModule("Mtval2") with TrapEntryMEventSinkBundle) 277 .setAddr(CSRs.mtval2) 278 279 val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle { 280 val PMM = RO(33, 32) 281 val SSEED = RO( 9) 282 val USEED = RO( 8) 283 val RLB = RO( 2) 284 val MMWP = RO( 1) 285 val MML = RO( 0) 286 })).setAddr(CSRs.mseccfg) 287 288 val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle { 289 reg.ALL := Mux(!mcountinhibit.CY.asUInt.asBool, reg.ALL.asUInt + 1.U, reg.ALL.asUInt) 290 }).setAddr(CSRs.mcycle) 291 292 293 val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle { 294 reg.ALL := Mux(!mcountinhibit.IR.asUInt.asBool && robCommit.instNum.valid, reg.ALL.asUInt + robCommit.instNum.bits, reg.ALL.asUInt) 295 }).setAddr(CSRs.minstret) 296 297 val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num => 298 Module(new CSRModule(s"Mhpmcounter$num") with HasMachineCounterControlBundle with HasPerfCounterBundle { 299 val countingInhibit = mcountinhibit.asUInt(num) | !countingEn 300 val counterAdd = reg.ALL.asUInt +& perf.value 301 reg.ALL := Mux(countingInhibit, reg.ALL.asUInt, counterAdd.tail(1)) 302 // Count overflow never results from writes to the mhpmcountern or mhpmeventn registers, only from 303 // hardware increments of counter registers. 304 toMhpmeventOF := !countingInhibit & counterAdd.head(1) 305 }).setAddr(CSRs.mhpmcounter3 - 3 + num) 306 ) 307 308 val mvendorid = Module(new CSRModule("Mvendorid") { rdata := 0.U }) 309 .setAddr(CSRs.mvendorid) 310 311 // architecture id for XiangShan is 25 312 // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md 313 val marchid = Module(new CSRModule("Marchid", new CSRBundle { 314 val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid) 315 })).setAddr(CSRs.marchid) 316 317 val mimpid = Module(new CSRModule("Mimpid", new CSRBundle { 318 val ALL = RO(0).withReset(0.U) 319 })) 320 .setAddr(CSRs.mimpid) 321 322 val mhartid = Module(new CSRModule("Mhartid", new CSRBundle { 323 val ALL = RO(7, 0) 324 }) { 325 val hartid = IO(Input(UInt(hartIdLen.W))) 326 this.reg.ALL := RegEnable(hartid, reset.asBool) 327 }) 328 .setAddr(CSRs.mhartid) 329 330 val mconfigptr = Module(new CSRModule("Mconfigptr")) 331 .setAddr(CSRs.mconfigptr) 332 333 val mstateen0 = Module(new CSRModule("Mstateen", new MstateenBundle0)).setAddr(CSRs.mstateen0) 334 335 val machineLevelCSRMods: Seq[CSRModule[_]] = Seq( 336 mstatus, 337 misa, 338 medeleg, 339 mideleg, 340 mie, 341 mtvec, 342 mcounteren, 343 mvien, 344 mvip, 345 menvcfg, 346 mcountinhibit, 347 mscratch, 348 mepc, 349 mcause, 350 mtval, 351 mip, 352 mtinst, 353 mtval2, 354 mseccfg, 355 mcycle, 356 minstret, 357 mvendorid, 358 marchid, 359 mimpid, 360 mhartid, 361 mconfigptr, 362 mstateen0, 363 ) ++ mhpmevents ++ mhpmcounters 364 365 val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from( 366 machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator 367 ) 368 369 val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from( 370 machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator 371 ) 372 373 // read/write/update mhpmevents -> read/write/update perfEvents 374 val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++ 375 List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++ 376 List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++ 377 List.fill(5)(RegInit("hc0300c0300".U(XLEN.W))) 378 379 mhpmevents.foreach { mod => 380 mod match { 381 case m: HasPerfEventBundle => 382 m.perfEvents := perfEvents 383 case _ => 384 } 385 } 386 387} 388 389class MstatusBundle extends CSRBundle { 390 391 val SIE = CSRRWField (1).withReset(0.U) 392 val MIE = CSRRWField (3).withReset(0.U) 393 val SPIE = CSRRWField (5).withReset(0.U) 394 val UBE = CSRROField (6).withReset(0.U) 395 val MPIE = CSRRWField (7).withReset(0.U) 396 val SPP = CSRRWField (8).withReset(0.U) 397 val VS = ContextStatus (10, 9).withReset(ContextStatus.Off) 398 val MPP = PrivMode (12, 11).withReset(PrivMode.U) 399 val FS = ContextStatus (14, 13).withReset(ContextStatus.Off) 400 val XS = ContextStatusRO(16, 15).withReset(0.U) 401 val MPRV = CSRRWField (17).withReset(0.U) 402 val SUM = CSRRWField (18).withReset(0.U) 403 val MXR = CSRRWField (19).withReset(0.U) 404 val TVM = CSRRWField (20).withReset(0.U) 405 val TW = CSRRWField (21).withReset(0.U) 406 val TSR = CSRRWField (22).withReset(0.U) 407 val UXL = XLENField (33, 32).withReset(XLENField.XLEN64) 408 val SXL = XLENField (35, 34).withReset(XLENField.XLEN64) 409 val SBE = CSRROField (36).withReset(0.U) 410 val MBE = CSRROField (37).withReset(0.U) 411 val GVA = CSRRWField (38).withReset(0.U) 412 val MPV = VirtMode (39).withReset(0.U) 413 val SD = CSRROField (63, 414 (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty 415 ) 416} 417 418class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle) 419 with TrapEntryMEventSinkBundle 420 with TrapEntryHSEventSinkBundle 421 with DretEventSinkBundle 422 with MretEventSinkBundle 423 with SretEventSinkBundle 424 with HasRobCommitBundle 425{ 426 val mstatus = IO(Output(bundle)) 427 val sstatus = IO(Output(new SstatusBundle)) 428 val sstatusRdata = IO(Output(UInt(64.W))) 429 430 val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle))) 431 432 // write connection 433 this.wfn(reg)(Seq(wAliasSstatus)) 434 435 when (robCommit.fsDirty || writeFCSR) { 436 assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode") 437 reg.FS := ContextStatus.Dirty 438 } 439 440 when (robCommit.vsDirty || writeVCSR) { 441 assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode") 442 reg.VS := ContextStatus.Dirty 443 } 444 445 // read connection 446 mstatus :|= reg 447 sstatus := mstatus 448 rdata := mstatus.asUInt 449 sstatusRdata := sstatus.asUInt 450} 451 452class MisaBundle extends CSRBundle { 453 // Todo: reset with ISA string 454 val A = RO( 0).withReset(1.U) // Atomic extension 455 val B = RO( 1).withReset(0.U) // Reserved 456 val C = RO( 2).withReset(1.U) // Compressed extension 457 val D = RO( 3).withReset(1.U) // Double-precision floating-point extension 458 val E = RO( 4).withReset(0.U) // RV32E/64E base ISA 459 val F = RO( 5).withReset(1.U) // Single-precision floating-point extension 460 val G = RO( 6).withReset(0.U) // Reserved 461 val H = RO( 7).withReset(1.U) // Hypervisor extension 462 val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA 463 val J = RO( 9).withReset(0.U) // Reserved 464 val K = RO(10).withReset(0.U) // Reserved 465 val L = RO(11).withReset(0.U) // Reserved 466 val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi 467 val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension 468 val O = RO(14).withReset(0.U) // Reserved 469 val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension 470 val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension 471 val R = RO(17).withReset(0.U) // Reserved 472 val S = RO(18).withReset(1.U) // Supervisor mode implemented 473 val T = RO(19).withReset(0.U) // Reserved 474 val U = RO(20).withReset(1.U) // User mode implemented 475 val V = RO(21).withReset(1.U) // Vector extension 476 val W = RO(22).withReset(0.U) // Reserved 477 val X = RO(23).withReset(0.U) // Non-standard extensions present 478 val Y = RO(24).withReset(0.U) // Reserved 479 val Z = RO(25).withReset(0.U) // Reserved 480 val MXL = XLENField(63, 62).withReset(XLENField.XLEN64) 481 482 def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString 483} 484 485class MedelegBundle extends ExceptionBundle { 486 this.getALL.foreach(_.setRW().withReset(0.U)) 487 this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall 488 this.EX_BP.setRO().withReset(0.U) // Parter 5.4 in debug spec. tcontrol is implemented. medeleg [3] is hard-wired to 0. 489} 490 491class MidelegBundle extends InterruptBundle { 492 this.getALL.foreach(_.setRW().withReset(0.U)) 493 // Don't delegate Machine level interrupts 494 this.getM.foreach(_.setRO().withReset(0.U)) 495 // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg) 496 // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level 497 // interrupts) are each read-only one. 498 this.getVS.foreach(_.setRO().withReset(1.U)) 499 // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one. 500 // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode. 501 this.SGEI.setRO().withReset(1.U) 502} 503 504class MieBundle extends InterruptEnableBundle { 505 this.getNonLocal.foreach(_.setRW().withReset(0.U)) 506} 507 508class MipBundle extends InterruptPendingBundle { 509 // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers 510 // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip 511 // 512 // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers, 513 // while these bits in hip are aliases for the same bits in mip. 514 // 515 // Ref: riscv interrupt spec - 2.1 Machine-level CSRs 516 // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes. 517 this.getHS.foreach(_.setRW().withReset(0.U)) 518 this.getVS.foreach(_.setRW().withReset(0.U)) 519 this.LCOFIP.setRW().withReset(0.U) 520} 521 522class MvienBundle extends InterruptEnableBundle { 523 // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level 524 // It is strongly recommended that bit 9 of mvien be writable. 525 // It is strongly recommended that bit 1 of mvien also be writable. 526 // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63. 527 this.SSIE.setRW().withReset(0.U) 528 this.SEIE.setRW().withReset(0.U) 529 this.getLocal.foreach(_.setRW().withReset(0.U)) 530} 531 532class MvipBundle extends InterruptPendingBundle { 533 this.getHS.foreach(_.setRW().withReset(0.U)) 534 this.getLocal.foreach(_.setRW().withReset(0.U)) 535} 536 537class Epc extends CSRBundle { 538 import CSRConfig._ 539 540 val epc = RW(VaddrMaxWidth - 1, 1) 541} 542 543class McountinhibitBundle extends CSRBundle { 544 val CY = RW(0) 545 val IR = RW(2) 546 val HPM3 = RW(31, 3) 547} 548 549// todo: for the future, delete bypass between mhpmevents and perfEvents 550class MhpmeventBundle extends CSRBundle { 551 val OF = RW(63).withReset(0.U) 552 val MINH = RW(62).withReset(0.U) 553 val SINH = RW(61).withReset(0.U) 554 val UINH = RW(60).withReset(0.U) 555 val VSINH = RW(59).withReset(0.U) 556 val VUINH = RW(58).withReset(0.U) 557} 558 559class MEnvCfg extends EnvCfg { 560 if (CSRConfig.EXT_SSTC) { 561 this.STCE.setRW().withReset(1.U) 562 } 563} 564 565object MarchidField extends CSREnum with ROApply { 566 val XSArchid = Value(25.U) 567} 568 569class MieToHie extends Bundle { 570 val VSSIE = ValidIO(RW(0)) 571 val VSTIE = ValidIO(RW(0)) 572 val VSEIE = ValidIO(RW(0)) 573 val SGEIE = ValidIO(RW(0)) 574} 575 576class MvipToMip extends IpValidBundle { 577 this.getHS.foreach(_.bits.setRW()) 578} 579 580class HipToMip extends IpValidBundle { 581 // Only hip.VSSIP is writable 582 this.VSSIP.bits.setRW() 583} 584 585class VSipToMip extends IpValidBundle { 586 this.LCOFIP.bits.setRW() 587} 588 589class MipToHvip extends IpValidBundle { 590 this.VSSIP.bits.setRW() 591} 592 593class MipToMvip extends IpValidBundle { 594 this.SEIP.bits.setRW() 595} 596 597trait HasMipToAlias { self: CSRModule[_] => 598 val mipAlias = Output(new MipBundle) 599} 600 601trait HasMachineDelegBundle { self: CSRModule[_] => 602 val mideleg = IO(Input(new MidelegBundle)) 603 val medeleg = IO(Input(new MedelegBundle)) 604} 605 606trait HasExternalInterruptBundle { 607 val platformIRP = IO(new Bundle { 608 val MEIP = Input(Bool()) 609 val MTIP = Input(Bool()) 610 val MSIP = Input(Bool()) 611 val SEIP = Input(Bool()) 612 val STIP = Input(Bool()) 613 val VSEIP = Input(Bool()) 614 val VSTIP = Input(Bool()) 615 // debug interrupt from debug module 616 val debugIP = Input(Bool()) 617 }) 618} 619 620trait HasMachineCounterControlBundle { self: CSRModule[_] => 621 val mcountinhibit = IO(Input(new McountinhibitBundle)) 622} 623 624trait HasRobCommitBundle { self: CSRModule[_] => 625 val robCommit = IO(Input(new RobCommitCSR)) 626 val writeFCSR = IO(Input(Bool())) 627 val writeVCSR = IO(Input(Bool())) 628 val isVirtMode = IO(Input(Bool())) 629} 630 631trait HasMachineEnvBundle { self: CSRModule[_] => 632 val menvcfg = IO(Input(new MEnvCfg)) 633} 634 635trait HasPerfCounterBundle { self: CSRModule[_] => 636 val countingEn = IO(Input(Bool())) 637 val perf = IO(Input(new PerfEvent)) 638 val toMhpmeventOF = IO(Output(Bool())) 639} 640 641trait HasPerfEventBundle { self: CSRModule[_] => 642 val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W)))) 643} 644 645trait HasLocalInterruptReqBundle { self: CSRModule[_] => 646 val lcofiReq = IO(Input(Bool())) 647}