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