xref: /XiangShan/src/main/scala/xiangshan/backend/fu/NewCSR/CSRPermitModule.scala (revision 6306fe335c2bca9aa17b8975c11e0e6116b494fd)
1package xiangshan.backend.fu.NewCSR
2
3import chisel3._
4import chisel3.util._
5import chisel3.util.experimental.decode.TruthTable
6import xiangshan.backend.fu.NewCSR.CSRBundles.PrivState
7import freechips.rocketchip.rocket.CSRs
8
9class CSRPermitModule extends Module {
10  val io = IO(new CSRPermitIO)
11
12  private val (ren, wen, addr, privState, debugMode) = (
13    io.in.csrAccess.ren,
14    io.in.csrAccess.wen,
15    io.in.csrAccess.addr,
16    io.in.privState,
17    io.in.debugMode
18  )
19
20  private val csrAccess = WireInit(ren || wen)
21
22  private val (mret, sret, wfi) = (
23    io.in.mret,
24    io.in.sret,
25    io.in.wfi,
26  )
27
28  private val (tsr, vtsr) = (
29    io.in.status.tsr,
30    io.in.status.vtsr,
31  )
32
33  private val (tw, vtw) = (
34    io.in.status.tw,
35    io.in.status.vtw
36  )
37
38  private val (tvm, vtvm) = (
39    io.in.status.tvm,
40    io.in.status.vtvm,
41  )
42
43  private val csrIsRO = addr(11, 10) === "b11".U
44
45  private val accessTable = TruthTable(Seq(
46    //       V PRVM ADDR
47    BitPat("b0__00___00") -> BitPat.Y(), // HU access U
48    BitPat("b1__00___00") -> BitPat.Y(), // VU access U
49    BitPat("b0__01___00") -> BitPat.Y(), // HS access U
50    BitPat("b0__01___01") -> BitPat.Y(), // HS access S
51    BitPat("b1__01___00") -> BitPat.Y(), // VS access U
52    BitPat("b1__01___01") -> BitPat.Y(), // VS access S
53    BitPat("b0__11___00") -> BitPat.Y(), // M  access HU
54    BitPat("b0__11___01") -> BitPat.Y(), // M  access HS
55    BitPat("b0__11___11") -> BitPat.Y(), // M  access M
56  ), BitPat.N())
57
58  private val isDebugReg = addr(11, 4) === "h7b".U
59  private val debugRegCanAccess = Mux(isDebugReg, debugMode, true.B)
60
61  private val isTriggerReg = addr(11, 4) === "h7a".U
62  private val triggerRegCanAccess = Mux(isTriggerReg, debugMode || privState.isModeM, true.B)
63
64  private val privilegeLegal = chisel3.util.experimental.decode.decoder(
65    privState.V.asUInt ## privState.PRVM.asUInt ## addr(9, 8),
66    accessTable
67  ).asBool
68
69  private val rwIllegal = csrIsRO && wen
70
71  private val csrAccessIllegal = (!privilegeLegal || rwIllegal) ||
72    (isDebugReg && !debugMode) ||                           // for debug reg
73    (isTriggerReg && !(debugMode || privState.isModeM))     // for trigger reg
74
75  private val mretIllegal = !privState.isModeM
76
77  private val sretIllegal = sret && (
78    privState.isModeHS && tsr || privState.isModeVS && vtsr || privState.isModeHUorVU
79  )
80
81  private val wfi_EX_II = wfi && (!privState.isModeM && tw)
82  private val wfi_EX_VI = wfi && (privState.isModeVS && vtw && !tw || privState.isModeVU && !tw)
83
84  private val rwSatp_EX_II = csrAccess && privState.isModeHS &&  tvm && (addr === CSRs.satp.U || addr === CSRs.hgatp.U)
85  private val rwSatp_EX_VI = csrAccess && privState.isModeVS && vtvm && (addr === CSRs.satp.U)
86
87  io.out.illegal := csrAccess && csrAccessIllegal || mret && mretIllegal || sret && sretIllegal
88
89  // Todo: check correct
90  io.out.EX_II := io.out.illegal && !privState.isVirtual || wfi_EX_II || rwSatp_EX_II
91  io.out.EX_VI := io.out.illegal &&  privState.isVirtual || wfi_EX_VI || rwSatp_EX_VI
92
93  io.out.hasLegalWen := io.in.csrAccess.wen && !csrAccessIllegal && debugRegCanAccess && triggerRegCanAccess
94  io.out.hasLegalMret := mret && !mretIllegal
95  io.out.hasLegalSret := sret && !sretIllegal
96  io.out.hasLegalWfi := wfi && !wfi_EX_II && !wfi_EX_VI
97}
98
99class CSRPermitIO extends Bundle {
100  val in = Input(new Bundle {
101    val csrAccess = new Bundle {
102      val ren = Bool()
103      val wen = Bool()
104      val addr = UInt(12.W)
105    }
106    val privState = new PrivState
107    val debugMode = Bool()
108    val mret = Bool()
109    val sret = Bool()
110    val wfi = Bool()
111    val status = new Bundle {
112      // Trap SRET
113      val tsr = Bool()
114      // Virtual Trap SRET
115      val vtsr = Bool()
116      // Timeout Wait
117      val tw = Bool()
118      // Virtual Timeout Wait
119      val vtw = Bool()
120      // Trap Virtual Memory
121      val tvm = Bool()
122      // Virtual Trap Virtual Memory
123      val vtvm = Bool()
124    }
125  })
126
127  val out = Output(new Bundle {
128    val hasLegalWen = Bool()
129    val hasLegalMret = Bool()
130    val hasLegalSret = Bool()
131    val hasLegalWfi = Bool()
132    // Todo: split illegal into EX_II and EX_VI
133    val illegal = Bool()
134    val EX_II = Bool()
135    val EX_VI = Bool()
136  })
137}
138