xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision e1d5ffc2d93873b72146e78c8f6a904926de8590)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.experimental.SourceInfo
5import chisel3.util._
6import org.chipsalliance.cde.config.Parameters
7import freechips.rocketchip.rocket.CSRs
8import utility.SignExt
9import utils.PerfEvent
10import xiangshan.backend.fu.NewCSR.CSRBundles._
11import xiangshan.backend.fu.NewCSR.CSRDefines._
12import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _}
13import xiangshan.backend.fu.NewCSR.CSREvents._
14import xiangshan.backend.fu.NewCSR.CSREnumTypeImplicitCast._
15import xiangshan.backend.fu.NewCSR.ChiselRecordForField._
16import xiangshan.backend.fu.PerfCounterIO
17import xiangshan.backend.fu.NewCSR.CSRConfig._
18import xiangshan.backend.fu.NewCSR.CSRFunc.wNoEffectWhen
19
20import scala.collection.immutable.SeqMap
21
22trait MachineLevel { self: NewCSR =>
23  val mstatus = Module(new MstatusModule)
24    .setAddr(CSRs.mstatus)
25
26  val misa = Module(new CSRModule("Misa", new MisaBundle))
27    .setAddr(CSRs.misa)
28
29  println(s"[CSR] supported isa ext: ${misa.bundle.getISAString}")
30
31  val medeleg = Module(new CSRModule("Medeleg", new MedelegBundle))
32    .setAddr(CSRs.medeleg)
33
34  val mideleg = Module(new CSRModule("Mideleg", new MidelegBundle))
35    .setAddr(CSRs.mideleg)
36
37  val mie = Module(new CSRModule("Mie", new MieBundle) with HasIpIeBundle {
38    val fromHie  = IO(Flipped(new HieToMie))
39    val fromSie  = IO(Flipped(new SieToMie))
40    val fromVSie = IO(Flipped(new VSieToMie))
41
42    // bit 1 SSIE
43    when (fromSie.SSIE.valid) {
44      reg.SSIE := fromSie.SSIE.bits
45    }
46
47    // bit 2 VSSIE
48    when (fromHie.VSSIE.valid || fromVSie.VSSIE.valid) {
49      reg.VSSIE := Mux1H(Seq(
50        fromHie .VSSIE.valid -> fromHie .VSSIE.bits,
51        fromVSie.VSSIE.valid -> fromVSie.VSSIE.bits,
52      ))
53    }
54
55    // bit 5 STIE
56    when(fromSie.STIE.valid) {
57      reg.STIE := fromSie.STIE.bits
58    }
59
60    // bit 6 VSTIE
61    when(fromHie.VSTIE.valid || fromVSie.VSTIE.valid) {
62      reg.VSTIE := Mux1H(Seq(
63        fromHie .VSTIE.valid -> fromHie .VSTIE.bits,
64        fromVSie.VSTIE.valid -> fromVSie.VSTIE.bits,
65      ))
66    }
67
68    // bit 9 SEIE
69    when(fromSie.SEIE.valid) {
70      reg.SEIE := fromSie.SEIE.bits
71    }
72
73    // bit 10 VSEIE
74    when(fromHie.VSEIE.valid || fromVSie.VSEIE.valid) {
75      reg.VSEIE := Mux1H(Seq(
76        fromHie .VSEIE.valid -> fromHie .VSEIE.bits,
77        fromVSie.VSEIE.valid -> fromVSie.VSEIE.bits,
78      ))
79    }
80
81    // bit 12 SGEIE
82    when(fromHie.SGEIE.valid) {
83      reg.SGEIE := fromHie.SGEIE.bits
84    }
85
86    // bit 13~63 LCIP
87    reg.getLocal lazyZip fromSie.getLocal lazyZip fromVSie.getLocal foreach { case (rLCIE, sieLCIE, vsieLCIE) =>
88      when (sieLCIE.valid || vsieLCIE.valid) {
89        rLCIE := Mux1H(Seq(
90          sieLCIE .valid -> sieLCIE .bits,
91          vsieLCIE.valid -> vsieLCIE.bits,
92        ))
93      }
94    }
95
96    // 14~63 read only 0
97    regOut.getLocal.filterNot(_.lsb == InterruptNO.COI).foreach(_ := 0.U)
98  }).setAddr(CSRs.mie)
99
100  val mtvec = Module(new CSRModule("Mtvec", new XtvecBundle))
101    .setAddr(CSRs.mtvec)
102
103  // Todo: support "Stimecmp/Vstimecmp" Extension, Version 1.0.0
104  // Todo: support Sscounterenw Extension
105  val mcounteren = Module(new CSRModule("Mcounteren", new Counteren))
106    .setAddr(CSRs.mcounteren)
107
108  val mvien = Module(new CSRModule("Mvien", new MvienBundle))
109    .setAddr(CSRs.mvien)
110
111  val mvip = Module(new CSRModule("Mvip", new MvipBundle)
112    with HasIpIeBundle
113    with HasMachineEnvBundle
114  {
115    val toMip = IO(new MvipToMip).connectZeroNonRW
116    val fromMip = IO(Flipped(new MipToMvip))
117    val fromSip = IO(Flipped(new SipToMvip))
118    val fromVSip = IO(Flipped(new VSipToMvip))
119
120    // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip.
121    // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP.
122    // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED.
123    // XiangShan will keep the value in mvip.SSIP when mvien.SSIE is changed from zero to one
124    reg.SSIP := Mux(wen && this.mvien.SSIE.asBool, wdata.SSIP, reg.SSIP)
125    regOut.SSIP := Mux(this.mvien.SSIE.asBool, reg.SSIP, this.mip.SSIP)
126    toMip.SSIP.valid := wen && !this.mvien.SSIE.asBool
127    toMip.SSIP.bits := wdata.SSIP
128
129    // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip.
130    // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero.
131    // Todo: check mip writable when menvcfg.STCE = 1
132    regOut.STIP := Mux(this.menvcfg.STCE.asBool, 0.U, this.mip.STIP.asBool)
133    // Don't update mip.STIP when menvcfg.STCE is 1
134    toMip.STIP.valid := wen && !this.menvcfg.STCE.asBool
135    toMip.STIP.bits := wdata.STIP
136
137    // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP).
138    // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP.
139    // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip.
140    toMip.SEIP.valid := wen && !this.mvien.SEIE.asUInt.asBool
141    toMip.SEIP.bits := wdata.SEIP
142    when (fromMip.SEIP.valid) {
143      reg.SEIP := fromMip.SEIP.bits
144    }
145
146    // write from sip
147    when (fromSip.SSIP.valid) {
148      reg.SSIP := fromSip.SSIP.bits
149    }
150
151    reg.getLocal lazyZip fromSip.getLocal lazyZip fromVSip.getLocal foreach { case (rLCIP, sipLCIP, vsipLCIP) =>
152      // sip should assert valid when mideleg=0 && mvien=1
153      when (sipLCIP.valid || vsipLCIP.valid) {
154        rLCIP := Mux1H(Seq(
155          sipLCIP .valid -> sipLCIP .bits,
156          vsipLCIP.valid -> vsipLCIP.bits,
157        ))
158      }
159    }
160  }).setAddr(CSRs.mvip)
161
162  val menvcfg = Module(new CSRModule("Menvcfg", new MEnvCfg))
163    .setAddr(CSRs.menvcfg)
164
165  val mcountinhibit = Module(new CSRModule("Mcountinhibit", new McountinhibitBundle))
166    .setAddr(CSRs.mcountinhibit)
167
168  val mhpmevents: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
169    Module(new CSRModule(s"Mhpmevent$num") with HasPerfEventBundle {
170      regOut := this.perfEvents(num - 3)
171    })
172      .setAddr(CSRs.mhpmevent3 - 3 + num)
173  )
174
175  val mscratch = Module(new CSRModule("Mscratch"))
176    .setAddr(CSRs.mscratch)
177
178  val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle)
179    .setAddr(CSRs.mepc)
180
181  val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle)
182    .setAddr(CSRs.mcause)
183
184  val mtval = Module(new CSRModule("Mtval", new XtvalBundle) with TrapEntryMEventSinkBundle)
185    .setAddr(CSRs.mtval)
186
187  val mip = Module(new CSRModule("Mip", new MipBundle)
188    with HasIpIeBundle
189    with HasExternalInterruptBundle
190    with HasMachineEnvBundle
191    with HasLocalInterruptReqBundle
192    with HasAIABundle
193  {
194    // Alias write in
195    val fromMvip = IO(Flipped(new MvipToMip))
196    val fromSip  = IO(Flipped(new SipToMip))
197    val fromVSip = IO(Flipped(new VSipToMip))
198    // Alias write out
199    val toMvip   = IO(new MipToMvip).connectZeroNonRW
200    val toHvip   = IO(new MipToHvip).connectZeroNonRW
201
202    // bit 1 SSIP
203    when (fromMvip.SSIP.valid || fromSip.SSIP.valid) {
204      reg.SSIP := Mux1H(Seq(
205        fromMvip.SSIP.valid -> fromMvip.SSIP.bits,
206        fromSip .SSIP.valid -> fromSip .SSIP.bits,
207      ))
208    }
209
210    // bit 2 VSSIP reg in hvip
211    // alias of hvip.VSSIP
212    toHvip.VSSIP.valid := wen
213    toHvip.VSSIP.bits  := wdata.VSSIP
214    regOut.VSSIP := hvip.VSSIP
215
216    // bit 3 MSIP is read-only in mip, and is written by accesses to memory-mapped control registers,
217    // which are used by remote harts to provide machine-level interprocessor interrupts.
218    regOut.MSIP := platformIRP.MSIP
219
220    // bit 5 STIP
221    // If the stimecmp (supervisor-mode timer compare) register is implemented(menvcfg.STCE=1), STIP is read-only in mip.
222    regOut.STIP := Mux(this.menvcfg.STCE.asBool, platformIRP.STIP, reg.STIP.asBool)
223    when ((wen || fromMvip.STIP.valid) && !this.menvcfg.STCE) {
224      reg.STIP := Mux1H(Seq(
225        wen -> wdata.STIP,
226        fromMvip.STIP.valid -> fromMvip.STIP.bits,
227      ))
228    }
229
230    // bit 6 VSTIP
231    regOut.VSTIP := hvip.VSTIP || platformIRP.VSTIP
232
233    // bit 7 MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register
234    regOut.MTIP := platformIRP.MTIP
235
236    // bit 9 SEIP
237    // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP.
238    // when bit 9 of mvien is one, bit SEIP in mip is read-only and does not include the value of bit 9 of mvip.
239    //
240    // As explained in this issue(https://github.com/riscv/riscv-aia/issues/64),
241    // when mvien[9]=0, mip.SEIP is a software-writable bit and is special in its read value, which is the logical-OR of
242    // mip.SEIP reg and other source from the interrupt controller.
243    // mvip.SEIP is alias of mip.SEIP's reg part, and is independent of the other source from the interrupt controller.
244    //
245    // mip.SEIP is implemented as the alias of mvip.SEIP when mvien=0
246    // the read valid of SEIP is ORed by mvip.SEIP and the other source from the interrupt controller.
247
248    toMvip.SEIP.valid := wen && !this.mvien.SSIE
249    toMvip.SEIP.bits := wdata.SEIP
250    // When mvien.SEIE = 0, mip.SEIP is alias of mvip.SEIP.
251    // Otherwise, mip.SEIP is read only 0
252    regOut.SEIP := Mux(!this.mvien.SEIE, this.mvip.SEIP.asUInt, 0.U)
253    rdataFields.SEIP := regOut.SEIP || platformIRP.SEIP || aiaToCSR.seip
254
255    // bit 10 VSEIP
256    regOut.VSEIP := hvip.VSEIP || platformIRP.VSEIP || hgeip.asUInt(hstatusVGEIN.asUInt)
257
258    // bit 11 MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller.
259    // MEIP can from PLIC and IMSIC
260    regOut.MEIP := platformIRP.MEIP || aiaToCSR.meip
261
262    // bit 12 SGEIP
263    regOut.SGEIP := Cat(hgeip.asUInt & hgeie.asUInt).orR
264
265    // bit 13 LCOFIP
266    reg.LCOFIP := lcofiReq
267    when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid || wen) {
268      reg.LCOFIP := Mux1H(Seq(
269        fromSip.LCOFIP.valid  -> fromSip.LCOFIP.bits,
270        fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits,
271        wen -> wdata.LCOFIP,
272      ))
273    }
274  }).setAddr(CSRs.mip)
275
276  val mtinst = Module(new CSRModule("Mtinst", new XtinstBundle) with TrapEntryMEventSinkBundle)
277    .setAddr(CSRs.mtinst)
278
279  val mtval2 = Module(new CSRModule("Mtval2", new Mtval2Bundle) with TrapEntryMEventSinkBundle)
280    .setAddr(CSRs.mtval2)
281
282  val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle {
283    val PMM   = RO(33, 32)
284    val SSEED = RO(     9)
285    val USEED = RO(     8)
286    val RLB   = RO(     2)
287    val MMWP  = RO(     1)
288    val MML   = RO(     0)
289  })).setAddr(CSRs.mseccfg)
290
291  val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle {
292    when(w.wen) {
293      reg := w.wdata
294    }.elsewhen(!this.mcountinhibit.CY.asUInt.asBool) {
295      reg := reg.ALL.asUInt + 1.U
296    }.otherwise {
297      reg := reg
298    }
299  }).setAddr(CSRs.mcycle)
300
301
302  val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle {
303    when(w.wen) {
304      reg := w.wdata
305    }.elsewhen(!this.mcountinhibit.IR && robCommit.instNum.valid) {
306      reg := reg.ALL.asUInt + robCommit.instNum.bits
307    }.otherwise {
308      reg := reg
309    }
310  }).setAddr(CSRs.minstret)
311
312  val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
313    Module(new CSRModule(s"Mhpmcounter$num", new MhpmcounterBundle) with HasMachineCounterControlBundle with HasPerfCounterBundle {
314      val countingInhibit = this.mcountinhibit.asUInt(num) | !countingEn
315      val counterAdd = reg.ALL.asUInt +& perf.value
316      when (w.wen) {
317        reg := w.wdata
318      }.elsewhen (perf.value =/= 0.U && !countingInhibit) {
319        reg := counterAdd.tail(1)
320      }.otherwise {
321        reg := reg
322      }
323      // Count overflow never results from writes to the mhpmcountern or mhpmeventn registers, only from
324      // hardware increments of counter registers.
325      toMhpmeventOF := !countingInhibit & counterAdd.head(1)
326    }).setAddr(CSRs.mhpmcounter3 - 3 + num)
327  )
328
329  val mvendorid = Module(new CSRModule("Mvendorid") { rdata := 0.U })
330    .setAddr(CSRs.mvendorid)
331
332  // architecture id for XiangShan is 25
333  // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md
334  val marchid = Module(new CSRModule("Marchid", new CSRBundle {
335    val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid)
336  })).setAddr(CSRs.marchid)
337
338  val mimpid = Module(new CSRModule("Mimpid", new CSRBundle {
339    val ALL = RO(0).withReset(0.U)
340  }))
341    .setAddr(CSRs.mimpid)
342
343  val mhartid = Module(new CSRModule("Mhartid", new CSRBundle {
344    val ALL = RO(7, 0)
345  }) {
346    val hartid = IO(Input(UInt(hartIdLen.W)))
347    this.reg.ALL := RegEnable(hartid, reset.asBool)
348  })
349    .setAddr(CSRs.mhartid)
350
351  val mconfigptr = Module(new CSRModule("Mconfigptr", new CSRBundle {
352    val ALL = RO(63, 0)
353  }))
354    .setAddr(CSRs.mconfigptr)
355
356  val mstateen0 = Module(new CSRModule("Mstateen", new MstateenBundle0)).setAddr(CSRs.mstateen0)
357
358  // smrnmi extension
359  val mnepc = Module(new CSRModule("Mnepc", new Epc) with TrapEntryMNEventSinkBundle {
360    rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN)
361  })
362    .setAddr(CSRs.mnepc)
363
364  val mncause = Module(new CSRModule("Mncause", new CauseBundle) with TrapEntryMNEventSinkBundle)
365    .setAddr(CSRs.mncause)
366  val mnstatus = Module(new CSRModule("Mnstatus", new MnstatusBundle)
367    with TrapEntryMNEventSinkBundle
368    with MNretEventSinkBundle{
369    // NMIE write 0 with no effect
370    // as opensbi not support smrnmi, we init nmie with 1,and allow software to set nmie close for testing
371    // Attension, when set nmie to zero ,do not cause double trap when nmi interrupt has triggered
372//    when(!wdata.NMIE.asBool) {
373//      reg.NMIE := reg.NMIE
374//    }
375  }).setAddr(CSRs.mnstatus)
376  val mnscratch = Module(new CSRModule("Mnscratch"))
377    .setAddr(CSRs.mnscratch)
378
379  val machineLevelCSRMods: Seq[CSRModule[_]] = Seq(
380    mstatus,
381    misa,
382    medeleg,
383    mideleg,
384    mie,
385    mtvec,
386    mcounteren,
387    mvien,
388    mvip,
389    menvcfg,
390    mcountinhibit,
391    mscratch,
392    mepc,
393    mcause,
394    mtval,
395    mip,
396    mtinst,
397    mtval2,
398    mseccfg,
399    mcycle,
400    minstret,
401    mvendorid,
402    marchid,
403    mimpid,
404    mhartid,
405    mconfigptr,
406    mstateen0,
407    mnepc,
408    mncause,
409    mnstatus,
410    mnscratch,
411  ) ++ mhpmevents ++ mhpmcounters
412
413  val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
414    machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
415  )
416
417  val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
418    machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
419  )
420
421  // read/write/update mhpmevents -> read/write/update perfEvents
422  val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++
423    List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++
424    List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++
425    List.fill(5)(RegInit("hc0300c0300".U(XLEN.W)))
426
427  mhpmevents.foreach { mod =>
428    mod match {
429      case m: HasPerfEventBundle =>
430        m.perfEvents := perfEvents
431      case _ =>
432    }
433  }
434
435}
436
437class MstatusBundle extends CSRBundle {
438
439  val SIE  = CSRRWField     (1).withReset(0.U)
440  val MIE  = CSRRWField     (3).withReset(0.U)
441  val SPIE = CSRRWField     (5).withReset(0.U)
442  val UBE  = CSRROField     (6).withReset(0.U)
443  val MPIE = CSRRWField     (7).withReset(0.U)
444  val SPP  = CSRRWField     (8).withReset(0.U)
445  val VS   = ContextStatus  (10,  9).withReset(ContextStatus.Off)
446  val MPP  = PrivMode       (12, 11).withReset(PrivMode.U)
447  val FS   = ContextStatus  (14, 13).withReset(ContextStatus.Off)
448  val XS   = ContextStatusRO(16, 15).withReset(0.U)
449  val MPRV = CSRRWField     (17).withReset(0.U)
450  val SUM  = CSRRWField     (18).withReset(0.U)
451  val MXR  = CSRRWField     (19).withReset(0.U)
452  val TVM  = CSRRWField     (20).withReset(0.U)
453  val TW   = CSRRWField     (21).withReset(0.U)
454  val TSR  = CSRRWField     (22).withReset(0.U)
455  val UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
456  val SXL  = XLENField      (35, 34).withReset(XLENField.XLEN64)
457  val SBE  = CSRROField     (36).withReset(0.U)
458  val MBE  = CSRROField     (37).withReset(0.U)
459  val GVA  = CSRRWField     (38).withReset(0.U)
460  val MPV  = VirtMode       (39).withReset(0.U)
461  val SD   = CSRROField     (63,
462    (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
463  )
464}
465
466class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle)
467  with TrapEntryMEventSinkBundle
468  with TrapEntryHSEventSinkBundle
469  with DretEventSinkBundle
470  with MretEventSinkBundle
471  with MNretEventSinkBundle
472  with SretEventSinkBundle
473  with HasRobCommitBundle
474{
475  val mstatus = IO(Output(bundle))
476  val sstatus = IO(Output(new SstatusBundle))
477  val sstatusRdata = IO(Output(UInt(64.W)))
478
479  val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle)))
480
481  // write connection
482  this.wfn(reg)(Seq(wAliasSstatus))
483
484  when (robCommit.fsDirty || writeFCSR) {
485    assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode")
486    reg.FS := ContextStatus.Dirty
487  }
488
489  when (robCommit.vsDirty || writeVCSR) {
490    assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode")
491    reg.VS := ContextStatus.Dirty
492  }
493
494  // read connection
495  mstatus :|= reg
496  sstatus := mstatus
497  rdata := mstatus.asUInt
498  sstatusRdata := sstatus.asUInt
499}
500class MnstatusBundle extends CSRBundle {
501
502  val NMIE   = CSRRWField  (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open
503  val MNPV   = VirtMode    (7).withReset(0.U)
504  val MNPELP = CSRRWField  (9).withReset(0.U)
505  val MNPP   = PrivMode    (12, 11).withReset(PrivMode.U)
506}
507class MisaBundle extends CSRBundle {
508  // Todo: reset with ISA string
509  val A = RO( 0).withReset(1.U) // Atomic extension
510  val B = RO( 1).withReset(1.U) // B extension
511  val C = RO( 2).withReset(1.U) // Compressed extension
512  val D = RO( 3).withReset(1.U) // Double-precision floating-point extension
513  val E = RO( 4).withReset(0.U) // RV32E/64E base ISA
514  val F = RO( 5).withReset(1.U) // Single-precision floating-point extension
515  val G = RO( 6).withReset(0.U) // Reserved
516  val H = RO( 7).withReset(1.U) // Hypervisor extension
517  val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA
518  val J = RO( 9).withReset(0.U) // Reserved
519  val K = RO(10).withReset(0.U) // Reserved
520  val L = RO(11).withReset(0.U) // Reserved
521  val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi
522  val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension
523  val O = RO(14).withReset(0.U) // Reserved
524  val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension
525  val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension
526  val R = RO(17).withReset(0.U) // Reserved
527  val S = RO(18).withReset(1.U) // Supervisor mode implemented
528  val T = RO(19).withReset(0.U) // Reserved
529  val U = RO(20).withReset(1.U) // User mode implemented
530  val V = RO(21).withReset(1.U) // Vector extension
531  val W = RO(22).withReset(0.U) // Reserved
532  val X = RO(23).withReset(0.U) // Non-standard extensions present
533  val Y = RO(24).withReset(0.U) // Reserved
534  val Z = RO(25).withReset(0.U) // Reserved
535  val MXL = XLENField(63, 62).withReset(XLENField.XLEN64)
536
537  def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString
538}
539
540class MedelegBundle extends ExceptionBundle {
541  this.getALL.foreach(_.setRW().withReset(0.U))
542  this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall
543  this.EX_BP.setRO().withReset(0.U)    // Parter 5.4 in debug spec. tcontrol is implemented. medeleg [3] is hard-wired to 0.
544}
545
546class MidelegBundle extends InterruptBundle {
547  this.getALL.foreach(_.setRW().withReset(0.U))
548  // Don't delegate Machine level interrupts
549  this.getM.foreach(_.setRO().withReset(0.U))
550  // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg)
551  // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level
552  // interrupts) are each read-only one.
553  this.getVS.foreach(_.setRO().withReset(1.U))
554  // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one.
555  // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode.
556  this.SGEI.setRO().withReset(1.U)
557  this.getLocal.foreach(_.setRO().withReset(0.U))
558  this.LCOFI.setRW().withReset(0.U)
559}
560
561class MieBundle extends InterruptEnableBundle {
562  this.getNonLocal.foreach(_.setRW().withReset(0.U))
563  this.LCOFIE.setRW().withReset(0.U)
564}
565
566class MipBundle extends InterruptPendingBundle {
567  // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers
568  // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip
569  //
570  // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers,
571  // while these bits in hip are aliases for the same bits in mip.
572  //
573  // Ref: riscv interrupt spec - 2.1 Machine-level CSRs
574  // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes.
575  this.getHS.foreach(_.setRW().withReset(0.U))
576  this.getVS.foreach(_.setRW().withReset(0.U))
577  this.LCOFIP.setRW().withReset(0.U)
578}
579
580class MvienBundle extends InterruptEnableBundle {
581  // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level
582  // It is strongly recommended that bit 9 of mvien be writable.
583  // It is strongly recommended that bit 1 of mvien also be writable.
584  // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63.
585  this.SSIE.setRW().withReset(0.U)
586  this.SEIE.setRW().withReset(0.U)
587  this.getLocal.foreach(_.setRW().withReset(0.U))
588}
589
590class MvipBundle extends InterruptPendingBundle {
591  this.getHS.foreach(_.setRW().withReset(0.U))
592  this.getLocal.foreach(_.setRW().withReset(0.U))
593}
594
595class Epc extends CSRBundle {
596  val epc = RW(63, 1).withReset(0.U)
597}
598
599class McountinhibitBundle extends CSRBundle {
600  val CY = RW(0).withReset(0.U)
601  val IR = RW(2).withReset(0.U)
602  val HPM3 = RW(31, 3).withReset(0.U)
603}
604
605class Mtval2Bundle extends FieldInitBundle
606
607class MhpmcounterBundle extends FieldInitBundle
608
609// todo: for the future, delete bypass between mhpmevents and perfEvents
610class MhpmeventBundle extends CSRBundle {
611  val OF    = RW(63).withReset(0.U)
612  val MINH  = RW(62).withReset(0.U)
613  val SINH  = RW(61).withReset(0.U)
614  val UINH  = RW(60).withReset(0.U)
615  val VSINH = RW(59).withReset(0.U)
616  val VUINH = RW(58).withReset(0.U)
617}
618
619class MEnvCfg extends EnvCfg {
620  if (CSRConfig.EXT_SSTC) {
621    this.STCE.setRW().withReset(1.U)
622  }
623}
624
625object MarchidField extends CSREnum with ROApply {
626  val XSArchid = Value(25.U)
627}
628
629class MieToHie extends Bundle {
630  val VSSIE = ValidIO(RW(0))
631  val VSTIE = ValidIO(RW(0))
632  val VSEIE = ValidIO(RW(0))
633  val SGEIE = ValidIO(RW(0))
634}
635
636class MvipToMip extends IpValidBundle {
637  this.getHS.foreach(_.bits.setRW())
638}
639
640class HipToMip extends IpValidBundle {
641  // Only hip.VSSIP is writable
642  this.VSSIP.bits.setRW()
643}
644
645class VSipToMip extends IpValidBundle {
646  this.LCOFIP.bits.setRW()
647}
648
649class MipToHvip extends IpValidBundle {
650  this.VSSIP.bits.setRW()
651}
652
653class MipToMvip extends IpValidBundle {
654  this.SEIP.bits.setRW()
655}
656
657trait HasMipToAlias { self: CSRModule[_] =>
658  val mipAlias = Output(new MipBundle)
659}
660
661trait HasMachineDelegBundle { self: CSRModule[_] =>
662  val mideleg = IO(Input(new MidelegBundle))
663  val medeleg = IO(Input(new MedelegBundle))
664}
665
666trait HasExternalInterruptBundle {
667  val platformIRP = IO(new Bundle {
668    val MEIP  = Input(Bool())
669    val MTIP  = Input(Bool())
670    val MSIP  = Input(Bool())
671    val SEIP  = Input(Bool())
672    val STIP  = Input(Bool())
673    val VSEIP = Input(Bool())
674    val VSTIP = Input(Bool())
675    // debug interrupt from debug module
676    val debugIP = Input(Bool())
677  })
678}
679trait HasNonMaskableIRPBundle {
680  val nonMaskableIRP = IO(new Bundle {
681    val NMI = Input(Bool())
682  })
683}
684
685trait HasMachineCounterControlBundle { self: CSRModule[_] =>
686  val mcountinhibit = IO(Input(new McountinhibitBundle))
687}
688
689trait HasRobCommitBundle { self: CSRModule[_] =>
690  val robCommit = IO(Input(new RobCommitCSR))
691  val writeFCSR = IO(Input(Bool()))
692  val writeVCSR = IO(Input(Bool()))
693  val isVirtMode = IO(Input(Bool()))
694}
695
696trait HasMachineEnvBundle { self: CSRModule[_] =>
697  val menvcfg = IO(Input(new MEnvCfg))
698}
699
700trait HasPerfCounterBundle { self: CSRModule[_] =>
701  val countingEn    = IO(Input(Bool()))
702  val perf          = IO(Input(new PerfEvent))
703  val toMhpmeventOF = IO(Output(Bool()))
704}
705
706trait HasPerfEventBundle { self: CSRModule[_] =>
707  val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W))))
708}
709
710trait HasLocalInterruptReqBundle { self: CSRModule[_] =>
711  val lcofiReq = IO(Input(Bool()))
712}