xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision 1bc48dd1fa0af361fd194c65bad3b86349ec2903)
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 UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
456  val SXL  = XLENField      (35, 34).withReset(XLENField.XLEN64)
457  val SBE  = CSRROField     (36).withReset(0.U)
458  val MBE  = CSRROField     (37).withReset(0.U)
459  val GVA  = CSRRWField     (38).withReset(0.U)
460  val MPV  = VirtMode       (39).withReset(0.U)
461  val SD   = CSRROField     (63,
462    (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
463  )
464}
465
466class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle)
467  with TrapEntryMEventSinkBundle
468  with TrapEntryHSEventSinkBundle
469  with DretEventSinkBundle
470  with MretEventSinkBundle
471  with MNretEventSinkBundle
472  with SretEventSinkBundle
473  with HasRobCommitBundle
474{
475  val mstatus = IO(Output(bundle))
476  val sstatus = IO(Output(new SstatusBundle))
477  val sstatusRdata = IO(Output(UInt(64.W)))
478
479  val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle)))
480  for ((name, field) <- wAliasSstatus.wdataFields.elements) {
481    reg.elements(name).asInstanceOf[CSREnumType].addOtherUpdate(
482      wAliasSstatus.wen && field.asInstanceOf[CSREnumType].isLegal,
483      field.asInstanceOf[CSREnumType]
484    )
485  }
486
487  // write connection
488  reconnectReg()
489
490  when (robCommit.fsDirty || writeFCSR) {
491    assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode")
492    reg.FS := ContextStatus.Dirty
493  }
494
495  when (robCommit.vsDirty || writeVCSR) {
496    assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode")
497    reg.VS := ContextStatus.Dirty
498  }
499
500  // read connection
501  mstatus :|= reg
502  sstatus := mstatus
503  rdata := mstatus.asUInt
504  sstatusRdata := sstatus.asUInt
505}
506
507class MnstatusBundle extends CSRBundle {
508  val NMIE   = CSRRWField  (3).withReset(1.U) // as opensbi not support smrnmi, we init nmie open
509  val MNPV   = VirtMode    (7).withReset(0.U)
510  val MNPELP = RO          (9).withReset(0.U)
511  val MNPP   = PrivMode    (12, 11).withReset(PrivMode.U)
512}
513
514class MisaBundle extends CSRBundle {
515  // Todo: reset with ISA string
516  val A = RO( 0).withReset(1.U) // Atomic extension
517  val B = RO( 1).withReset(1.U) // B extension
518  val C = RO( 2).withReset(1.U) // Compressed extension
519  val D = RO( 3).withReset(1.U) // Double-precision floating-point extension
520  val E = RO( 4).withReset(0.U) // RV32E/64E base ISA
521  val F = RO( 5).withReset(1.U) // Single-precision floating-point extension
522  val G = RO( 6).withReset(0.U) // Reserved
523  val H = RO( 7).withReset(1.U) // Hypervisor extension
524  val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA
525  val J = RO( 9).withReset(0.U) // Reserved
526  val K = RO(10).withReset(0.U) // Reserved
527  val L = RO(11).withReset(0.U) // Reserved
528  val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi
529  val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension
530  val O = RO(14).withReset(0.U) // Reserved
531  val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension
532  val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension
533  val R = RO(17).withReset(0.U) // Reserved
534  val S = RO(18).withReset(1.U) // Supervisor mode implemented
535  val T = RO(19).withReset(0.U) // Reserved
536  val U = RO(20).withReset(1.U) // User mode implemented
537  val V = RO(21).withReset(1.U) // Vector extension
538  val W = RO(22).withReset(0.U) // Reserved
539  val X = RO(23).withReset(0.U) // Non-standard extensions present
540  val Y = RO(24).withReset(0.U) // Reserved
541  val Z = RO(25).withReset(0.U) // Reserved
542  val MXL = XLENField(63, 62).withReset(XLENField.XLEN64)
543
544  def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString
545}
546
547class MedelegBundle extends ExceptionBundle {
548  this.getALL.foreach(_.setRW().withReset(0.U))
549  this.EX_MCALL.setRO().withReset(0.U) // never delegate machine level ecall
550  this.EX_DBLTRP.setRO().withReset(0.U)// double trap is not delegatable
551}
552
553class MidelegBundle extends InterruptBundle {
554  this.getALL.foreach(_.setRW().withReset(0.U))
555  // Don't delegate Machine level interrupts
556  this.getM.foreach(_.setRO().withReset(0.U))
557  // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg)
558  // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level
559  // interrupts) are each read-only one.
560  this.getVS.foreach(_.setRO().withReset(1.U))
561  // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one.
562  // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode.
563  this.SGEI.setRO().withReset(1.U)
564  this.getLocal.foreach(_.setRO().withReset(0.U))
565  this.LCOFI.setRW().withReset(0.U)
566}
567
568class MieBundle extends InterruptEnableBundle {
569  this.getNonLocal.foreach(_.setRW().withReset(0.U))
570  this.LCOFIE.setRW().withReset(0.U)
571}
572
573class MipBundle extends InterruptPendingBundle {
574  // Ref: riscv privileged spec - 18.4.3. Machine Interrupt (mip and mie) Registers
575  // Bits SGEIP, VSEIP, VSTIP, and VSSIP in mip are aliases for the same bits in hypervisor CSR hip
576  //
577  // We implement SGEIP, VSEIP, VSTIP, and VSSIP in mip are registers,
578  // while these bits in hip are aliases for the same bits in mip.
579  //
580  // Ref: riscv interrupt spec - 2.1 Machine-level CSRs
581  // Existing CSRs mie, mip, and mideleg are widended to 64 bits to support a total of 64 interrupt causes.
582  this.getHS.foreach(_.setRW().withReset(0.U))
583  this.getVS.foreach(_.setRW().withReset(0.U))
584  this.LCOFIP.setRW().withReset(0.U)
585}
586
587class MvienBundle extends InterruptEnableBundle {
588  // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level
589  // It is strongly recommended that bit 9 of mvien be writable.
590  // It is strongly recommended that bit 1 of mvien also be writable.
591  // A bit in mvien can be set to 1 only for major interrupts 1, 9, and 13–63.
592  this.SSIE.setRW().withReset(0.U)
593  this.SEIE.setRW().withReset(0.U)
594  this.getLocal.foreach(_.setRW().withReset(0.U))
595}
596
597class MvipBundle extends InterruptPendingBundle {
598  this.getHS.foreach(_.setRW().withReset(0.U))
599  this.getLocal.foreach(_.setRW().withReset(0.U))
600}
601
602class Epc extends CSRBundle {
603  val epc = RW(63, 1).withReset(0.U)
604}
605
606class McountinhibitBundle extends CSRBundle {
607  val CY = RW(0).withReset(0.U)
608  val IR = RW(2).withReset(0.U)
609  val HPM3 = RW(31, 3).withReset(0.U)
610}
611
612class Mtval2Bundle extends FieldInitBundle
613
614class MhpmcounterBundle extends FieldInitBundle
615
616// todo: for the future, delete bypass between mhpmevents and perfEvents
617class MhpmeventBundle extends CSRBundle {
618  val OF    = RW(63).withReset(0.U)
619  val MINH  = RW(62).withReset(0.U)
620  val SINH  = RW(61).withReset(0.U)
621  val UINH  = RW(60).withReset(0.U)
622  val VSINH = RW(59).withReset(0.U)
623  val VUINH = RW(58).withReset(0.U)
624}
625
626class MEnvCfg extends EnvCfg {
627  if (CSRConfig.EXT_SSTC) {
628    this.STCE.setRW().withReset(1.U)
629  }
630  this.PBMTE.setRW().withReset(0.U)
631}
632
633object MarchidField extends CSREnum with ROApply {
634  val XSArchid = Value(25.U)
635}
636
637class MieToHie extends Bundle {
638  val VSSIE = ValidIO(RW(0))
639  val VSTIE = ValidIO(RW(0))
640  val VSEIE = ValidIO(RW(0))
641  val SGEIE = ValidIO(RW(0))
642}
643
644class MvipToMip extends IpValidBundle {
645  this.getHS.foreach(_.bits.setRW())
646}
647
648class HipToMip extends IpValidBundle {
649  // Only hip.VSSIP is writable
650  this.VSSIP.bits.setRW()
651}
652
653class VSipToMip extends IpValidBundle {
654  this.LCOFIP.bits.setRW()
655}
656
657class MipToHvip extends IpValidBundle {
658  this.VSSIP.bits.setRW()
659}
660
661class MipToMvip extends IpValidBundle {
662  this.SEIP.bits.setRW()
663}
664
665trait HasMipToAlias { self: CSRModule[_] =>
666  val mipAlias = Output(new MipBundle)
667}
668
669trait HasMachineDelegBundle { self: CSRModule[_] =>
670  val mideleg = IO(Input(new MidelegBundle))
671  val medeleg = IO(Input(new MedelegBundle))
672}
673
674trait HasExternalInterruptBundle {
675  val platformIRP = IO(new Bundle {
676    val MEIP  = Input(Bool())
677    val MTIP  = Input(Bool())
678    val MSIP  = Input(Bool())
679    val SEIP  = Input(Bool())
680    val STIP  = Input(Bool())
681    val VSEIP = Input(Bool())
682    val VSTIP = Input(Bool())
683    // debug interrupt from debug module
684    val debugIP = Input(Bool())
685  })
686}
687trait HasNonMaskableIRPBundle {
688  val nonMaskableIRP = IO(new Bundle {
689    val NMI_43 = Input(Bool())
690    val NMI_31 = Input(Bool())
691  })
692}
693
694trait HasMachineCounterControlBundle { self: CSRModule[_] =>
695  val mcountinhibit = IO(Input(new McountinhibitBundle))
696}
697
698trait HasRobCommitBundle { self: CSRModule[_] =>
699  val robCommit = IO(Input(new RobCommitCSR))
700  val writeFCSR = IO(Input(Bool()))
701  val writeVCSR = IO(Input(Bool()))
702  val isVirtMode = IO(Input(Bool()))
703}
704
705trait HasMachineEnvBundle { self: CSRModule[_] =>
706  val menvcfg = IO(Input(new MEnvCfg))
707}
708
709trait HasPerfCounterBundle { self: CSRModule[_] =>
710  val countingEn    = IO(Input(Bool()))
711  val perf          = IO(Input(new PerfEvent))
712  val toMhpmeventOF = IO(Output(Bool()))
713}
714
715trait HasPerfEventBundle { self: CSRModule[_] =>
716  val perfEvents = IO(Input(Vec(perfCntNum, UInt(XLEN.W))))
717}
718
719trait HasLocalInterruptReqBundle { self: CSRModule[_] =>
720  val lcofiReq = IO(Input(Bool()))
721}