xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRAIA.scala (revision 96e3f6c1467adc591a1cc2ea2aa16a200bb2313f)
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))
94    .setAddr(0x30)
95
96  val miprios: Seq[CSRModule[_]] = (2 to (0xF, 2)).map(num =>
97    Module(new CSRModule(s"Iprio$num", new IprioBundle))
98      .setAddr(0x30 + num)
99  )
100
101  val siprio0 = Module(new CSRModule(s"Iprio0", new Iprio0Bundle))
102    .setAddr(0x30)
103
104  val siprios: Seq[CSRModule[_]] = (2 to (0xF, 2)).map(num =>
105    Module(new CSRModule(s"Iprio$num", new IprioBundle))
106    .setAddr(0x30 + num)
107  )
108
109  val miregiprios: Seq[CSRModule[_]] = Seq(miprio0) ++: miprios
110
111  val siregiprios: Seq[CSRModule[_]] = Seq(siprio0) ++: siprios
112
113  val aiaCSRMods = Seq(
114    miselect,
115    mireg,
116    mtopei,
117    mtopi,
118    siselect,
119    sireg,
120    stopei,
121    stopi,
122    vsiselect,
123    vsireg,
124    vstopi,
125    vstopei,
126  )
127
128  val aiaCSRMap: SeqMap[Int, (CSRAddrWriteBundle[_], UInt)] = SeqMap.from(
129    aiaCSRMods.map(csr => (csr.addr -> (csr.w -> csr.rdata))).iterator
130  )
131
132  val aiaCSROutMap: SeqMap[Int, UInt] = SeqMap.from(
133    aiaCSRMods.map(csr => (csr.addr -> csr.regOut.asInstanceOf[CSRBundle].asUInt)).iterator
134  )
135
136  private val miregRData: UInt = Mux1H(
137    miregiprios.map(prio => (miselect.rdata.asUInt === prio.addr.U) -> prio.rdata)
138  )
139
140  private val siregRData: UInt = Mux1H(
141    siregiprios.map(prio => (siselect.rdata.asUInt === prio.addr.U) -> prio.rdata)
142  )
143
144  aiaCSRMods.foreach { mod =>
145    mod match {
146      case m: HasIregSink =>
147        m.iregRead.mireg := miregRData
148        m.iregRead.sireg := siregRData
149        m.iregRead.vsireg := 0.U // Todo: IMSIC
150      case _ =>
151    }
152  }
153}
154
155class ISelectField(final val maxValue: Int, reserved: Seq[Range]) extends CSREnum with WARLApply {
156  override def isLegal(enumeration: CSREnumType): Bool = enumeration.asUInt <= maxValue.U
157}
158
159object VSISelectField extends ISelectField(
160  0x1FF,
161  reserved = Seq(
162    Range.inclusive(0x000, 0x02F),
163    Range.inclusive(0x040, 0x06F),
164    Range.inclusive(0x100, 0x1FF),
165  ),
166)
167
168object MISelectField extends ISelectField(
169  maxValue = 0xFF,
170  reserved = Seq(
171    Range.inclusive(0x00, 0x2F),
172    Range.inclusive(0x40, 0x6F),
173  ),
174)
175
176object SISelectField extends ISelectField(
177  maxValue = 0xFF,
178  reserved = Seq(
179    Range.inclusive(0x00, 0x2F),
180    Range.inclusive(0x40, 0x6F),
181  ),
182)
183
184class VSISelectBundle extends CSRBundle {
185  val ALL = VSISelectField(log2Up(0x1FF), 0, null).withReset(0.U)
186}
187
188class MISelectBundle extends CSRBundle {
189  val ALL = MISelectField(log2Up(0xFF), 0, null).withReset(0.U)
190}
191
192class SISelectBundle extends CSRBundle {
193  val ALL = SISelectField(log2Up(0xFF), 0, null).withReset(0.U)
194}
195
196class TopIBundle extends CSRBundle {
197  val IID   = RO(27, 16)
198  val IPRIO = RO(7, 0)
199}
200
201class TopEIBundle extends CSRBundle {
202  val IID   = RW(26, 16)
203  val IPRIO = RW(10, 0)
204}
205
206class IprioBundle extends FieldInitBundle
207
208class Iprio0Bundle extends CSRBundle {
209  val PrioSSI  = RW(15,  8).withReset(0.U)
210  val PrioVSSI = RW(23, 16).withReset(0.U)
211  val PrioMSI  = RW(31, 24).withReset(0.U)
212  val PrioSTI  = RW(47, 40).withReset(0.U)
213  val PrioVSTI = RW(55, 48).withReset(0.U)
214  val PrioMTI  = RW(63, 56).withReset(0.U)
215}
216
217class CSRToAIABundle extends Bundle {
218  private final val AddrWidth = 12
219
220  val addr = ValidIO(new Bundle {
221    val addr = UInt(AddrWidth.W)
222    val v = VirtMode()
223    val prvm = PrivMode()
224  })
225
226  val vgein = UInt(VGEINWidth.W)
227
228  val wdata = ValidIO(new Bundle {
229    val op = UInt(2.W)
230    val data = UInt(XLEN.W)
231  })
232
233  val mClaim = Bool()
234  val sClaim = Bool()
235  val vsClaim = Bool()
236}
237
238class AIAToCSRBundle extends Bundle {
239  private val NumVSIRFiles = 63
240  val rdata = ValidIO(new Bundle {
241    val data = UInt(XLEN.W)
242    val illegal = Bool()
243  })
244  val meip    = Bool()
245  val seip    = Bool()
246  val vseip   = UInt(NumVSIRFiles.W)
247  val mtopei  = new TopEIBundle
248  val stopei  = new TopEIBundle
249  val vstopei = new TopEIBundle
250}
251
252trait HasAIABundle { self: CSRModule[_] =>
253  val aiaToCSR = IO(Input(new AIAToCSRBundle))
254}
255
256trait HasInterruptFilterSink { self: CSRModule[_] =>
257  val topIR = IO(new Bundle {
258    val mtopi  = Input(new TopIBundle)
259    val stopi  = Input(new TopIBundle)
260    val vstopi = Input(new TopIBundle)
261  })
262}
263
264trait HasISelectBundle { self: CSRModule[_] =>
265  val inIMSICRange = IO(Output(Bool()))
266  val isIllegal = IO(Output(Bool()))
267}
268
269trait HasIregSink { self: CSRModule[_] =>
270  val iregRead = IO(Input(new Bundle {
271    val mireg = UInt(XLEN.W) // Todo: check if use ireg bundle, and shrink the width
272    val sireg = UInt(XLEN.W)
273    val vsireg = UInt(XLEN.W)
274  }))
275}
276