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