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