xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRAIA.scala (revision cdf05a9c30f5fa0ae231b1648b61dde8c327c28c)
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 CSRBundle {
31    val id   = RW(26, 16)
32    val prio = RW(10,  0)
33  }))
34    .setAddr(CSRs.mtopei)
35
36  val mtopi = Module(new CSRModule("Mtopi", new TopIBundle) with HasInterruptFilterSink {
37    regOut.IID   := topIR.mtopi.IID
38    regOut.IPRIO := topIR.mtopi.IPRIO
39  })
40    .setAddr(CSRs.mtopi)
41
42  val siselect = Module(new CSRModule("Siselect", new SISelectBundle) with HasISelectBundle {
43    private val value = reg.ALL.asUInt
44    inIMSICRange := value >= 0x70.U && value < 0x100.U && value(0) =/= 1.U
45    isIllegal :=
46      value < 0x30.U ||
47      value >= 0x40.U && value < 0x70.U ||
48      value >= 0x100.U ||
49      value(0) === 1.U
50  })
51    .setAddr(CSRs.siselect)
52
53  val sireg = Module(new CSRModule("Sireg") with HasIregSink {
54    rdata := iregRead.sireg
55  })
56    .setAddr(CSRs.sireg)
57
58  val stopei = Module(new CSRModule("Stopei", new CSRBundle {
59    val id   = RW(26, 16)
60    val prio = RW(10,  0)
61  }))
62    .setAddr(CSRs.stopei)
63
64  val stopi = Module(new CSRModule("Stopi", new TopIBundle) with HasInterruptFilterSink {
65    regOut.IID   := topIR.stopi.IID
66    regOut.IPRIO := topIR.stopi.IPRIO
67  })
68    .setAddr(CSRs.stopi)
69
70  val vsiselect = Module(new CSRModule("VSiselect", new VSISelectBundle) with HasISelectBundle {
71    private val value = reg.ALL.asUInt
72    inIMSICRange := value >= 0x70.U && value < 0x100.U && value(0) =/= 1.U
73    isIllegal :=
74      value < 0x70.U ||
75      value >= 0x100.U ||
76      value(0) === 1.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 CSRBundle {
86    val id   = RW(26, 16)
87    val prio = RW(10,  0)
88  }))
89    .setAddr(CSRs.vstopei)
90
91  val vstopi = Module(new CSRModule("VStopi", new TopIBundle) with HasInterruptFilterSink {
92    regOut.IID   := topIR.vstopi.IID
93    regOut.IPRIO := topIR.vstopi.IPRIO
94  })
95    .setAddr(CSRs.vstopi)
96
97  val miregiprios: Seq[CSRModule[_]] = Range(0, 0xF, 2).map(num =>
98    Module(new CSRModule(s"Iprio$num"))
99      .setAddr(0x30 + num)
100  )
101
102  val siregiprios: Seq[CSRModule[_]] = Range(0, 0xF, 2).map(num =>
103    Module(new CSRModule(s"Iprio$num"))
104      .setAddr(0x30 + num)
105  )
106
107  val aiaCSRMods = Seq(
108    miselect,
109    mireg,
110    mtopei,
111    mtopi,
112    siselect,
113    sireg,
114    stopei,
115    stopi,
116    vsiselect,
117    vsireg,
118    vstopi,
119    vstopei,
120  )
121
122  val aiaSkipCSRs = Seq(
123    mtopei,
124    mtopi,
125    stopei,
126    stopi,
127    vstopi,
128    vstopei,
129  )
130
131  val aiaCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
132    aiaCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
133  )
134
135  val aiaCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
136    aiaCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
137  )
138
139  private val miregRData: UInt = Mux1H(
140    miregiprios.map(prio => (miselect.rdata.asUInt === prio.addr.U) -> prio.rdata)
141  )
142
143  private val siregRData: UInt = Mux1H(
144    siregiprios.map(prio => (siselect.rdata.asUInt === prio.addr.U) -> prio.rdata)
145  )
146
147  aiaCSRMods.foreach { mod =>
148    mod match {
149      case m: HasIregSink =>
150        m.iregRead.mireg := miregRData
151        m.iregRead.sireg := siregRData
152        m.iregRead.vsireg := 0.U // Todo: IMSIC
153      case _ =>
154    }
155  }
156}
157
158class ISelectField(final val maxValue: Int, reserved: Seq[Range]) extends CSREnum with WARLApply {
159  override def isLegal(enum: CSREnumType): Bool = {
160    !reserved.map(range => enum.asUInt >= range.start.U && enum.asUInt <= range.end.U).reduce(_ || _)
161  }
162}
163
164object VSISelectField extends ISelectField(
165  0x1FF,
166  reserved = Seq(
167    Range.inclusive(0x000, 0x02F),
168    Range.inclusive(0x040, 0x06F),
169    Range.inclusive(0x100, 0x1FF),
170  ),
171)
172
173object MISelectField extends ISelectField(
174  maxValue = 0xFF,
175  reserved = Seq(
176    Range.inclusive(0x00, 0x2F),
177    Range.inclusive(0x40, 0x6F),
178  ),
179)
180
181object SISelectField extends ISelectField(
182  maxValue = 0xFF,
183  reserved = Seq(
184    Range.inclusive(0x00, 0x2F),
185    Range.inclusive(0x40, 0x6F),
186  ),
187)
188
189class VSISelectBundle extends CSRBundle {
190  val ALL = VSISelectField(log2Up(0x1FF), 0, null)
191}
192
193class MISelectBundle extends CSRBundle {
194  val ALL = MISelectField(log2Up(0xFF), 0, null)
195}
196
197class SISelectBundle extends CSRBundle {
198  val ALL = SISelectField(log2Up(0xFF), 0, null)
199}
200
201class TopIBundle extends CSRBundle {
202  val IID   = RO(27, 16)
203  val IPRIO = RO(7, 0)
204}
205
206class TopEIBundle extends CSRBundle {
207  val IID   = RW(26, 16)
208  val IPRIO = RW(10, 0)
209}
210
211class IprioBundle extends CSRBundle {
212  val ALL = RW(63, 0).withReset(0.U)
213}
214
215class CSRToAIABundle extends Bundle {
216  private final val AddrWidth = 12
217
218  val addr = ValidIO(new Bundle {
219    val addr = UInt(AddrWidth.W)
220    val v = VirtMode()
221    val prvm = PrivMode()
222  })
223
224  val vgein = UInt(VGEINWidth.W)
225
226  val wdata = ValidIO(new Bundle {
227    val op = UInt(2.W)
228    val data = UInt(XLEN.W)
229  })
230
231  val mClaim = Bool()
232  val sClaim = Bool()
233  val vsClaim = Bool()
234}
235
236class AIAToCSRBundle extends Bundle {
237  val rdata = ValidIO(new Bundle {
238    val data = UInt(XLEN.W)
239    val illegal = Bool()
240  })
241  val mtopei = ValidIO(new TopEIBundle)
242  val stopei = ValidIO(new TopEIBundle)
243  val vstopei = ValidIO(new TopEIBundle)
244}
245
246trait HasAIABundle { self: CSRModule[_] =>
247  val aiaToCSR = IO(Input(new AIAToCSRBundle))
248}
249
250trait HasInterruptFilterSink { self: CSRModule[_] =>
251  val topIR = IO(new Bundle {
252    val mtopi  = Input(new TopIBundle)
253    val stopi  = Input(new TopIBundle)
254    val vstopi = Input(new TopIBundle)
255  })
256}
257
258trait HasISelectBundle { self: CSRModule[_] =>
259  val inIMSICRange = IO(Output(Bool()))
260  val isIllegal = IO(Output(Bool()))
261}
262
263trait HasIregSink { self: CSRModule[_] =>
264  val iregRead = IO(Input(new Bundle {
265    val mireg = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width
266    val sireg = UInt(XLEN.W)
267    val vsireg = UInt(XLEN.W)
268  }))
269}