xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRAIA.scala (revision 0427fd02df1699b6c7f89cf1ffd98f68cb303fb6)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import freechips.rocketchip.rocket.CSRs
6import CSRConfig._
7import xiangshan.backend.fu.NewCSR.CSRBundles.PrivState
8import xiangshan.backend.fu.NewCSR.CSRConfig._
9import xiangshan.backend.fu.NewCSR.CSRDefines.{CSRROField => RO, CSRRWField => RW, _}
10
11import scala.collection.immutable.SeqMap
12
13trait CSRAIA { self: NewCSR with HypervisorLevel =>
14  val miselect = Module(new CSRModule("Miselect", new MISelectBundle) with HasISelectBundle {
15    private val value = reg.ALL.asUInt
16    inIMSICRange := value >= 0x70.U && value < 0x100.U
17    isIllegal :=
18      value < 0x30.U ||
19      value >= 0x30.U && value < 0x40.U && value(0) === 1.U ||
20      value >= 0x40.U && value < 0x70.U ||
21      value >= 0x100.U
22  })
23    .setAddr(CSRs.miselect)
24
25  val mireg = Module(new CSRModule("Mireg") with HasIregSink {
26    rdata := iregRead.mireg
27  })
28    .setAddr(CSRs.mireg)
29
30  val mtopei = Module(new CSRModule("Mtopei", new TopEIBundle) with HasAIABundle {
31    regOut := aiaToCSR.mtopei
32  })
33    .setAddr(CSRs.mtopei)
34
35  val mtopi = Module(new CSRModule("Mtopi", new TopIBundle) with HasInterruptFilterSink {
36    regOut.IID   := topIR.mtopi.IID
37    regOut.IPRIO := topIR.mtopi.IPRIO
38  })
39    .setAddr(CSRs.mtopi)
40
41  val siselect = Module(new CSRModule("Siselect", new SISelectBundle) with HasISelectBundle {
42    private val value = reg.ALL.asUInt
43    inIMSICRange := value >= 0x70.U && value < 0x100.U
44    isIllegal :=
45      value < 0x30.U ||
46      value >= 0x30.U && value < 0x40.U && value(0) === 1.U ||
47      value >= 0x40.U && value < 0x70.U ||
48      value >= 0x100.U
49  })
50    .setAddr(CSRs.siselect)
51
52  val sireg = Module(new CSRModule("Sireg") with HasIregSink {
53    rdata := iregRead.sireg
54  })
55    .setAddr(CSRs.sireg)
56
57  val stopei = Module(new CSRModule("Stopei", new TopEIBundle) with HasAIABundle {
58    regOut := aiaToCSR.stopei
59  })
60    .setAddr(CSRs.stopei)
61
62  val stopi = Module(new CSRModule("Stopi", new TopIBundle) with HasInterruptFilterSink {
63    regOut.IID   := topIR.stopi.IID
64    regOut.IPRIO := topIR.stopi.IPRIO
65  })
66    .setAddr(CSRs.stopi)
67
68  val vsiselect = Module(new CSRModule("VSiselect", new VSISelectBundle) with HasISelectBundle {
69    private val value = reg.ALL.asUInt
70    inIMSICRange := value >= 0x70.U && value < 0x100.U
71    isIllegal :=
72      value < 0x70.U ||
73      value >= 0x100.U
74  })
75    .setAddr(CSRs.vsiselect)
76
77  val vsireg    = Module(new CSRModule("VSireg") with HasIregSink {
78    rdata := iregRead.sireg
79  })
80    .setAddr(CSRs.vsireg)
81
82  val vstopei   = Module(new CSRModule("VStopei", new TopEIBundle) with HasAIABundle {
83    regOut := aiaToCSR.vstopei
84  })
85    .setAddr(CSRs.vstopei)
86
87  val vstopi = Module(new CSRModule("VStopi", new TopIBundle) with HasInterruptFilterSink {
88    regOut.IID   := topIR.vstopi.IID
89    regOut.IPRIO := topIR.vstopi.IPRIO
90  })
91    .setAddr(CSRs.vstopi)
92
93  val miprio0 = Module(new CSRModule(s"Iprio0", new Iprio0Bundle))
94    .setAddr(0x30)
95
96  val miprio2 = Module(new CSRModule(s"Iprio2", new Iprio2Bundle))
97    .setAddr(0x32)
98
99  val miprio4 = Module(new CSRModule(s"Iprio4", new IprioBundle))
100    .setAddr(0x34)
101
102  val miprio6 = Module(new CSRModule(s"Iprio6", new IprioBundle))
103    .setAddr(0x36)
104
105  val miprio8 = Module(new CSRModule(s"Iprio8", new Iprio8Bundle))
106    .setAddr(0x38)
107
108  val miprio10 = Module(new CSRModule(s"Iprio10", new Iprio10Bundle))
109    .setAddr(0x3A)
110
111  val miprio12 = Module(new CSRModule(s"Iprio12", new IprioBundle))
112    .setAddr(0x3C)
113
114  val miprio14 = Module(new CSRModule(s"Iprio14", new IprioBundle))
115    .setAddr(0x3E)
116
117  val siprio0 = Module(new CSRModule(s"Iprio0", new Iprio0Bundle))
118    .setAddr(0x30)
119
120  val siprio2 = Module(new CSRModule(s"Iprio2", new Iprio2Bundle))
121    .setAddr(0x32)
122
123  val siprio4 = Module(new CSRModule(s"Iprio4", new IprioBundle))
124    .setAddr(0x34)
125
126  val siprio6 = Module(new CSRModule(s"Iprio6", new IprioBundle))
127    .setAddr(0x36)
128
129  val siprio8 = Module(new CSRModule(s"Iprio8", new Iprio8Bundle))
130    .setAddr(0x38)
131
132  val siprio10 = Module(new CSRModule(s"Iprio10", new Iprio10Bundle))
133    .setAddr(0x3A)
134
135  val siprio12 = Module(new CSRModule(s"Iprio12", new IprioBundle))
136    .setAddr(0x3C)
137
138  val siprio14 = Module(new CSRModule(s"Iprio14", new IprioBundle))
139    .setAddr(0x3E)
140
141  val miregiprios: Seq[CSRModule[_]] = Seq(miprio0, miprio2, miprio4, miprio6, miprio8, miprio10, miprio12, miprio14)
142
143  val siregiprios: Seq[CSRModule[_]] = Seq(siprio0, siprio2, siprio4, siprio6, siprio8, siprio10, siprio12, siprio14)
144
145  val aiaCSRMods = Seq(
146    miselect,
147    mireg,
148    mtopei,
149    mtopi,
150    siselect,
151    sireg,
152    stopei,
153    stopi,
154    vsiselect,
155    vsireg,
156    vstopi,
157    vstopei,
158  )
159
160  val aiaCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
161    aiaCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
162  )
163
164  val aiaCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
165    aiaCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
166  )
167
168  private val miregRData: UInt = Mux1H(
169    miregiprios.map(prio => (miselect.rdata.asUInt === prio.addr.U) -> prio.rdata)
170  )
171
172  private val siregRData: UInt = Mux1H(
173    siregiprios.map(prio => (siselect.rdata.asUInt === prio.addr.U) -> prio.rdata)
174  )
175
176  aiaCSRMods.foreach { mod =>
177    mod match {
178      case m: HasIregSink =>
179        m.iregRead.mireg := miregRData
180        m.iregRead.sireg := siregRData
181        m.iregRead.vsireg := 0.U // Todo: IMSIC
182      case _ =>
183    }
184  }
185}
186
187class ISelectField(final val maxValue: Int, reserved: Seq[Range]) extends CSREnum with WARLApply {
188  override def isLegal(enumeration: CSREnumType): Bool = enumeration.asUInt <= maxValue.U
189}
190
191object VSISelectField extends ISelectField(
192  0x1FF,
193  reserved = Seq(
194    Range.inclusive(0x000, 0x02F),
195    Range.inclusive(0x040, 0x06F),
196    Range.inclusive(0x100, 0x1FF),
197  ),
198)
199
200object MISelectField extends ISelectField(
201  maxValue = 0xFF,
202  reserved = Seq(
203    Range.inclusive(0x00, 0x2F),
204    Range.inclusive(0x40, 0x6F),
205  ),
206)
207
208object SISelectField extends ISelectField(
209  maxValue = 0xFF,
210  reserved = Seq(
211    Range.inclusive(0x00, 0x2F),
212    Range.inclusive(0x40, 0x6F),
213  ),
214)
215
216class VSISelectBundle extends CSRBundle {
217  val ALL = VSISelectField(log2Up(0x1FF), 0, null).withReset(0.U)
218}
219
220class MISelectBundle extends CSRBundle {
221  val ALL = MISelectField(log2Up(0xFF), 0, null).withReset(0.U)
222}
223
224class SISelectBundle extends CSRBundle {
225  val ALL = SISelectField(log2Up(0xFF), 0, null).withReset(0.U)
226}
227
228class TopIBundle extends CSRBundle {
229  val IID   = RO(27, 16)
230  val IPRIO = RO(7, 0)
231}
232
233class TopEIBundle extends CSRBundle {
234  val IID   = RW(26, 16)
235  val IPRIO = RW(10, 0)
236}
237
238class IprioBundle extends CSRBundle {
239  val ALL = RO(63, 0).withReset(0.U)
240}
241
242class Iprio0Bundle extends CSRBundle {
243  val PrioSSI  = RW(15,  8).withReset(0.U)
244  val PrioVSSI = RW(23, 16).withReset(0.U)
245  val PrioMSI  = RW(31, 24).withReset(0.U)
246  val PrioSTI  = RW(47, 40).withReset(0.U)
247  val PrioVSTI = RW(55, 48).withReset(0.U)
248  val PrioMTI  = RW(63, 56).withReset(0.U)
249}
250
251class Iprio2Bundle extends CSRBundle {
252  val PrioSEI  = RW(15,  8).withReset(0.U)
253  val PrioVSEI = RW(23, 16).withReset(0.U)
254  val PrioMEI  = RW(31, 24).withReset(0.U)
255  val PrioSGEI = RW(39, 32).withReset(0.U)
256  val PrioCOI  = RW(47, 40).withReset(0.U)
257}
258
259class Iprio8Bundle extends CSRBundle {
260  val PrioLPRASEI = RW(31, 24).withReset(0.U)
261}
262
263class Iprio10Bundle extends CSRBundle {
264  val PrioHPRASEI = RW(31, 24).withReset(0.U)
265}
266
267class CSRToAIABundle extends Bundle {
268  private final val AddrWidth = 12
269
270  val addr = ValidIO(new Bundle {
271    val addr = UInt(AddrWidth.W)
272    val v = VirtMode()
273    val prvm = PrivMode()
274  })
275
276  val vgein = UInt(VGEINWidth.W)
277
278  val wdata = ValidIO(new Bundle {
279    val op = UInt(2.W)
280    val data = UInt(XLEN.W)
281  })
282
283  val mClaim = Bool()
284  val sClaim = Bool()
285  val vsClaim = Bool()
286}
287
288class AIAToCSRBundle extends Bundle {
289  private val NumVSIRFiles = 63
290  val rdata = ValidIO(new Bundle {
291    val data = UInt(XLEN.W)
292    val illegal = Bool()
293  })
294  val meip    = Bool()
295  val seip    = Bool()
296  val vseip   = UInt(NumVSIRFiles.W)
297  val mtopei  = new TopEIBundle
298  val stopei  = new TopEIBundle
299  val vstopei = new TopEIBundle
300}
301
302trait HasAIABundle { self: CSRModule[_] =>
303  val aiaToCSR = IO(Input(new AIAToCSRBundle))
304}
305
306trait HasInterruptFilterSink { self: CSRModule[_] =>
307  val topIR = IO(new Bundle {
308    val mtopi  = Input(new TopIBundle)
309    val stopi  = Input(new TopIBundle)
310    val vstopi = Input(new TopIBundle)
311  })
312}
313
314trait HasISelectBundle { self: CSRModule[_] =>
315  val inIMSICRange = IO(Output(Bool()))
316  val isIllegal = IO(Output(Bool()))
317}
318
319trait HasIregSink { self: CSRModule[_] =>
320  val iregRead = IO(Input(new Bundle {
321    val mireg = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width
322    val sireg = UInt(XLEN.W)
323    val vsireg = UInt(XLEN.W)
324  }))
325}
326