xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision cb36ac0f37d64c496ebf443ea86082c516f12938)
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    when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid || wen) {
267      reg.LCOFIP := Mux1H(Seq(
268        fromSip.LCOFIP.valid  -> fromSip.LCOFIP.bits,
269        fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits,
270        wen -> wdata.LCOFIP,
271      ))
272    }.elsewhen(lcofiReq) {
273      reg.LCOFIP := lcofiReq
274    }
275  }).setAddr(CSRs.mip)
276
277  val mtinst = Module(new CSRModule("Mtinst", new XtinstBundle) with TrapEntryMEventSinkBundle)
278    .setAddr(CSRs.mtinst)
279
280  val mtval2 = Module(new CSRModule("Mtval2", new Mtval2Bundle) with TrapEntryMEventSinkBundle)
281    .setAddr(CSRs.mtval2)
282
283  val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle {
284    val MLPE  = RO(10) // Landing pand, Zicfilp extension
285    val SSEED = RO( 9) // Zkr extension
286    val USEED = RO( 8) // Zkr extension
287    val RLB   = RO( 2) // Smepmp
288    val MMWP  = RO( 1) // Smepmp
289    val MML   = RO( 0) // Smepmp
290  })).setAddr(CSRs.mseccfg)
291
292  val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle {
293    when(w.wen) {
294      reg := w.wdata
295    }.elsewhen(!this.mcountinhibit.CY.asUInt.asBool) {
296      reg := reg.ALL.asUInt + 1.U
297    }.otherwise {
298      reg := reg
299    }
300  }).setAddr(CSRs.mcycle)
301
302
303  val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle {
304    when(w.wen) {
305      reg := w.wdata
306    }.elsewhen(!this.mcountinhibit.IR && robCommit.instNum.valid) {
307      reg := reg.ALL.asUInt + robCommit.instNum.bits
308    }.otherwise {
309      reg := reg
310    }
311  }).setAddr(CSRs.minstret)
312
313  val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
314    Module(new CSRModule(s"Mhpmcounter$num", new MhpmcounterBundle) with HasMachineCounterControlBundle with HasPerfCounterBundle {
315      val countingInhibit = this.mcountinhibit.asUInt(num) | !countingEn
316      val counterAdd = reg.ALL.asUInt +& perf.value
317      when (w.wen) {
318        reg := w.wdata
319      }.elsewhen (perf.value =/= 0.U && !countingInhibit) {
320        reg := counterAdd.tail(1)
321      }.otherwise {
322        reg := reg
323      }
324      // Count overflow never results from writes to the mhpmcountern or mhpmeventn registers, only from
325      // hardware increments of counter registers.
326      toMhpmeventOF := !countingInhibit & counterAdd.head(1)
327    }).setAddr(CSRs.mhpmcounter3 - 3 + num)
328  )
329
330  val mvendorid = Module(new CSRModule("Mvendorid") { rdata := 0.U })
331    .setAddr(CSRs.mvendorid)
332
333  // architecture id for XiangShan is 25
334  // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md
335  val marchid = Module(new CSRModule("Marchid", new CSRBundle {
336    val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid)
337  })).setAddr(CSRs.marchid)
338
339  val mimpid = Module(new CSRModule("Mimpid", new CSRBundle {
340    val ALL = RO(0).withReset(0.U)
341  }))
342    .setAddr(CSRs.mimpid)
343
344  val mhartid = Module(new CSRModule("Mhartid", new CSRBundle {
345    val ALL = RO(7, 0)
346  }) {
347    val hartid = IO(Input(UInt(hartIdLen.W)))
348    this.reg.ALL := RegEnable(hartid, reset.asBool)
349  })
350    .setAddr(CSRs.mhartid)
351
352  val mconfigptr = Module(new CSRModule("Mconfigptr", new CSRBundle {
353    val ALL = RO(63, 0)
354  }))
355    .setAddr(CSRs.mconfigptr)
356
357  val mstateen0 = Module(new CSRModule("Mstateen", new MstateenBundle0)).setAddr(CSRs.mstateen0)
358
359  // smrnmi extension
360  val mnepc = Module(new CSRModule("Mnepc", new Epc) with TrapEntryMNEventSinkBundle {
361    rdata := SignExt(Cat(reg.epc.asUInt, 0.U(1.W)), XLEN)
362  })
363    .setAddr(CSRs.mnepc)
364
365  val mncause = Module(new CSRModule("Mncause", new CauseBundle) with TrapEntryMNEventSinkBundle)
366    .setAddr(CSRs.mncause)
367  val mnstatus = Module(new CSRModule("Mnstatus", new MnstatusBundle)
368    with TrapEntryMNEventSinkBundle
369    with MNretEventSinkBundle{
370    // NMIE write 0 with no effect
371    // as opensbi not support smrnmi, we init nmie with 1,and allow software to set nmie close for testing
372    // Attension, when set nmie to zero ,do not cause double trap when nmi interrupt has triggered
373//    when(!wdata.NMIE.asBool) {
374//      reg.NMIE := reg.NMIE
375//    }
376  }).setAddr(CSRs.mnstatus)
377  val mnscratch = Module(new CSRModule("Mnscratch"))
378    .setAddr(CSRs.mnscratch)
379
380  val machineLevelCSRMods: Seq[CSRModule[_]] = Seq(
381    mstatus,
382    misa,
383    medeleg,
384    mideleg,
385    mie,
386    mtvec,
387    mcounteren,
388    mvien,
389    mvip,
390    menvcfg,
391    mcountinhibit,
392    mscratch,
393    mepc,
394    mcause,
395    mtval,
396    mip,
397    mtinst,
398    mtval2,
399    mseccfg,
400    mcycle,
401    minstret,
402    mvendorid,
403    marchid,
404    mimpid,
405    mhartid,
406    mconfigptr,
407    mstateen0,
408    mnepc,
409    mncause,
410    mnstatus,
411    mnscratch,
412  ) ++ mhpmevents ++ mhpmcounters
413
414  val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
415    machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
416  )
417
418  val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
419    machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
420  )
421
422  // read/write/update mhpmevents -> read/write/update perfEvents
423  val perfEvents = List.fill(8)(RegInit("h0000000000".U(XLEN.W))) ++
424    List.fill(8)(RegInit("h4010040100".U(XLEN.W))) ++
425    List.fill(8)(RegInit("h8020080200".U(XLEN.W))) ++
426    List.fill(5)(RegInit("hc0300c0300".U(XLEN.W)))
427
428  mhpmevents.foreach { mod =>
429    mod match {
430      case m: HasPerfEventBundle =>
431        m.perfEvents := perfEvents
432      case _ =>
433    }
434  }
435
436}
437
438class MstatusBundle extends CSRBundle {
439
440  val SIE  = CSRRWField     (1).withReset(0.U)
441  val MIE  = CSRRWField     (3).withReset(0.U)
442  val SPIE = CSRRWField     (5).withReset(0.U)
443  val UBE  = CSRROField     (6).withReset(0.U)
444  val MPIE = CSRRWField     (7).withReset(0.U)
445  val SPP  = CSRRWField     (8).withReset(0.U)
446  val VS   = ContextStatus  (10,  9).withReset(ContextStatus.Off)
447  val MPP  = PrivMode       (12, 11).withReset(PrivMode.U)
448  val FS   = ContextStatus  (14, 13).withReset(ContextStatus.Off)
449  val XS   = ContextStatusRO(16, 15).withReset(0.U)
450  val MPRV = CSRRWField     (17).withReset(0.U)
451  val SUM  = CSRRWField     (18).withReset(0.U)
452  val MXR  = CSRRWField     (19).withReset(0.U)
453  val TVM  = CSRRWField     (20).withReset(0.U)
454  val TW   = CSRRWField     (21).withReset(0.U)
455  val TSR  = CSRRWField     (22).withReset(0.U)
456  val UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
457  val SXL  = XLENField      (35, 34).withReset(XLENField.XLEN64)
458  val SBE  = CSRROField     (36).withReset(0.U)
459  val MBE  = CSRROField     (37).withReset(0.U)
460  val GVA  = CSRRWField     (38).withReset(0.U)
461  val MPV  = VirtMode       (39).withReset(0.U)
462  val SD   = CSRROField     (63,
463    (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
464  )
465}
466
467class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle)
468  with TrapEntryMEventSinkBundle
469  with TrapEntryHSEventSinkBundle
470  with DretEventSinkBundle
471  with MretEventSinkBundle
472  with MNretEventSinkBundle
473  with SretEventSinkBundle
474  with HasRobCommitBundle
475{
476  val mstatus = IO(Output(bundle))
477  val sstatus = IO(Output(new SstatusBundle))
478  val sstatusRdata = IO(Output(UInt(64.W)))
479
480  val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle)))
481  for ((name, field) <- wAliasSstatus.wdataFields.elements) {
482    reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate(
483      wAliasSstatus.wen && field.asInstanceOf[CSREnumType].isLegal,
484      field.asInstanceOf[CSREnumType]
485    )
486  }
487
488  // write connection
489  reconnectReg()
490
491  when (robCommit.fsDirty || writeFCSR) {
492    assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode")
493    reg.FS := ContextStatus.Dirty
494  }
495
496  when (robCommit.vsDirty || writeVCSR) {
497    assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode")
498    reg.VS := ContextStatus.Dirty
499  }
500
501  // read connection
502  mstatus :|= reg
503  sstatus := mstatus
504  rdata := mstatus.asUInt
505  sstatusRdata := sstatus.asUInt
506}
507
508class MnstatusBundle extends CSRBundle {
509  val NMIE   = CSRRWField  (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open
510  val MNPV   = VirtMode    (7).withReset(0.U)
511  val MNPELP = RO          (9).withReset(0.U)
512  val MNPP   = PrivMode    (12, 11).withReset(PrivMode.U)
513}
514
515class MisaBundle extends CSRBundle {
516  // Todo: reset with ISA string
517  val A = RO( 0).withReset(1.U) // Atomic extension
518  val B = RO( 1).withReset(1.U) // B extension
519  val C = RO( 2).withReset(1.U) // Compressed extension
520  val D = RO( 3).withReset(1.U) // Double-precision floating-point extension
521  val E = RO( 4).withReset(0.U) // RV32E/64E base ISA
522  val F = RO( 5).withReset(1.U) // Single-precision floating-point extension
523  val G = RO( 6).withReset(0.U) // Reserved
524  val H = RO( 7).withReset(1.U) // Hypervisor extension
525  val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA
526  val J = RO( 9).withReset(0.U) // Reserved
527  val K = RO(10).withReset(0.U) // Reserved
528  val L = RO(11).withReset(0.U) // Reserved
529  val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi
530  val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension
531  val O = RO(14).withReset(0.U) // Reserved
532  val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension
533  val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension
534  val R = RO(17).withReset(0.U) // Reserved
535  val S = RO(18).withReset(1.U) // Supervisor mode implemented
536  val T = RO(19).withReset(0.U) // Reserved
537  val U = RO(20).withReset(1.U) // User mode implemented
538  val V = RO(21).withReset(1.U) // Vector extension
539  val W = RO(22).withReset(0.U) // Reserved
540  val X = RO(23).withReset(0.U) // Non-standard extensions present
541  val Y = RO(24).withReset(0.U) // Reserved
542  val Z = RO(25).withReset(0.U) // Reserved
543  val MXL = XLENField(63, 62).withReset(XLENField.XLEN64)
544
545  def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString
546}
547
548class MedelegBundle extends ExceptionBundle {
549  this.getALL.foreach(_.setRW().withReset(0.U))
550  this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall
551  this.EX_BP.setRO().withReset(0.U)    // Parter 5.4 in debug spec. tcontrol is implemented. medeleg [3] is hard-wired to 0.
552}
553
554class MidelegBundle extends InterruptBundle {
555  this.getALL.foreach(_.setRW().withReset(0.U))
556  // Don't delegate Machine level interrupts
557  this.getM.foreach(_.setRO().withReset(0.U))
558  // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg)
559  // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level
560  // interrupts) are each read-only one.
561  this.getVS.foreach(_.setRO().withReset(1.U))
562  // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one.
563  // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode.
564  this.SGEI.setRO().withReset(1.U)
565  this.getLocal.foreach(_.setRO().withReset(0.U))
566  this.LCOFI.setRW().withReset(0.U)
567}
568
569class MieBundle extends InterruptEnableBundle {
570  this.getNonLocal.foreach(_.setRW().withReset(0.U))
571  this.LCOFIE.setRW().withReset(0.U)
572}
573
574class MipBundle extends InterruptPendingBundle {
575  // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers
576  // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip
577  //
578  // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers,
579  // while these bits in hip are aliases for the same bits in mip.
580  //
581  // Ref: riscv interrupt spec - 2.1 Machine-level CSRs
582  // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes.
583  this.getHS.foreach(_.setRW().withReset(0.U))
584  this.getVS.foreach(_.setRW().withReset(0.U))
585  this.LCOFIP.setRW().withReset(0.U)
586}
587
588class MvienBundle extends InterruptEnableBundle {
589  // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level
590  // It is strongly recommended that bit 9 of mvien be writable.
591  // It is strongly recommended that bit 1 of mvien also be writable.
592  // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63.
593  this.SSIE.setRW().withReset(0.U)
594  this.SEIE.setRW().withReset(0.U)
595  this.getLocal.foreach(_.setRW().withReset(0.U))
596}
597
598class MvipBundle extends InterruptPendingBundle {
599  this.getHS.foreach(_.setRW().withReset(0.U))
600  this.getLocal.foreach(_.setRW().withReset(0.U))
601}
602
603class Epc extends CSRBundle {
604  val epc = RW(63, 1).withReset(0.U)
605}
606
607class McountinhibitBundle extends CSRBundle {
608  val CY = RW(0).withReset(0.U)
609  val IR = RW(2).withReset(0.U)
610  val HPM3 = RW(31, 3).withReset(0.U)
611}
612
613class Mtval2Bundle extends FieldInitBundle
614
615class MhpmcounterBundle extends FieldInitBundle
616
617// todo: for the future, delete bypass between mhpmevents and perfEvents
618class MhpmeventBundle extends CSRBundle {
619  val OF    = RW(63).withReset(0.U)
620  val MINH  = RW(62).withReset(0.U)
621  val SINH  = RW(61).withReset(0.U)
622  val UINH  = RW(60).withReset(0.U)
623  val VSINH = RW(59).withReset(0.U)
624  val VUINH = RW(58).withReset(0.U)
625}
626
627class MEnvCfg extends EnvCfg {
628  if (CSRConfig.EXT_SSTC) {
629    this.STCE.setRW().withReset(1.U)
630  }
631  this.PBMTE.setRW().withReset(0.U)
632}
633
634object MarchidField extends CSREnum with ROApply {
635  val XSArchid = Value(25.U)
636}
637
638class MieToHie extends Bundle {
639  val VSSIE = ValidIO(RW(0))
640  val VSTIE = ValidIO(RW(0))
641  val VSEIE = ValidIO(RW(0))
642  val SGEIE = ValidIO(RW(0))
643}
644
645class MvipToMip extends IpValidBundle {
646  this.getHS.foreach(_.bits.setRW())
647}
648
649class HipToMip extends IpValidBundle {
650  // Only hip.VSSIP is writable
651  this.VSSIP.bits.setRW()
652}
653
654class VSipToMip extends IpValidBundle {
655  this.LCOFIP.bits.setRW()
656}
657
658class MipToHvip extends IpValidBundle {
659  this.VSSIP.bits.setRW()
660}
661
662class MipToMvip extends IpValidBundle {
663  this.SEIP.bits.setRW()
664}
665
666trait HasMipToAlias { self: CSRModule[_] =>
667  val mipAlias = Output(new MipBundle)
668}
669
670trait HasMachineDelegBundle { self: CSRModule[_] =>
671  val mideleg = IO(Input(new MidelegBundle))
672  val medeleg = IO(Input(new MedelegBundle))
673}
674
675trait HasExternalInterruptBundle {
676  val platformIRP = IO(new Bundle {
677    val MEIP  = Input(Bool())
678    val MTIP  = Input(Bool())
679    val MSIP  = Input(Bool())
680    val SEIP  = Input(Bool())
681    val STIP  = Input(Bool())
682    val VSEIP = Input(Bool())
683    val VSTIP = Input(Bool())
684    // debug interrupt from debug module
685    val debugIP = Input(Bool())
686  })
687}
688trait HasNonMaskableIRPBundle {
689  val nonMaskableIRP = IO(new Bundle {
690    val NMI = Input(Bool())
691  })
692}
693
694trait HasMachineCounterControlBundle { self: CSRModule[_] =>
695  val mcountinhibit = IO(Input(new McountinhibitBundle))
696}
697
698trait HasRobCommitBundle { self: CSRModule[_] =>
699  val robCommit = IO(Input(new RobCommitCSR))
700  val writeFCSR = IO(Input(Bool()))
701  val writeVCSR = IO(Input(Bool()))
702  val isVirtMode = IO(Input(Bool()))
703}
704
705trait HasMachineEnvBundle { self: CSRModule[_] =>
706  val menvcfg = IO(Input(new MEnvCfg))
707}
708
709trait HasPerfCounterBundle { self: CSRModule[_] =>
710  val countingEn    = IO(Input(Bool()))
711  val perf          = IO(Input(new PerfEvent))
712  val toMhpmeventOF = IO(Output(Bool()))
713}
714
715trait HasPerfEventBundle { self: CSRModule[_] =>
716  val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W))))
717}
718
719trait HasLocalInterruptReqBundle { self: CSRModule[_] =>
720  val lcofiReq = IO(Input(Bool()))
721}