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