xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision 22a9a4559bce22c164326c9fea03f3589b52793c)
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}