xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/NewCSR.scala (revision c2650312b580f636dcbe07b8ba84fa3d8b9d3e3d)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import org.chipsalliance.cde.config.Parameters
6import top.{ArgParser, Generator}
7import xiangshan.{HasXSParameter, XSCoreParamsKey, XSTileKey}
8import xiangshan.backend.fu.NewCSR.CSRDefines.{PrivMode, VirtMode}
9import xiangshan.backend.fu.NewCSR.CSREvents.{CSREvents, EventUpdatePrivStateOutput, MretEventSinkBundle, SretEventSinkBundle, TrapEntryEventInput, TrapEntryHSEventSinkBundle, TrapEntryMEventSinkBundle, TrapEntryVSEventSinkBundle}
10
11object CSRConfig {
12  final val GEILEN = 63
13
14  final val ASIDLEN = 16 // the length of ASID of XS implementation
15
16  final val ASIDMAX = 16 // the max value of ASIDLEN defined by spec
17
18  final val HIIDWidth = 12 // support Hvictl[27:16](IID)
19
20  final val VMIDLEN = 14 // the length of VMID of XS implementation
21
22  final val VMIDMAX = 14 // the max value of VMIDLEN defined by spec
23
24  // the width of VGEIN
25  final val VGEINWidth = 6
26
27  final val VaddrMaxWidth = 41 // only Sv39 and Sv39x4
28
29  final val XLEN = 64 // Todo: use XSParams
30}
31
32class NewCSR(implicit val p: Parameters) extends Module
33  with HasXSParameter
34  with MachineLevel
35  with SupervisorLevel
36  with HypervisorLevel
37  with VirtualSupervisorLevel
38  with Unprivileged
39  with CSRAIA
40  with HasExternalInterruptBundle
41  with HasInstCommitBundle
42  with SupervisorMachineAliasConnect
43  with CSREvents
44{
45
46  import CSRConfig._
47
48  val io = IO(new Bundle {
49    val w = Flipped(ValidIO(new Bundle {
50      val addr = UInt(12.W)
51      val data = UInt(64.W)
52    }))
53    val rAddr = Input(UInt(12.W))
54    val rData = Output(UInt(64.W))
55    val trap = Flipped(ValidIO(new Bundle {
56      val toPRVM          = PrivMode()
57      val toV             = VirtMode()
58      val tpc             = UInt(VaddrMaxWidth.W)
59      val isInterrupt     = Bool()
60      val trapVec         = UInt(64.W)
61      val isCrossPageIPF  = Bool()
62    }))
63    val fromMem = Input(new Bundle {
64      val excpVA  = UInt(VaddrMaxWidth.W)
65      val excpGPA = UInt(VaddrMaxWidth.W) // Todo: use guest physical address width
66    })
67    val tret = Flipped(ValidIO(new Bundle {
68      val toPRVM = PrivMode()
69      val toV = VirtMode()
70    }))
71    val out = new Bundle {
72      val targetPc = UInt(VaddrMaxWidth.W)
73    }
74  })
75
76  val toAIA   = IO(Output(new CSRToAIABundle))
77  val fromAIA = IO(Flipped(Output(new AIAToCSRBundle)))
78
79  dontTouch(toAIA)
80  dontTouch(fromAIA)
81  toAIA := DontCare
82
83  val addr = io.w.bits.addr
84  val data = io.w.bits.data
85  val wen = io.w.valid
86
87  val PRVM = RegInit(PrivMode(0), PrivMode.M)
88  val V = RegInit(VirtMode(0), VirtMode.Off)
89
90  val trap = io.trap.valid
91  val trapToPRVM = io.trap.bits.toPRVM
92  val trapToV = io.trap.bits.toV
93  val trapToM = trapToPRVM === PrivMode.M
94  val trapToHS = trapToPRVM === PrivMode.S && trapToV === VirtMode.Off
95  val trapToHU = trapToPRVM === PrivMode.U && trapToV === VirtMode.Off
96  val trapToVS = trapToPRVM === PrivMode.S && trapToV === VirtMode.On
97  val trapToVU = trapToPRVM === PrivMode.U && trapToV === VirtMode.On
98
99  val tret = io.tret.valid
100  val tretPRVM = io.tret.bits.toPRVM
101  val tretV = io.tret.bits.toV
102  val isSret = tret && tretPRVM === PrivMode.S
103  val isMret = tret && tretPRVM === PrivMode.M
104
105  var csrRwMap = machineLevelCSRMap ++ supervisorLevelCSRMap ++ hypervisorCSRMap ++ virtualSupervisorCSRMap ++ unprivilegedCSRMap ++ aiaCSRMap
106
107  val csrMods = machineLevelCSRMods ++ supervisorLevelCSRMods ++ hypervisorCSRMods ++ virtualSupervisorCSRMods ++ unprivilegedCSRMods ++ aiaCSRMods
108
109  for ((id, (wBundle, _)) <- csrRwMap) {
110    wBundle.wen := wen && addr === id.U
111    wBundle.wdata := data
112  }
113  io.rData := Mux1H(csrRwMap.map { case (id, (_, rBundle)) =>
114    (io.rAddr === id.U) -> rBundle.asUInt
115  })
116
117  csrMods.foreach { mod =>
118    mod match {
119      case m: HypervisorBundle =>
120        m.hstatus := hstatus.regOut
121        m.hvip := hvip.regOut
122        m.hideleg := hideleg.regOut
123        m.hedeleg := hedeleg.regOut
124        m.hgeip := hgeip.regOut
125        m.hgeie := hgeie.regOut
126        m.hip := hip.regOut
127        m.hie := hie.regOut
128      case _ =>
129    }
130    mod match {
131      case m: HasMachineInterruptBundle =>
132        m.mvien := mvien.regOut
133        m.mvip := mvip.regOut
134        m.mip := mip.regOut
135        m.mie := mie.regOut
136      case _ =>
137    }
138    mod match {
139      case m: HasMachineDelegBundle =>
140        m.mideleg := mideleg.regOut
141        m.medeleg := medeleg.regOut
142      case _ =>
143    }
144    mod match {
145      case m: HasMachineCounterControlBundle =>
146        m.mcountinhibit := mcountinhibit.regOut
147      case _ =>
148    }
149    mod match {
150      case m: HasExternalInterruptBundle =>
151        m.platformIRP := this.platformIRP
152      case _ =>
153    }
154    mod match {
155      case m: HasInstCommitBundle =>
156        m.commitValid := this.commitValid
157        m.commitInstNum := this.commitInstNum
158      case _ =>
159    }
160    mod match {
161      case m: TrapEntryMEventSinkBundle =>
162        m.trapToM := trapEntryMEvent.out
163      case _ =>
164    }
165    mod match {
166      case m: TrapEntryHSEventSinkBundle =>
167        m.trapToHS := trapEntryHSEvent.out
168      case _ =>
169    }
170    mod match {
171      case m: TrapEntryVSEventSinkBundle =>
172        m.trapToVS := trapEntryVSEvent.out
173      case _ =>
174    }
175    mod match {
176      case m: MretEventSinkBundle =>
177        m.retFromM := mretEvent.out
178      case _ =>
179    }
180    mod match {
181      case m: SretEventSinkBundle =>
182        m.retFromS := sretEvent.out
183      case _ =>
184    }
185  }
186
187  csrMods.foreach { mod =>
188    mod.commonIn.status := mstatus.mstatus
189    mod.commonIn.prvm := PRVM
190    mod.commonIn.v := V
191    mod.commonIn.hstatus := hstatus.rdata
192    println(s"${mod.modName}: ")
193    println(mod.dumpFields)
194  }
195
196  trapEntryMEvent.valid := trapToM
197  trapEntryHSEvent.valid := trapToHS
198  trapEntryVSEvent.valid := trapToVS
199
200  Seq(trapEntryMEvent, trapEntryHSEvent, trapEntryVSEvent).foreach { mod =>
201    mod.in match { case in: TrapEntryEventInput =>
202      in.causeNO := DontCare
203      in.trapPc := io.trap.bits.tpc
204      in.isCrossPageIPF := io.trap.bits.isCrossPageIPF
205
206      in.iMode.PRVM := PRVM
207      in.iMode.V := V
208      in.dMode.PRVM := Mux(mstatus.rdata.MPRV.asBool, mstatus.rdata.MPP, PRVM)
209      in.dMode.V := Mux(mstatus.rdata.MPRV.asBool, mstatus.rdata.MPV, V)
210
211      in.privState.PRVM := PRVM
212      in.privState.V := V
213      in.mstatus := mstatus.regOut
214      in.hstatus := hstatus.regOut
215      in.sstatus := mstatus.sstatus
216      in.vsstatus := vsstatus.regOut
217      in.satp := satp.rdata
218      in.vsatp := vsatp.rdata
219
220      in.memExceptionVAddr := io.fromMem.excpVA
221      in.memExceptionGPAddr := io.fromMem.excpGPA
222    }
223  }
224
225  mretEvent.valid := isMret
226  mretEvent.in match {
227    case in =>
228      in.mstatus := mstatus.regOut
229      in.mepc := mepc.regOut
230  }
231
232  sretEvent.valid := isSret
233  sretEvent.in match {
234    case in =>
235      in.privState.PRVM := PRVM
236      in.privState.V := V
237      in.sstatus := mstatus.sstatus
238      in.hstatus := hstatus.regOut
239      in.vsstatus := vsstatus.regOut
240      in.sepc := sepc.regOut
241      in.vsepc := vsepc.regOut
242  }
243
244  PRVM := MuxCase(
245    PRVM,
246    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
247      x => x.out match {
248        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.PRVM)
249      }
250    }
251  )
252
253  V := MuxCase(
254    V,
255    events.filter(_.out.isInstanceOf[EventUpdatePrivStateOutput]).map {
256      x => x.out match {
257        case xx: EventUpdatePrivStateOutput => (xx.privState.valid -> xx.privState.bits.V)
258      }
259    }
260  )
261
262  io.out.targetPc := Mux1H(Seq(
263    mretEvent.out.targetPc.valid -> mretEvent.out.targetPc.bits.asUInt
264  ))
265}
266
267trait SupervisorMachineAliasConnect { self: NewCSR with MachineLevel with SupervisorLevel =>
268  mip.fromMvip := mvip.toMip
269  mip.fromSip := sip.toMip
270  mie.fromSie := sie.toMie
271}
272
273object NewCSRMain extends App {
274  val (config, firrtlOpts, firtoolOpts) = ArgParser.parse(
275    args :+ "--disable-always-basic-diff" :+ "--dump-fir" :+ "--fpga-platform" :+ "--target" :+ "verilog")
276
277  val defaultConfig = config.alterPartial({
278    // Get XSCoreParams and pass it to the "small module"
279    case XSCoreParamsKey => config(XSTileKey).head
280  })
281
282  Generator.execute(
283    firrtlOpts :+ "--full-stacktrace" :+ "--target-dir" :+ "backend",
284    new NewCSR()(defaultConfig),
285    firtoolOpts
286  )
287
288  println("done")
289}