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