xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision 01cdded87283f55be427ca849d18baa3e9459c2d)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import xiangshan.backend.fu.NewCSR.CSRBundles._
7import xiangshan.backend.fu.NewCSR.CSRDefines._
8import xiangshan.backend.fu.NewCSR.CSRDefines.{
9  CSRROField => RO,
10  CSRRWField => RW,
11  _
12}
13import xiangshan.backend.fu.NewCSR.CSREvents._
14
15import scala.collection.immutable.SeqMap
16
17trait MachineLevel { self: NewCSR =>
18  val mstatus = Module(new MstatusModule)
19    .setAddr(0x300)
20
21  val misa = Module(new CSRModule("Misa", new MisaBundle))
22    .setAddr(0x301)
23
24  println(s"[CSR] supported isa ext: ${misa.bundle.getISAString}")
25
26  val medeleg = Module(new CSRModule("Medeleg", new MedelegBundle))
27    .setAddr(0x302)
28
29  val mideleg = Module(new CSRModule("Mideleg", new MidelegBundle))
30    .setAddr(0x303)
31
32  val mie = Module(new CSRModule("Mie", new MieBundle) with HypervisorBundle {
33    val toHie = IO(new MieToHie)
34    val fromSie = IO(Flipped(new SieToMie))
35
36    when (fromSie.SSIE.valid) { reg.SSIE := fromSie.SSIE.bits }
37    when (fromSie.STIE.valid) { reg.STIE := fromSie.STIE.bits }
38    when (fromSie.SEIE.valid) { reg.SEIE := fromSie.SEIE.bits }
39
40    toHie.VSSIE.valid := wen
41    toHie.VSTIE.valid := wen
42    toHie.VSEIE.valid := wen
43    toHie.SGEIE.valid := wen
44    toHie.VSSIE.bits := wdata.VSSIE
45    toHie.VSTIE.bits := wdata.VSTIE
46    toHie.VSEIE.bits := wdata.VSEIE
47    toHie.SGEIE.bits := wdata.SGEIE
48
49    rdata.VSSIE := hie.VSSIE
50    rdata.VSTIE := hie.VSTIE
51    rdata.VSEIE := hie.VSEIE
52    rdata.SGEIE := hie.SGEIE
53  }).setAddr(0x304)
54
55  val mtvec = Module(new CSRModule("Mtvec", new XtvecBundle))
56    .setAddr(0x305)
57
58  // Todo: support "Stimecmp/Vstimecmp" Extension, Version 1.0.0
59  // Todo: support Sscounterenw Extension
60  val mcounteren = Module(new CSRModule("Mcounteren", new Counteren))
61    .setAddr(0x306)
62
63  val mvien = Module(new CSRModule("Mvien", new MvienBundle))
64    .setAddr(0x308)
65
66  val mvip = Module(new CSRModule("Mvip", new MvipBundle) with HasMachineInterruptBundle {
67    val toMip = IO(new MvipToMip)
68
69    // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip.
70    // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP.
71    // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED.
72    // XS will keep the value in mvip.SSIP when mvien.SSIE is changed from zero to one
73    rdata.SSIP := Mux(!mvien.SSIE.asUInt.asBool, mip.SSIP, reg.SSIP)
74    toMip.SSIP.valid := wen && !mvien.SSIE.asUInt.asBool
75    toMip.SSIP.bits := wdata.SSIP
76    reg.SSIP := Mux(wen && mvien.SSIE.asUInt.asBool, wdata.SSIP, reg.SSIP)
77
78    // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip.
79    // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero.
80    // Todo: check mip writable when menvcfg.STCE = 1
81    rdata.STIP := mip.STIP
82    toMip.STIP.valid := wen
83    toMip.STIP.bits := wdata.STIP
84
85    // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP).
86    // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP.
87    // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip.
88    rdata.SEIP := Mux(!mvien.SEIE.asUInt.asBool, mip.SEIP, reg.SEIP)
89    toMip.SEIP.valid := wen && !mvien.SEIE.asUInt.asBool
90    toMip.SEIP.bits := wdata.SEIP
91    reg.SEIP := Mux(wen && mvien.SEIE.asUInt.asBool, wdata.SEIP, reg.SEIP)
92  }).setAddr(0x309)
93
94  val menvcfg = Module(new CSRModule("Menvcfg", new Envcfg))
95    .setAddr(0x30A)
96
97  val mcountinhibit = Module(new CSRModule("Mcountinhibit", new McountinhibitBundle))
98    .setAddr(0x320)
99
100  val mhpmevents: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
101    Module(new CSRModule(s"Mhpmevent$num"))
102      .setAddr(0x320 + num)
103  )
104
105  val mscratch = Module(new CSRModule("Mscratch"))
106    .setAddr(0x340)
107
108  val mepc = Module(new CSRModule("Mepc", new Epc) with TrapEntryMEventSinkBundle)
109    .setAddr(0x341)
110
111  val mcause = Module(new CSRModule("Mcause", new CauseBundle) with TrapEntryMEventSinkBundle)
112    .setAddr(0x342)
113
114  val mtval = Module(new CSRModule("Mtval") with TrapEntryMEventSinkBundle)
115    .setAddr(0x343)
116
117  val mip = Module(new CSRModule("Mip", new MipBundle) with HasMachineInterruptBundle with HasExternalInterruptBundle {
118    val fromMvip = IO(Flipped(new MvipToMip))
119    val fromSip = IO(Flipped(new SipToMip))
120
121    // When bit 9 of mvien is zero, the value of bit 9 of mvip is logically ORed into the readable value of mip.SEIP.
122    // 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.
123    rdata.SEIP := Mux(!mvien.SEIE.asUInt.asBool, reg.SEIP.asUInt.asBool | mvip.SEIP.asUInt.asBool | platformIRP.SEIP, platformIRP.SEIP)
124    when (wen && !mvien.SEIE.asUInt.asBool) { reg.SEIP := reg.SEIP }
125    when (fromMvip.SSIP.valid) { reg.SSIP := fromMvip.SSIP.bits }
126    when (fromMvip.STIP.valid) { reg.STIP := fromMvip.STIP.bits }
127    when (fromMvip.SEIP.valid) { reg.SEIP := fromMvip.SEIP.bits }
128    when (fromSip.SSIP.valid) { reg.SSIP := fromSip.SSIP.bits }
129
130    // MEIP is read-only in mip, and is set and cleared by a platform-specific interrupt controller.
131    rdata.MEIP := platformIRP.MEIP
132    // MTIP is read-only in mip, and is cleared by writing to the memory-mapped machine-mode timer compare register
133    rdata.MTIP := platformIRP.MTIP
134    // MSIP is read-only in mip, and is written by accesses to memory-mapped control registers,
135    // which are used by remote harts to provide machine-level interprocessor interrupts.
136    rdata.MSIP := platformIRP.MSIP
137  }).setAddr(0x344)
138
139  val mtinst = Module(new CSRModule("Mtinst") with TrapEntryMEventSinkBundle)
140    .setAddr(0x34A)
141
142  val mtval2 = Module(new CSRModule("Mtval2") with TrapEntryMEventSinkBundle)
143    .setAddr(0x34B)
144
145  val mseccfg = Module(new CSRModule("Mseccfg", new CSRBundle {
146    val PMM   = RO(33, 32)
147    val SSEED = RO(     9)
148    val USEED = RO(     8)
149    val RLB   = RO(     2)
150    val MMWP  = RO(     1)
151    val MML   = RO(     0)
152  })).setAddr(0x747)
153
154  val mcycle = Module(new CSRModule("Mcycle") with HasMachineCounterControlBundle {
155    reg.ALL := Mux(!mcountinhibit.CY.asUInt.asBool, reg.ALL.asUInt + 1.U, reg.ALL.asUInt)
156  }).setAddr(0xB00)
157
158  val minstret = Module(new CSRModule("Minstret") with HasMachineCounterControlBundle with HasRobCommitBundle {
159    reg.ALL := Mux(!mcountinhibit.IR.asUInt.asBool && robCommit.instNum.valid, reg.ALL.asUInt + robCommit.instNum.bits, reg.ALL.asUInt)
160  })
161
162  // Todo: guarded by mcountinhibit
163  val mhpmcounters: Seq[CSRModule[_]] = (3 to 0x1F).map(num =>
164    Module(new CSRModule(s"Mhpmcounter$num") {
165
166    }).setAddr(0xB00 + num)
167  )
168
169  val mvendorid = Module(new CSRModule("Mvendorid") { rdata.ALL := 0.U })
170    .setAddr(0xF11)
171
172  // architecture id for XiangShan is 25
173  // see https://github.com/riscv/riscv-isa-manual/blob/master/marchid.md
174  val marchid = Module(new CSRModule("Marchid", new CSRBundle {
175    val ALL = MarchidField(63, 0).withReset(MarchidField.XSArchid)
176  })).setAddr(0xF12)
177
178  val machineLevelCSRMods: Seq[CSRModule[_]] = Seq(
179    mstatus,
180    misa,
181    medeleg,
182    mideleg,
183    mie,
184    mtvec,
185    mcounteren,
186    mvien,
187    mvip,
188    menvcfg,
189    mcountinhibit,
190    mscratch,
191    mepc,
192    mcause,
193    mtval,
194    mip,
195    mtinst,
196    mtval2,
197    mseccfg,
198    mcycle,
199    minstret,
200    mvendorid,
201    marchid,
202  ) ++ mhpmevents ++ mhpmcounters
203
204  val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = SeqMap.from(
205    machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata.asInstanceOf[CSRBundle].asUInt))).iterator
206  )
207
208  val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
209    machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
210  )
211}
212
213class MstatusBundle extends CSRBundle {
214
215  val SIE  = CSRRWField     (1).withReset(0.U)
216  val MIE  = CSRRWField     (3).withReset(0.U)
217  val SPIE = CSRRWField     (5).withReset(0.U)
218  val UBE  = CSRROField     (6).withReset(0.U)
219  val MPIE = CSRRWField     (7).withReset(0.U)
220  val SPP  = CSRRWField     (8).withReset(0.U)
221  val VS   = ContextStatus  (10,  9).withReset(ContextStatus.Off)
222  val MPP  = PrivMode       (12, 11).withReset(PrivMode.U)
223  val FS   = ContextStatus  (14, 13).withReset(ContextStatus.Off)
224  val XS   = ContextStatusRO(16, 15).withReset(0.U)
225  val MPRV = CSRRWField     (17).withReset(0.U)
226  val SUM  = CSRRWField     (18).withReset(0.U)
227  val MXR  = CSRRWField     (19).withReset(0.U)
228  val TVM  = CSRRWField     (20).withReset(0.U)
229  val TW   = CSRRWField     (21).withReset(0.U)
230  val TSR  = CSRRWField     (22).withReset(0.U)
231  val UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
232  val SXL  = XLENField      (35, 34).withReset(XLENField.XLEN64)
233  val SBE  = CSRROField     (36).withReset(0.U)
234  val MBE  = CSRROField     (37).withReset(0.U)
235  val GVA  = CSRRWField     (38).withReset(0.U)
236  val MPV  = VirtMode       (39).withReset(0.U)
237  val SD   = CSRROField     (63,
238    (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
239  )
240}
241
242class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle)
243  with TrapEntryMEventSinkBundle
244  with TrapEntryHSEventSinkBundle
245  with MretEventSinkBundle
246  with SretEventSinkBundle
247  with HasRobCommitBundle
248{
249  val mstatus = IO(Output(bundle))
250  val sstatus = IO(Output(new SstatusBundle))
251
252  val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle)))
253
254  // write connection
255  this.wfn(reg)(Seq(wAliasSstatus))
256
257  when (robCommit.fsDirty) {
258    assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode")
259    reg.FS := ContextStatus.Dirty
260  }
261
262  when (robCommit.vsDirty) {
263    assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode")
264    reg.VS := ContextStatus.Dirty
265  }
266
267  // read connection
268  mstatus :|= reg
269  sstatus := mstatus
270  rdata := mstatus.asUInt
271}
272
273class MisaBundle extends CSRBundle {
274  // Todo: reset with ISA string
275  val A = RO( 0).withReset(1.U) // Atomic extension
276  val B = RO( 1).withReset(0.U) // Reserved
277  val C = RO( 2).withReset(1.U) // Compressed extension
278  val D = RO( 3).withReset(1.U) // Double-precision floating-point extension
279  val E = RO( 4).withReset(0.U) // RV32E/64E base ISA
280  val F = RO( 5).withReset(1.U) // Single-precision floating-point extension
281  val G = RO( 6).withReset(0.U) // Reserved
282  val H = RO( 7).withReset(1.U) // Hypervisor extension
283  val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA
284  val J = RO( 9).withReset(0.U) // Reserved
285  val K = RO(10).withReset(0.U) // Reserved
286  val L = RO(11).withReset(0.U) // Reserved
287  val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi
288  val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension
289  val O = RO(14).withReset(0.U) // Reserved
290  val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension
291  val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension
292  val R = RO(17).withReset(0.U) // Reserved
293  val S = RO(18).withReset(1.U) // Supervisor mode implemented
294  val T = RO(19).withReset(0.U) // Reserved
295  val U = RO(20).withReset(1.U) // User mode implemented
296  val V = RO(21).withReset(1.U) // Vector extension
297  val W = RO(22).withReset(0.U) // Reserved
298  val X = RO(23).withReset(0.U) // Non-standard extensions present
299  val Y = RO(24).withReset(0.U) // Reserved
300  val Z = RO(25).withReset(0.U) // Reserved
301  val MXL = XLENField(63, 62).withReset(XLENField.XLEN64)
302
303  def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString
304}
305
306class MedelegBundle extends ExceptionBundle {
307  this.EX_MCALL.setRO() // never delegate machine level ecall
308}
309
310class MidelegBundle extends InterruptBundle {
311  // Don't delegate Machine level interrupts
312  this.getM.foreach(_.setRO().withReset(0.U))
313  // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg)
314  // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level
315  // interrupts) are each read-only one.
316  this.getVS.foreach(_.setRO().withReset(1.U))
317  // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one.
318  // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode.
319  this.SGEI.setRO().withReset(1.U)
320}
321
322class MieBundle extends InterruptEnableBundle {
323  this.SGEIE.setRO()
324  this.getVS.foreach(_.setRO())
325}
326
327class MipBundle extends InterruptPendingBundle {
328  this.getM.foreach(_.setRO())
329}
330
331class MvienBundle extends CSRBundle {
332  // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level
333  // It is strongly recommended that bit 9 of mvien be writable.
334  // It is strongly recommended that bit 1 of mvien also be writable.
335  val SSIE     = RW(1)
336  val SEIE     = RW(9)
337  val OTHERIE  = RW(63, 13)
338}
339
340class MvipBundle extends CSRBundle {
341  // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip.
342  // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP.
343  // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED.
344  val SSIP     = RW(1)
345  // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip.
346  // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero.
347  val STIP     = RW(5)
348  // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP).
349  // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP.
350  // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip.
351  val SEIP     = RW(9)
352  val OTHERIP  = RW(63, 13)
353}
354
355class Epc extends CSRBundle {
356  // TODO: configure it with VAddrBits
357  val ALL = RW(63, 1)
358}
359
360class McountinhibitBundle extends CSRBundle {
361  val CY = RW(0)
362  val IR = RW(2)
363  val HPM3 = RW(31, 3)
364}
365
366object MarchidField extends CSREnum with ROApply {
367  val XSArchid = Value(25.U)
368}
369
370class MieToHie extends Bundle {
371  val VSSIE = ValidIO(RW(0))
372  val VSTIE = ValidIO(RW(0))
373  val VSEIE = ValidIO(RW(0))
374  val SGEIE = ValidIO(RW(0))
375}
376
377class MvipToMip extends Bundle {
378  val SSIP = ValidIO(RW(0))
379  val STIP = ValidIO(RW(0))
380  val SEIP = ValidIO(RW(0))
381}
382
383trait HasMachineInterruptBundle { self: CSRModule[_] =>
384  val mvien = IO(Input(new MvienBundle))
385  val mvip  = IO(Input(new MvipBundle))
386  val mip   = IO(Input(new MipBundle))
387  val mie   = IO(Input(new MieBundle))
388}
389
390trait HasMachineDelegBundle { self: CSRModule[_] =>
391  val mideleg = IO(Input(new MidelegBundle))
392  val medeleg = IO(Input(new MedelegBundle))
393}
394
395trait HasExternalInterruptBundle {
396  val platformIRP = IO(new Bundle {
397    val MEIP  = Input(Bool())
398    val MTIP  = Input(Bool())
399    val MSIP  = Input(Bool())
400    val SEIP  = Input(Bool())
401    val VSEIP = Input(Bool())
402    val VSTIP = Input(Bool())
403    val debugIP = Input(Bool())
404  })
405}
406
407trait HasMachineCounterControlBundle { self: CSRModule[_] =>
408  val mcountinhibit = IO(Input(new McountinhibitBundle))
409}
410
411trait HasRobCommitBundle { self: CSRModule[_] =>
412  val robCommit = IO(Input(new RobCommitCSR))
413}