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