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