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