xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision 85a8d7ca95be7636399af9f3c39382ab20231da7)
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.wNoEffectWhen
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") with HasPerfEventBundle {
169      regOut := this.perfEvents(num - 3)
170    })
171      .setAddr(CSRs.mhpmevent3 - 3 + num)
172  )
173
174  val mscratch = Module(new CSRModule("Mscratch"))
175    .setAddr(CSRs.mscratch)
176
177  val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle)
178    .setAddr(CSRs.mepc)
179
180  val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle)
181    .setAddr(CSRs.mcause)
182
183  val mtval = Module(new CSRModule("Mtval", new XtvalBundle) with TrapEntryMEventSinkBundle)
184    .setAddr(CSRs.mtval)
185
186  val mip = Module(new CSRModule("Mip", new MipBundle)
187    with HasIpIeBundle
188    with HasExternalInterruptBundle
189    with HasMachineEnvBundle
190    with HasLocalInterruptReqBundle
191    with HasAIABundle
192  {
193    // Alias write in
194    val fromMvip = IO(Flipped(new MvipToMip))
195    val fromSip  = IO(Flipped(new SipToMip))
196    val fromVSip = IO(Flipped(new VSipToMip))
197    // Alias write out
198    val toMvip   = IO(new MipToMvip).connectZeroNonRW
199    val toHvip   = IO(new MipToHvip).connectZeroNonRW
200
201    // bit 1 SSIP
202    when (fromMvip.SSIP.valid || fromSip.SSIP.valid) {
203      reg.SSIP := Mux1H(Seq(
204        fromMvip.SSIP.valid -> fromMvip.SSIP.bits,
205        fromSip .SSIP.valid -> fromSip .SSIP.bits,
206      ))
207    }
208
209    // bit 2 VSSIP reg in hvip
210    // alias of hvip.VSSIP
211    toHvip.VSSIP.valid := wen
212    toHvip.VSSIP.bits  := wdata.VSSIP
213    regOut.VSSIP := hvip.VSSIP
214
215    // bit 3 MSIP is read-only in mip, and is written by accesses to memory-mapped control registers,
216    // which are used by remote harts to provide machine-level interprocessor interrupts.
217    regOut.MSIP := platformIRP.MSIP
218
219    // bit 5 STIP
220    // If the stimecmp (supervisor-mode timer compare) register is implemented(menvcfg.STCE=1), STIP is read-only in mip.
221    regOut.STIP := Mux(this.menvcfg.STCE.asBool, platformIRP.STIP, reg.STIP.asBool)
222    when ((wen || fromMvip.STIP.valid) && !this.menvcfg.STCE) {
223      reg.STIP := Mux1H(Seq(
224        wen -> wdata.STIP,
225        fromMvip.STIP.valid -> fromMvip.STIP.bits,
226      ))
227    }
228
229    // bit 6 VSTIP
230    regOut.VSTIP := hvip.VSTIP || platformIRP.VSTIP
231
232    // bit 7 MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register
233    regOut.MTIP := platformIRP.MTIP
234
235    // bit 9 SEIP
236    // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP.
237    // 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.
238    //
239    // As explained in this issue(https://github.com/riscv/riscv-aia/issues/64),
240    // when mvien[9]=0, mip.SEIP is a software-writable bit and is special in its read value, which is the logical-OR of
241    // mip.SEIP reg and other source from the interrupt controller.
242    // mvip.SEIP is alias of mip.SEIP's reg part, and is independent of the other source from the interrupt controller.
243    //
244    // mip.SEIP is implemented as the alias of mvip.SEIP when mvien=0
245    // the read valid of SEIP is ORed by mvip.SEIP and the other source from the interrupt controller.
246
247    toMvip.SEIP.valid := wen && !this.mvien.SSIE
248    toMvip.SEIP.bits := wdata.SEIP
249    // When mvien.SEIE = 0, mip.SEIP is alias of mvip.SEIP.
250    // Otherwise, mip.SEIP is read only 0
251    regOut.SEIP := Mux(!this.mvien.SEIE, this.mvip.SEIP.asUInt, 0.U)
252    rdataFields.SEIP := regOut.SEIP || platformIRP.SEIP || aiaToCSR.seip
253
254    // bit 10 VSEIP
255    regOut.VSEIP := hvip.VSEIP || platformIRP.VSEIP || hgeip.asUInt(hstatusVGEIN.asUInt)
256
257    // bit 11 MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller.
258    // MEIP can from PLIC and IMSIC
259    regOut.MEIP := platformIRP.MEIP || aiaToCSR.meip
260
261    // bit 12 SGEIP
262    regOut.SGEIP := Cat(hgeip.asUInt & hgeie.asUInt).orR
263
264    // bit 13 LCOFIP
265    when (fromSip.LCOFIP.valid || fromVSip.LCOFIP.valid || wen) {
266      reg.LCOFIP := Mux1H(Seq(
267        fromSip.LCOFIP.valid  -> fromSip.LCOFIP.bits,
268        fromVSip.LCOFIP.valid -> fromVSip.LCOFIP.bits,
269        wen -> wdata.LCOFIP,
270      ))
271    }.elsewhen(lcofiReq) {
272      reg.LCOFIP := lcofiReq
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 MLPE  = RO(10) // Landing pand, Zicfilp extension
284    val SSEED = RO( 9) // Zkr extension
285    val USEED = RO( 8) // Zkr extension
286    val RLB   = RO( 2) // Smepmp
287    val MMWP  = RO( 1) // Smepmp
288    val MML   = RO( 0) // Smepmp
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(hartIdLen - 1, 0)
345  }) {
346    val hartid = IO(Input(UInt(hartIdLen.W)))
347    this.regOut.ALL := hartid
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 SDT  = CSRRWField     (24).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 MDT  = CSRRWField     (42).withReset(mdtInit.U)
463  val SD   = CSRROField     (63,
464    (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
465  )
466}
467
468class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle)
469  with TrapEntryMEventSinkBundle
470  with TrapEntryHSEventSinkBundle
471  with DretEventSinkBundle
472  with MretEventSinkBundle
473  with MNretEventSinkBundle
474  with SretEventSinkBundle
475  with HasRobCommitBundle
476  with HasMachineEnvBundle
477{
478  val mstatus = IO(Output(bundle))
479  val sstatus = IO(Output(new SstatusBundle))
480  val sstatusRdata = IO(Output(UInt(64.W)))
481
482  val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle)))
483  for ((name, field) <- wAliasSstatus.wdataFields.elements) {
484    reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate(
485      wAliasSstatus.wen && field.asInstanceOf[CSREnumType].isLegal,
486      field.asInstanceOf[CSREnumType]
487    )
488  }
489
490  // write connection
491  reconnectReg()
492
493  when (robCommit.fsDirty || writeFCSR) {
494    assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode")
495    reg.FS := ContextStatus.Dirty
496  }
497
498  when (robCommit.vsDirty || writeVCSR) {
499    assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode")
500    reg.VS := ContextStatus.Dirty
501  }
502  // when MDT is explicitly written by 1, clear MIE
503  // only when reg.MDT is zero or wdata.MDT is zero , MIE can be explicitly written by 1
504  when (w.wdataFields.MDT && w.wen) {
505    reg.MIE := false.B
506  }
507  // when DTE is zero, SDT field is read-only zero(write any, read zero, side effect of write 1 is block)
508  val writeSDT = Wire(Bool())
509  writeSDT := Mux(this.menvcfg.DTE.asBool, (w.wdataFields.SDT && w.wen) || (wAliasSstatus.wdataFields.SDT && wAliasSstatus.wen), 0.U)
510  when (!this.menvcfg.DTE) {
511    regOut.SDT := false.B
512  }
513  // SDT and SIE is the same as MDT and MIE
514  when (writeSDT) {
515    reg.SIE := false.B
516  }
517  // read connection
518  mstatus :|= regOut
519  sstatus := mstatus
520  rdata := mstatus.asUInt
521  sstatusRdata := sstatus.asUInt
522}
523
524class MnstatusBundle extends CSRBundle {
525  val NMIE   = CSRRWField  (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open
526  val MNPV   = VirtMode    (7).withReset(0.U)
527  val MNPELP = RO          (9).withReset(0.U)
528  val MNPP   = PrivMode    (12, 11).withReset(PrivMode.U)
529}
530
531class MisaBundle extends CSRBundle {
532  // Todo: reset with ISA string
533  val A = RO( 0).withReset(1.U) // Atomic extension
534  val B = RO( 1).withReset(1.U) // B extension
535  val C = RO( 2).withReset(1.U) // Compressed extension
536  val D = RO( 3).withReset(1.U) // Double-precision floating-point extension
537  val E = RO( 4).withReset(0.U) // RV32E/64E base ISA
538  val F = RO( 5).withReset(1.U) // Single-precision floating-point extension
539  val G = RO( 6).withReset(0.U) // Reserved
540  val H = RO( 7).withReset(1.U) // Hypervisor extension
541  val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA
542  val J = RO( 9).withReset(0.U) // Reserved
543  val K = RO(10).withReset(0.U) // Reserved
544  val L = RO(11).withReset(0.U) // Reserved
545  val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi
546  val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension
547  val O = RO(14).withReset(0.U) // Reserved
548  val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension
549  val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension
550  val R = RO(17).withReset(0.U) // Reserved
551  val S = RO(18).withReset(1.U) // Supervisor mode implemented
552  val T = RO(19).withReset(0.U) // Reserved
553  val U = RO(20).withReset(1.U) // User mode implemented
554  val V = RO(21).withReset(1.U) // Vector extension
555  val W = RO(22).withReset(0.U) // Reserved
556  val X = RO(23).withReset(0.U) // Non-standard extensions present
557  val Y = RO(24).withReset(0.U) // Reserved
558  val Z = RO(25).withReset(0.U) // Reserved
559  val MXL = XLENField(63, 62).withReset(XLENField.XLEN64)
560
561  def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString
562}
563
564class MedelegBundle extends ExceptionBundle {
565  this.getALL.foreach(_.setRW().withReset(0.U))
566  this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall
567  this.EX_DBLTRP.setRO().withReset(0.U)// double trap is not delegatable
568}
569
570class MidelegBundle extends InterruptBundle {
571  this.getALL.foreach(_.setRW().withReset(0.U))
572  // Don't delegate Machine level interrupts
573  this.getM.foreach(_.setRO().withReset(0.U))
574  // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg)
575  // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level
576  // interrupts) are each read-only one.
577  this.getVS.foreach(_.setRO().withReset(1.U))
578  // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one.
579  // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode.
580  this.SGEI.setRO().withReset(1.U)
581  this.getLocal.foreach(_.setRO().withReset(0.U))
582  this.LCOFI.setRW().withReset(0.U)
583}
584
585class MieBundle extends InterruptEnableBundle {
586  this.getNonLocal.foreach(_.setRW().withReset(0.U))
587  this.LCOFIE.setRW().withReset(0.U)
588}
589
590class MipBundle extends InterruptPendingBundle {
591  // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers
592  // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip
593  //
594  // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers,
595  // while these bits in hip are aliases for the same bits in mip.
596  //
597  // Ref: riscv interrupt spec - 2.1 Machine-level CSRs
598  // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes.
599  this.getHS.foreach(_.setRW().withReset(0.U))
600  this.getVS.foreach(_.setRW().withReset(0.U))
601  this.LCOFIP.setRW().withReset(0.U)
602}
603
604class MvienBundle extends InterruptEnableBundle {
605  // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level
606  // It is strongly recommended that bit 9 of mvien be writable.
607  // It is strongly recommended that bit 1 of mvien also be writable.
608  // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63.
609  this.SSIE.setRW().withReset(0.U)
610  this.SEIE.setRW().withReset(0.U)
611  this.getLocal.foreach(_.setRW().withReset(0.U))
612}
613
614class MvipBundle extends InterruptPendingBundle {
615  this.getHS.foreach(_.setRW().withReset(0.U))
616  this.getLocal.foreach(_.setRW().withReset(0.U))
617}
618
619class Epc extends CSRBundle {
620  val epc = RW(63, 1).withReset(0.U)
621}
622
623class McountinhibitBundle extends CSRBundle {
624  val CY = RW(0).withReset(0.U)
625  val IR = RW(2).withReset(0.U)
626  val HPM3 = RW(31, 3).withReset(0.U)
627}
628
629class Mtval2Bundle extends FieldInitBundle
630
631class MhpmcounterBundle extends FieldInitBundle
632
633// todo: for the future, delete bypass between mhpmevents and perfEvents
634class MhpmeventBundle extends CSRBundle {
635  val OF    = RW(63).withReset(0.U)
636  val MINH  = RW(62).withReset(0.U)
637  val SINH  = RW(61).withReset(0.U)
638  val UINH  = RW(60).withReset(0.U)
639  val VSINH = RW(59).withReset(0.U)
640  val VUINH = RW(58).withReset(0.U)
641}
642
643class MEnvCfg extends EnvCfg {
644  if (CSRConfig.EXT_SSTC) {
645    this.STCE.setRW().withReset(1.U)
646  }
647  this.PBMTE.setRW().withReset(0.U)
648  if (CSRConfig.EXT_DBLTRP) {
649    // software write envcfg to open ssdbltrp if need
650    // set 0 to pass ci
651    this.DTE.setRW().withReset(0.U)
652  }
653}
654
655object MarchidField extends CSREnum with ROApply {
656  val XSArchid = Value(25.U)
657}
658
659class MieToHie extends Bundle {
660  val VSSIE = ValidIO(RW(0))
661  val VSTIE = ValidIO(RW(0))
662  val VSEIE = ValidIO(RW(0))
663  val SGEIE = ValidIO(RW(0))
664}
665
666class MvipToMip extends IpValidBundle {
667  this.getHS.foreach(_.bits.setRW())
668}
669
670class HipToMip extends IpValidBundle {
671  // Only hip.VSSIP is writable
672  this.VSSIP.bits.setRW()
673}
674
675class VSipToMip extends IpValidBundle {
676  this.LCOFIP.bits.setRW()
677}
678
679class MipToHvip extends IpValidBundle {
680  this.VSSIP.bits.setRW()
681}
682
683class MipToMvip extends IpValidBundle {
684  this.SEIP.bits.setRW()
685}
686
687trait HasMipToAlias { self: CSRModule[_] =>
688  val mipAlias = Output(new MipBundle)
689}
690
691trait HasMachineDelegBundle { self: CSRModule[_] =>
692  val mideleg = IO(Input(new MidelegBundle))
693  val medeleg = IO(Input(new MedelegBundle))
694}
695
696trait HasExternalInterruptBundle {
697  val platformIRP = IO(new Bundle {
698    val MEIP  = Input(Bool())
699    val MTIP  = Input(Bool())
700    val MSIP  = Input(Bool())
701    val SEIP  = Input(Bool())
702    val STIP  = Input(Bool())
703    val VSEIP = Input(Bool())
704    val VSTIP = Input(Bool())
705    // debug interrupt from debug module
706    val debugIP = Input(Bool())
707  })
708}
709trait HasNonMaskableIRPBundle {
710  val nonMaskableIRP = IO(new Bundle {
711    val NMI_43 = Input(Bool())
712    val NMI_31 = Input(Bool())
713  })
714}
715
716trait HasMachineCounterControlBundle { self: CSRModule[_] =>
717  val mcountinhibit = IO(Input(new McountinhibitBundle))
718}
719
720trait HasRobCommitBundle { self: CSRModule[_] =>
721  val robCommit = IO(Input(new RobCommitCSR))
722  val writeFCSR = IO(Input(Bool()))
723  val writeVCSR = IO(Input(Bool()))
724  val isVirtMode = IO(Input(Bool()))
725}
726
727trait HasMachineEnvBundle { self: CSRModule[_] =>
728  val menvcfg = IO(Input(new MEnvCfg))
729}
730
731trait HasPerfCounterBundle { self: CSRModule[_] =>
732  val countingEn    = IO(Input(Bool()))
733  val perf          = IO(Input(new PerfEvent))
734  val toMhpmeventOF = IO(Output(Bool()))
735}
736
737trait HasPerfEventBundle { self: CSRModule[_] =>
738  val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W))))
739}
740
741trait HasLocalInterruptReqBundle { self: CSRModule[_] =>
742  val lcofiReq = IO(Input(Bool()))
743}