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