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