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