xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRAIA.scala (revision c41f725a91c55e75c95c55b4bb0d2649f43e4c83)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import freechips.rocketchip.rocket.CSRs
6import CSRConfig._
7import xiangshan.backend.fu.NewCSR.CSRBundles._
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) with HasIeBundle {
94    val mask = Wire(Vec(8, UInt(8.W)))
95    for (i <- 0 until 8) {
96      mask(i) := Fill(8, mie.asUInt(i))
97    }
98    regOut := reg & mask.asUInt
99  })
100    .setAddr(0x30)
101
102  val miprio2 = Module(new CSRModule(s"Iprio2", new MIprio2Bundle) with HasIeBundle {
103    val mask = Wire(Vec(8, UInt(8.W)))
104    for (i <- 0 until 8) {
105      mask(i) := Fill(8, mie.asUInt(i+8))
106    }
107    regOut := reg & mask.asUInt
108  })
109    .setAddr(0x32)
110
111  val miprios: Seq[CSRModule[_]] = (4 to (0xF, 2)).map(num =>
112    Module(new CSRModule(s"Iprio$num", new IprioBundle) with HasIeBundle {
113      val mask = Wire(Vec(8, UInt(8.W)))
114      for (i <- 0 until 8) {
115        mask(i) := Fill(8, mie.asUInt(num*4+i))
116      }
117      regOut := reg & mask.asUInt
118    })
119      .setAddr(0x30 + num)
120  )
121
122  val siprio0 = Module(new CSRModule(s"Iprio0", new Iprio0Bundle) with HasIeBundle {
123    val mask = Wire(Vec(8, UInt(8.W)))
124    for (i <- 0 until 8) {
125      mask(i) := Fill(8, sie.asUInt(i))
126    }
127    regOut := reg & mask.asUInt
128  })
129    .setAddr(0x30)
130
131  val siprio2 = Module(new CSRModule(s"Iprio2", new SIprio2Bundle) with HasIeBundle {
132    val mask = Wire(Vec(8, UInt(8.W)))
133    for (i <- 0 until 8) {
134      mask(i) := Fill(8, sie.asUInt(i+8))
135    }
136    regOut := reg & mask.asUInt
137  })
138    .setAddr(0x32)
139
140  val siprios: Seq[CSRModule[_]] = (4 to (0xF, 2)).map(num =>
141    Module(new CSRModule(s"Iprio$num", new IprioBundle) with HasIeBundle{
142      val mask = Wire(Vec(8, UInt(8.W)))
143      for (i <- 0 until 8) {
144        mask(i) := Fill(8, sie.asUInt(num*4+i))
145      }
146      regOut := reg & mask.asUInt
147    })
148    .setAddr(0x30 + num)
149  )
150
151  val miregiprios: Seq[CSRModule[_]] = Seq(miprio0, miprio2) ++: miprios
152
153  val siregiprios: Seq[CSRModule[_]] = Seq(siprio0, siprio2) ++: siprios
154
155  val iregiprios = miregiprios ++ siregiprios
156
157  val aiaCSRMods = Seq(
158    miselect,
159    mireg,
160    mtopei,
161    mtopi,
162    siselect,
163    sireg,
164    stopei,
165    stopi,
166    vsiselect,
167    vsireg,
168    vstopi,
169    vstopei,
170  )
171
172  val aiaCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
173    aiaCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
174  )
175
176  val aiaCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
177    aiaCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
178  )
179
180  private val miregRData: UInt = Mux1H(
181    miregiprios.map(prio => (miselect.rdata.asUInt === prio.addr.U) -> prio.rdata)
182  )
183
184  private val siregRData: UInt = Mux1H(
185    siregiprios.map(prio => (siselect.rdata.asUInt === prio.addr.U) -> prio.rdata)
186  )
187
188  aiaCSRMods.foreach { mod =>
189    mod match {
190      case m: HasIregSink =>
191        m.iregRead.mireg := miregRData
192        m.iregRead.sireg := siregRData
193        m.iregRead.vsireg := 0.U // Todo: IMSIC
194      case _ =>
195    }
196  }
197}
198
199class ISelectField(final val maxValue: Int, reserved: Seq[Range]) extends CSREnum with WARLApply {
200  override def isLegal(enumeration: CSREnumType): Bool = enumeration.asUInt <= maxValue.U
201}
202
203object VSISelectField extends ISelectField(
204  0x1FF,
205  reserved = Seq(
206    Range.inclusive(0x000, 0x02F),
207    Range.inclusive(0x040, 0x06F),
208    Range.inclusive(0x100, 0x1FF),
209  ),
210)
211
212object MISelectField extends ISelectField(
213  maxValue = 0xFF,
214  reserved = Seq(
215    Range.inclusive(0x00, 0x2F),
216    Range.inclusive(0x40, 0x6F),
217  ),
218)
219
220object SISelectField extends ISelectField(
221  maxValue = 0xFF,
222  reserved = Seq(
223    Range.inclusive(0x00, 0x2F),
224    Range.inclusive(0x40, 0x6F),
225  ),
226)
227
228class VSISelectBundle extends CSRBundle {
229  val ALL = VSISelectField(log2Up(0x1FF), 0, null).withReset(0.U)
230}
231
232class MISelectBundle extends CSRBundle {
233  val ALL = MISelectField(log2Up(0xFF), 0, null).withReset(0.U)
234}
235
236class SISelectBundle extends CSRBundle {
237  val ALL = SISelectField(log2Up(0xFF), 0, null).withReset(0.U)
238}
239
240class TopIBundle extends CSRBundle {
241  val IID   = RO(27, 16)
242  val IPRIO = RO(7, 0)
243}
244
245class TopEIBundle extends CSRBundle {
246  val IID   = RW(26, 16)
247  val IPRIO = RW(10, 0)
248}
249
250class IprioBundle extends FieldInitBundle
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 MIprio2Bundle extends CSRBundle {
262  val PrioSEI   = RW(15,  8).withReset(0.U)
263  val PrioVSEI  = RW(23, 16).withReset(0.U)
264  val PrioMEI   = RO(31, 24).withReset(0.U)
265  val PrioSGEI  = RW(39, 32).withReset(0.U)
266  val PrioLCOFI = RW(47, 40).withReset(0.U)
267  val Prio14    = RW(55, 48).withReset(0.U)
268  val Prio15    = RW(63, 56).withReset(0.U)
269}
270
271class SIprio2Bundle extends CSRBundle {
272  val PrioSEI   = RO(15,  8).withReset(0.U)
273  val PrioVSEI  = RW(23, 16).withReset(0.U)
274  val PrioMEI   = RW(31, 24).withReset(0.U)
275  val PrioSGEI  = RW(39, 32).withReset(0.U)
276  val PrioLCOFI = RW(47, 40).withReset(0.U)
277  val Prio14    = RW(55, 48).withReset(0.U)
278  val Prio15    = RW(63, 56).withReset(0.U)
279}
280
281class CSRToAIABundle extends Bundle {
282  private final val AddrWidth = 12
283
284  val addr = ValidIO(new Bundle {
285    val addr = UInt(AddrWidth.W)
286    val v = VirtMode()
287    val prvm = PrivMode()
288  })
289
290  val vgein = UInt(VGEINWidth.W)
291
292  val wdata = ValidIO(new Bundle {
293    val op = UInt(2.W)
294    val data = UInt(XLEN.W)
295  })
296
297  val mClaim = Bool()
298  val sClaim = Bool()
299  val vsClaim = Bool()
300}
301
302class AIAToCSRBundle extends Bundle {
303  private val NumVSIRFiles = 5
304  val rdata = ValidIO(new Bundle {
305    val data = UInt(XLEN.W)
306    val illegal = Bool()
307  })
308  val meip    = Bool()
309  val seip    = Bool()
310  val vseip   = UInt(NumVSIRFiles.W)
311  val mtopei  = new TopEIBundle
312  val stopei  = new TopEIBundle
313  val vstopei = new TopEIBundle
314}
315
316trait HasAIABundle { self: CSRModule[_] =>
317  val aiaToCSR = IO(Input(new AIAToCSRBundle))
318}
319
320trait HasInterruptFilterSink { self: CSRModule[_] =>
321  val topIR = IO(new Bundle {
322    val mtopi  = Input(new TopIBundle)
323    val stopi  = Input(new TopIBundle)
324    val vstopi = Input(new TopIBundle)
325  })
326}
327
328trait HasISelectBundle { self: CSRModule[_] =>
329  val inIMSICRange = IO(Output(Bool()))
330  val isIllegal = IO(Output(Bool()))
331}
332
333trait HasIregSink { self: CSRModule[_] =>
334  val iregRead = IO(Input(new Bundle {
335    val mireg = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width
336    val sireg = UInt(XLEN.W)
337    val vsireg = UInt(XLEN.W)
338  }))
339}
340
341trait HasIeBundle { self: CSRModule[_] =>
342  val mie = IO(Input(new MieBundle))
343  val sie = IO(Input(new SieBundle))
344}
345