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