xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/MachineLevel.scala (revision 039cdc35f5f3b68b6295ec5ace90f22a77322e02)
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  CSRRWField => RW,
9  CSRROField => RO,
10  CSRWLRLField => WLRL,
11  CSRWARLField => WARL,
12  _
13}
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))
109    .setAddr(0x341)
110
111  val mcause = Module(new CSRModule("Mcause", new CauseBundle))
112    .setAddr(0x342)
113
114  val mtval = Module(new CSRModule("Mtval"))
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"))
140    .setAddr(0x34A)
141
142  val mtval2 = Module(new CSRModule("Mtval2"))
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 HasInstCommitBundle {
159    reg.ALL := Mux(!mcountinhibit.IR.asUInt.asBool && commitValid, reg.ALL.asUInt + commitInstNum, 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
209class MstatusBundle extends CSRBundle {
210
211  val SIE  = CSRRWField     (1).withReset(0.U)
212  val MIE  = CSRRWField     (3).withReset(0.U)
213  val SPIE = CSRRWField     (5).withReset(0.U)
214  val UBE  = CSRROField     (6).withReset(0.U)
215  val MPIE = CSRRWField     (7).withReset(0.U)
216  val SPP  = CSRRWField     (8).withReset(0.U)
217  val VS   = ContextStatus  (10,  9).withReset(ContextStatus.Initial)
218  val MPP  = PrivMode       (12, 11).withReset(PrivMode.U)
219  val FS   = ContextStatus  (14, 13).withReset(ContextStatus.Initial)
220  val XS   = ContextStatusRO(16, 15).withReset(0.U)
221  val MPRV = CSRRWField     (17).withReset(0.U)
222  val SUM  = CSRRWField     (18).withReset(0.U)
223  val MXR  = CSRRWField     (19).withReset(0.U)
224  val TVM  = CSRRWField     (20).withReset(0.U)
225  val TW   = CSRRWField     (21).withReset(0.U)
226  val TSR  = CSRRWField     (22).withReset(0.U)
227  val UXL  = XLENField      (33, 32).withReset(XLENField.XLEN64)
228  val SXL  = XLENField      (35, 34).withReset(XLENField.XLEN64)
229  val SBE  = CSRROField     (36).withReset(0.U)
230  val MBE  = CSRROField     (37).withReset(0.U)
231  val GVA  = CSRRWField     (38).withReset(0.U)
232  val MPV  = CSRRWField     (39).withReset(0.U)
233  val SD   = CSRROField     (63,
234    (_, _) => FS === ContextStatus.Dirty || VS === ContextStatus.Dirty
235  )
236}
237
238class MstatusModule extends CSRModule("MStatus", new MstatusBundle) {
239  val mstatus = IO(Output(bundle))
240  val sstatus = IO(Output(new SstatusBundle))
241
242  val wAliasSstatus = IO(Input(new CSRAddrWriteBundle(new SstatusBundle)))
243
244  // write connection
245  this.wfn(reg)(Seq(wAliasSstatus))
246
247  // read connection
248  mstatus :|= reg
249  sstatus := mstatus
250  rdata := mstatus.asUInt
251}
252
253class MisaBundle extends CSRBundle {
254  // Todo: reset with ISA string
255  val A = RO( 0).withReset(1.U) // Atomic extension
256  val B = RO( 1).withReset(0.U) // Reserved
257  val C = RO( 2).withReset(1.U) // Compressed extension
258  val D = RO( 3).withReset(1.U) // Double-precision floating-point extension
259  val E = RO( 4).withReset(0.U) // RV32E/64E base ISA
260  val F = RO( 5).withReset(1.U) // Single-precision floating-point extension
261  val G = RO( 6).withReset(0.U) // Reserved
262  val H = RO( 7).withReset(1.U) // Hypervisor extension
263  val I = RO( 8).withReset(1.U) // RV32I/64I/128I base ISA
264  val J = RO( 9).withReset(0.U) // Reserved
265  val K = RO(10).withReset(0.U) // Reserved
266  val L = RO(11).withReset(0.U) // Reserved
267  val M = RO(12).withReset(1.U) // Integer Multiply/Divide extensi
268  val N = RO(13).withReset(0.U) // Tentatively reserved for User-Level Interrupts extension
269  val O = RO(14).withReset(0.U) // Reserved
270  val P = RO(15).withReset(0.U) // Tentatively reserved for Packed-SIMD extension
271  val Q = RO(16).withReset(0.U) // Quad-precision floating-point extension
272  val R = RO(17).withReset(0.U) // Reserved
273  val S = RO(18).withReset(1.U) // Supervisor mode implemented
274  val T = RO(19).withReset(0.U) // Reserved
275  val U = RO(20).withReset(1.U) // User mode implemented
276  val V = RO(21).withReset(1.U) // Vector extension
277  val W = RO(22).withReset(0.U) // Reserved
278  val X = RO(23).withReset(0.U) // Non-standard extensions present
279  val Y = RO(24).withReset(0.U) // Reserved
280  val Z = RO(25).withReset(0.U) // Reserved
281  val MXL = XLENField(63, 62).withReset(XLENField.XLEN64)
282
283  def getISAString = this.getFields.filter(x => x != MXL && x.init.get.litValue == 1).sortBy(_.lsb).map(x => ('A' + x.msb).toChar).mkString
284}
285
286class MedelegBundle extends ExceptionBundle {
287  this.EX_MCALL.setRO() // never delegate machine level ecall
288}
289
290class MidelegBundle extends InterruptBundle {
291  // Don't delegate Machine level interrupts
292  this.getM.foreach(_.setRO().withReset(0.U))
293  // Ref: 13.4.2. Machine Interrupt Delegation Register (mideleg)
294  // When the hypervisor extension is implemented, bits 10, 6, and 2 of mideleg (corresponding to the standard VS-level
295  // interrupts) are each read-only one.
296  this.getVS.foreach(_.setRO().withReset(1.U))
297  // bit 12 of mideleg (corresponding to supervisor-level guest external interrupts) is also read-only one.
298  // VS-level interrupts and guest external interrupts are always delegated past M-mode to HS-mode.
299  this.SGEI.setRO().withReset(1.U)
300}
301
302class MieBundle extends InterruptEnableBundle {
303  this.SGEIE.setRO()
304  this.getVS.foreach(_.setRO())
305}
306
307class MipBundle extends InterruptPendingBundle {
308  this.getM.foreach(_.setRO())
309}
310
311class MvienBundle extends CSRBundle {
312  // Ref: riscv interrupt spec - 5.3 Interrupt filtering and virtual interrupts for supervisor level
313  // It is strongly recommended that bit 9 of mvien be writable.
314  // It is strongly recommended that bit 1 of mvien also be writable.
315  val SSIE     = RW(1)
316  val SEIE     = RW(9)
317  val OTHERIE  = RW(63, 13)
318}
319
320class MvipBundle extends CSRBundle {
321  // When bit 1 of mvien is zero, bit 1(SSIP) of mvip is an alias of the same bit (SSIP) of mip.
322  // But when bit 1 of mvien is one, bit 1(SSIP) of mvip is a separate writable bit independent of mip.SSIP.
323  // When the value of bit 1 of mvien is changed from zero to one, the value of bit 1 of mvip becomes UNSPECIFIED.
324  val SSIP     = RW(1)
325  // Bit 5 of mvip is an alias of the same bit (STIP) in mip when that bit is writable in mip.
326  // When STIP is not writable in mip (such as when menvcfg.STCE = 1), bit 5 of mvip is read-only zero.
327  val STIP     = RW(5)
328  // When bit 9 of mvien is zero, bit 9 of mvip is an alias of the software-writable bit 9 of mip (SEIP).
329  // But when bit 9 of mvien is one, bit 9 of mvip is a writable bit independent of mip.SEIP.
330  // Unlike for bit 1, changing the value of bit 9 of mvien does not affect the value of bit 9 of mvip.
331  val SEIP     = RW(9)
332  val OTHERIP  = RW(63, 13)
333}
334
335class Epc extends CSRBundle {
336  // TODO: configure it with VAddrBits
337  val ALL = RW(63, 1)
338}
339
340class McountinhibitBundle extends CSRBundle {
341  val CY = RW(0)
342  val IR = RW(2)
343  val HPM3 = RW(31, 3)
344}
345
346object MarchidField extends CSREnum with CSRROApply {
347  val XSArchid = Value(25.U)
348}
349
350class MieToHie extends Bundle {
351  val VSSIE = ValidIO(RW(0))
352  val VSTIE = ValidIO(RW(0))
353  val VSEIE = ValidIO(RW(0))
354  val SGEIE = ValidIO(RW(0))
355}
356
357class MvipToMip extends Bundle {
358  val SSIP = ValidIO(RW(0))
359  val STIP = ValidIO(RW(0))
360  val SEIP = ValidIO(RW(0))
361}
362
363trait HasMachineInterruptBundle { self: CSRModule[_] =>
364  val mvien = IO(Input(new MvienBundle))
365  val mvip  = IO(Input(new MvipBundle))
366  val mip   = IO(Input(new MipBundle))
367  val mie   = IO(Input(new MieBundle))
368}
369
370trait HasMachineDelegBundle { self: CSRModule[_] =>
371  val mideleg = IO(Input(new MidelegBundle))
372  val medeleg = IO(Input(new MedelegBundle))
373}
374
375trait HasExternalInterruptBundle {
376  val platformIRP = IO(new Bundle {
377    val MEIP  = Input(Bool())
378    val MTIP  = Input(Bool())
379    val MSIP  = Input(Bool())
380    val SEIP  = Input(Bool())
381    val VSEIP = Input(Bool())
382    val VSTIP = Input(Bool())
383  })
384}
385
386trait HasMachineCounterControlBundle { self: CSRModule[_] =>
387  val mcountinhibit = IO(Input(new McountinhibitBundle))
388}
389
390trait HasInstCommitBundle {
391  val commitValid   = IO(Input(Bool()))
392  // need contain 8x8
393  val commitInstNum = IO(Input(UInt(7.W)))
394}