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