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