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