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