xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision 40ac5bb1842d44eb247ef164881a9d06c158a05a)
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 mimpid = Module(new CSRModule("Mimpid", new CSRBundle {
179    val ALL = RO(0).withReset(0.U)
180  }))
181    .setAddr(0xF13)
182
183  val mhartid = Module(new CSRModule("Mhartid", new CSRBundle {
184    val ALL = RO(7, 0)
185  }) {
186    val hartid = IO(Input(UInt(hartIdLen.W)))
187    this.reg.ALL := RegEnable(hartid, reset.asBool)
188  })
189    .setAddr(0xF14)
190
191  val mconfigptr = Module(new CSRModule("Mconfigptr"))
192    .setAddr(0xF15)
193
194  val machineLevelCSRMods: Seq[CSRModule[_]] = Seq(
195    mstatus,
196    misa,
197    medeleg,
198    mideleg,
199    mie,
200    mtvec,
201    mcounteren,
202    mvien,
203    mvip,
204    menvcfg,
205    mcountinhibit,
206    mscratch,
207    mepc,
208    mcause,
209    mtval,
210    mip,
211    mtinst,
212    mtval2,
213    mseccfg,
214    mcycle,
215    minstret,
216    mvendorid,
217    marchid,
218    mimpid,
219    mhartid,
220    mconfigptr,
221  ) ++ mhpmevents ++ mhpmcounters
222
223  val machineLevelCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], Data)] = SeqMap.from(
224    machineLevelCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata.asInstanceOf[CSRBundle].asUInt))).iterator
225  )
226
227  val machineLevelCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
228    machineLevelCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
229  )
230}
231
232class MstatusBundle extends CSRBundle {
233
234  val SIE  = CSRRWField     (1).withReset(0.U)
235  val MIE  = CSRRWField     (3).withReset(0.U)
236  val SPIE = CSRRWField     (5).withReset(0.U)
237  val UBE  = CSRROField     (6).withReset(0.U)
238  val MPIE = CSRRWField     (7).withReset(0.U)
239  val SPP  = CSRRWField     (8).withReset(0.U)
240  val VS   = ContextStatus  (10,  9).withReset(ContextStatus.Off)
241  val MPP  = PrivMode       (12, 11).withReset(PrivMode.U)
242  val FS   = ContextStatus  (14, 13).withReset(ContextStatus.Off)
243  val XS   = ContextStatusRO(16, 15).withReset(0.U)
244  val MPRV = CSRRWField     (17).withReset(0.U)
245  val SUM  = CSRRWField     (18).withReset(0.U)
246  val MXR  = CSRRWField     (19).withReset(0.U)
247  val TVM  = CSRRWField     (20).withReset(0.U)
248  val TW   = CSRRWField     (21).withReset(0.U)
249  val TSR  = CSRRWField     (22).withReset(0.U)
250  val UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
251  val SXL  = XLENField      (35, 34).withReset(XLENField.XLEN64)
252  val SBE  = CSRROField     (36).withReset(0.U)
253  val MBE  = CSRROField     (37).withReset(0.U)
254  val GVA  = CSRRWField     (38).withReset(0.U)
255  val MPV  = VirtMode       (39).withReset(0.U)
256  val SD   = CSRROField     (63,
257    (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
258  )
259}
260
261class MstatusModule(implicit override val p: Parameters) extends CSRModule("MStatus", new MstatusBundle)
262  with TrapEntryMEventSinkBundle
263  with TrapEntryHSEventSinkBundle
264  with MretEventSinkBundle
265  with SretEventSinkBundle
266  with HasRobCommitBundle
267{
268  val mstatus = IO(Output(bundle))
269  val sstatus = IO(Output(new SstatusBundle))
270
271  val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle)))
272
273  // write connection
274  this.wfn(reg)(Seq(wAliasSstatus))
275
276  when (robCommit.fsDirty) {
277    assert(reg.FS =/= ContextStatus.Off, "The [m|s]status.FS should not be Off when set dirty, please check decode")
278    reg.FS := ContextStatus.Dirty
279  }
280
281  when (robCommit.vsDirty) {
282    assert(reg.VS =/= ContextStatus.Off, "The [m|s]status.VS should not be Off when set dirty, please check decode")
283    reg.VS := ContextStatus.Dirty
284  }
285
286  // read connection
287  mstatus :|= reg
288  sstatus := mstatus
289  rdata := mstatus.asUInt
290}
291
292class MisaBundle extends CSRBundle {
293  // Todo: reset with ISA string
294  val A = RO( 0).withReset(1.U) // Atomic extension
295  val B = RO( 1).withReset(0.U) // Reserved
296  val C = RO( 2).withReset(1.U) // Compressed extension
297  val D = RO( 3).withReset(1.U) // Double-precision floating-point extension
298  val E = RO( 4).withReset(0.U) // RV32E/64E base ISA
299  val F = RO( 5).withReset(1.U) // Single-precision floating-point extension
300  val G = RO( 6).withReset(0.U) // Reserved
301  val H = RO( 7).withReset(1.U) // Hypervisor extension
302  val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA
303  val J = RO( 9).withReset(0.U) // Reserved
304  val K = RO(10).withReset(0.U) // Reserved
305  val L = RO(11).withReset(0.U) // Reserved
306  val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi
307  val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension
308  val O = RO(14).withReset(0.U) // Reserved
309  val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension
310  val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension
311  val R = RO(17).withReset(0.U) // Reserved
312  val S = RO(18).withReset(1.U) // Supervisor mode implemented
313  val T = RO(19).withReset(0.U) // Reserved
314  val U = RO(20).withReset(1.U) // User mode implemented
315  val V = RO(21).withReset(1.U) // Vector extension
316  val W = RO(22).withReset(0.U) // Reserved
317  val X = RO(23).withReset(0.U) // Non-standard extensions present
318  val Y = RO(24).withReset(0.U) // Reserved
319  val Z = RO(25).withReset(0.U) // Reserved
320  val MXL = XLENField(63, 62).withReset(XLENField.XLEN64)
321
322  def getISAString = this.getFields.filter(x => x != MXL && x.init.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString
323}
324
325class MedelegBundle extends ExceptionBundle {
326  this.EX_MCALL.setRO() // never delegate machine level ecall
327}
328
329class MidelegBundle extends InterruptBundle {
330  // Don't delegate Machine level interrupts
331  this.getM.foreach(_.setRO().withReset(0.U))
332  // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg)
333  // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level
334  // interrupts) are each read-only one.
335  this.getVS.foreach(_.setRO().withReset(1.U))
336  // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one.
337  // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode.
338  this.SGEI.setRO().withReset(1.U)
339}
340
341class MieBundle extends InterruptEnableBundle {
342  this.SGEIE.setRO()
343  this.getVS.foreach(_.setRO())
344}
345
346class MipBundle extends InterruptPendingBundle {
347  this.getM.foreach(_.setRO())
348}
349
350class MvienBundle extends CSRBundle {
351  // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level
352  // It is strongly recommended that bit 9 of mvien be writable.
353  // It is strongly recommended that bit 1 of mvien also be writable.
354  val SSIE     = RW(1)
355  val SEIE     = RW(9)
356  val OTHERIE  = RW(63, 13)
357}
358
359class MvipBundle extends CSRBundle {
360  // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip.
361  // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP.
362  // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED.
363  val SSIP     = RW(1)
364  // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip.
365  // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero.
366  val STIP     = RW(5)
367  // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP).
368  // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP.
369  // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip.
370  val SEIP     = RW(9)
371  val OTHERIP  = RW(63, 13)
372}
373
374class Epc extends CSRBundle {
375  // TODO: configure it with VAddrBits
376  val ALL = RW(63, 1)
377}
378
379class McountinhibitBundle extends CSRBundle {
380  val CY = RW(0)
381  val IR = RW(2)
382  val HPM3 = RW(31, 3)
383}
384
385object MarchidField extends CSREnum with ROApply {
386  val XSArchid = Value(25.U)
387}
388
389class MieToHie extends Bundle {
390  val VSSIE = ValidIO(RW(0))
391  val VSTIE = ValidIO(RW(0))
392  val VSEIE = ValidIO(RW(0))
393  val SGEIE = ValidIO(RW(0))
394}
395
396class MvipToMip extends Bundle {
397  val SSIP = ValidIO(RW(0))
398  val STIP = ValidIO(RW(0))
399  val SEIP = ValidIO(RW(0))
400}
401
402trait HasMachineInterruptBundle { self: CSRModule[_] =>
403  val mvien = IO(Input(new MvienBundle))
404  val mvip  = IO(Input(new MvipBundle))
405  val mip   = IO(Input(new MipBundle))
406  val mie   = IO(Input(new MieBundle))
407}
408
409trait HasMachineDelegBundle { self: CSRModule[_] =>
410  val mideleg = IO(Input(new MidelegBundle))
411  val medeleg = IO(Input(new MedelegBundle))
412}
413
414trait HasExternalInterruptBundle {
415  val platformIRP = IO(new Bundle {
416    val MEIP  = Input(Bool())
417    val MTIP  = Input(Bool())
418    val MSIP  = Input(Bool())
419    val SEIP  = Input(Bool())
420    val VSEIP = Input(Bool())
421    val VSTIP = Input(Bool())
422    // debug interrupt from debug module
423    val debugIP = Input(Bool())
424  })
425}
426
427trait HasMachineCounterControlBundle { self: CSRModule[_] =>
428  val mcountinhibit = IO(Input(new McountinhibitBundle))
429}
430
431trait HasRobCommitBundle { self: CSRModule[_] =>
432  val robCommit = IO(Input(new RobCommitCSR))
433}