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