xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala (revision 9c13e9625dd5ed5520c98b7b287a5c1bfa21f5be)
1/***************************************************************************************
2* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
3* Copyright (c) 2020-2021 Peng Cheng Laboratory
4*
5* XiangShan is licensed under Mulan PSL v2.
6* You can use this software according to the terms and conditions of the Mulan PSL v2.
7* You may obtain a copy of Mulan PSL v2 at:
8*          http://license.coscl.org.cn/MulanPSL2
9*
10* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13*
14* See the Mulan PSL v2 for more details.
15***************************************************************************************/
16
17package xiangshan.backend.decode
18
19import org.chipsalliance.cde.config.Parameters
20import chisel3._
21import chisel3.util._
22import freechips.rocketchip.rocket.CSRs
23import freechips.rocketchip.rocket.Instructions._
24import freechips.rocketchip.rocket.CustomInstructions._
25import freechips.rocketchip.util.uintToBitPat
26import utility._
27import utils._
28import xiangshan.ExceptionNO.{EX_II, breakPoint, illegalInstr, virtualInstr}
29import xiangshan._
30import xiangshan.backend.fu.FuType
31import xiangshan.backend.Bundles.{DecodedInst, DynInst, StaticInst}
32import xiangshan.backend.decode.isa.PseudoInstructions
33import xiangshan.backend.decode.isa.bitfield.{InstVType, OPCODE5Bit, XSInstBitFields}
34import xiangshan.backend.fu.vector.Bundles.{VType, Vl}
35import xiangshan.backend.fu.wrapper.CSRToDecode
36import xiangshan.backend.decode.Zimop._
37import yunsuan.{VfaluType, VfcvtType}
38
39/**
40 * Abstract trait giving defaults and other relevant values to different Decode constants/
41 */
42abstract trait DecodeConstants {
43  // This X should be used only in 1-bit signal. Otherwise, use BitPat("b???") to align with the width of UInt.
44  def X = BitPat("b0")
45  def N = BitPat("b0")
46  def Y = BitPat("b1")
47  def T = true
48  def F = false
49
50  def decodeDefault: List[BitPat] = // illegal instruction
51    //   srcType(0) srcType(1) srcType(2) fuType    fuOpType    rfWen
52    //   |          |          |          |         |           |  fpWen
53    //   |          |          |          |         |           |  |  vecWen
54    //   |          |          |          |         |           |  |  |  isXSTrap
55    //   |          |          |          |         |           |  |  |  |  noSpecExec
56    //   |          |          |          |         |           |  |  |  |  |  blockBackward
57    //   |          |          |          |         |           |  |  |  |  |  |  flushPipe
58    //   |          |          |          |         |           |  |  |  |  |  |  |  canRobCompress
59    //   |          |          |          |         |           |  |  |  |  |  |  |  |  uopSplitType
60    //   |          |          |          |         |           |  |  |  |  |  |  |  |  |             selImm
61    List(SrcType.X, SrcType.X, SrcType.X, FuType.X, FuOpType.X, N, N, N, N, N, N, N, N, UopSplitType.X, SelImm.INVALID_INSTR) // Use SelImm to indicate invalid instr
62
63  val decodeArray: Array[(BitPat, XSDecodeBase)]
64  final def table: Array[(BitPat, List[BitPat])] = decodeArray.map(x => (x._1, x._2.generate()))
65}
66
67trait DecodeUnitConstants
68{
69  // abstract out instruction decode magic numbers
70  val RD_MSB  = 11
71  val RD_LSB  = 7
72  val RS1_MSB = 19
73  val RS1_LSB = 15
74  val RS2_MSB = 24
75  val RS2_LSB = 20
76  val RS3_MSB = 31
77  val RS3_LSB = 27
78}
79
80/**
81 * Decoded control signals
82 * See xiangshan/package.scala, xiangshan/backend/package.scala, Bundle.scala
83 */
84
85abstract class XSDecodeBase {
86  def X = BitPat("b?")
87  def N = BitPat("b0")
88  def Y = BitPat("b1")
89  def T = true
90  def F = false
91  def generate() : List[BitPat]
92}
93
94case class XSDecode(
95  src1: BitPat, src2: BitPat, src3: BitPat,
96  fu: FuType.OHType, fuOp: BitPat, selImm: BitPat,
97  uopSplitType: BitPat = UopSplitType.X,
98  xWen: Boolean = false,
99  fWen: Boolean = false,
100  vWen: Boolean = false,
101  mWen: Boolean = false,
102  xsTrap: Boolean = false,
103  noSpec: Boolean = false,
104  blockBack: Boolean = false,
105  flushPipe: Boolean = false,
106  canRobCompress: Boolean = false,
107) extends XSDecodeBase {
108  def generate() : List[BitPat] = {
109    List (src1, src2, src3, BitPat(fu.U(FuType.num.W)), fuOp, xWen.B, fWen.B, (vWen || mWen).B, xsTrap.B, noSpec.B, blockBack.B, flushPipe.B, canRobCompress.B, uopSplitType, selImm)
110  }
111}
112
113case class FDecode(
114  src1: BitPat, src2: BitPat, src3: BitPat,
115  fu: FuType.OHType, fuOp: BitPat, selImm: BitPat = SelImm.X,
116  uopSplitType: BitPat = UopSplitType.X,
117  xWen: Boolean = false,
118  fWen: Boolean = false,
119  vWen: Boolean = false,
120  mWen: Boolean = false,
121  xsTrap: Boolean = false,
122  noSpec: Boolean = false,
123  blockBack: Boolean = false,
124  flushPipe: Boolean = false,
125  canRobCompress: Boolean = false,
126) extends XSDecodeBase {
127  def generate() : List[BitPat] = {
128    XSDecode(src1, src2, src3, fu, fuOp, selImm, uopSplitType, xWen, fWen, vWen, mWen, xsTrap, noSpec, blockBack, flushPipe, canRobCompress).generate()
129  }
130}
131
132/**
133 * Overall Decode constants
134 */
135object XDecode extends DecodeConstants {
136  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
137    // RV32I
138    LW      -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lw  , SelImm.IMM_I, xWen = T),
139    LH      -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lh  , SelImm.IMM_I, xWen = T),
140    LHU     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lhu , SelImm.IMM_I, xWen = T),
141    LB      -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lb  , SelImm.IMM_I, xWen = T),
142    LBU     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lbu , SelImm.IMM_I, xWen = T),
143    SW      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu, LSUOpType.sw  , SelImm.IMM_S          ),
144    SH      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu, LSUOpType.sh  , SelImm.IMM_S          ),
145    SB      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu, LSUOpType.sb  , SelImm.IMM_S          ),
146    LUI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.add , SelImm.IMM_U, xWen = T, canRobCompress = T),
147    ADDI    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.add , SelImm.IMM_I, xWen = T, canRobCompress = T),
148    ANDI    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.and , SelImm.IMM_I, xWen = T, canRobCompress = T),
149    ORI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.or  , SelImm.IMM_I, xWen = T, canRobCompress = T),
150    XORI    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.xor , SelImm.IMM_I, xWen = T, canRobCompress = T),
151    SLTI    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.slt , SelImm.IMM_I, xWen = T, canRobCompress = T),
152    SLTIU   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.sltu, SelImm.IMM_I, xWen = T, canRobCompress = T),
153    SLL     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sll , SelImm.X    , xWen = T, canRobCompress = T),
154    ADD     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.add , SelImm.X    , xWen = T, canRobCompress = T),
155    SUB     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sub , SelImm.X    , xWen = T, canRobCompress = T),
156    SLT     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.slt , SelImm.X    , xWen = T, canRobCompress = T),
157    SLTU    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sltu, SelImm.X    , xWen = T, canRobCompress = T),
158    AND     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.and , SelImm.X    , xWen = T, canRobCompress = T),
159    OR      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.or  , SelImm.X    , xWen = T, canRobCompress = T),
160    XOR     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.xor , SelImm.X    , xWen = T, canRobCompress = T),
161    SRA     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sra , SelImm.X    , xWen = T, canRobCompress = T),
162    SRL     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.srl , SelImm.X    , xWen = T, canRobCompress = T),
163
164    // RV64I (extend from RV32I)
165    LD      -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.ld  , SelImm.IMM_I, xWen = T),
166    LWU     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lwu , SelImm.IMM_I, xWen = T),
167    SD      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu, LSUOpType.sd  , SelImm.IMM_S          ),
168
169    SLLI    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.sll , SelImm.IMM_I, xWen = T, canRobCompress = T),
170    SRLI    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.srl , SelImm.IMM_I, xWen = T, canRobCompress = T),
171    SRAI    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.sra , SelImm.IMM_I, xWen = T, canRobCompress = T),
172
173    ADDIW   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.addw, SelImm.IMM_I, xWen = T, canRobCompress = T),
174    SLLIW   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.sllw, SelImm.IMM_I, xWen = T, canRobCompress = T),
175    SRAIW   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.sraw, SelImm.IMM_I, xWen = T, canRobCompress = T),
176    SRLIW   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.srlw, SelImm.IMM_I, xWen = T, canRobCompress = T),
177
178    ADDW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.addw, SelImm.X    , xWen = T, canRobCompress = T),
179    SUBW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.subw, SelImm.X    , xWen = T, canRobCompress = T),
180    SLLW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sllw, SelImm.X    , xWen = T, canRobCompress = T),
181    SRAW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sraw, SelImm.X    , xWen = T, canRobCompress = T),
182    SRLW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.srlw, SelImm.X    , xWen = T, canRobCompress = T),
183
184    // RV64M
185    MUL     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mul, MDUOpType.mul   , SelImm.X, xWen = T, canRobCompress = T),
186    MULH    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mul, MDUOpType.mulh  , SelImm.X, xWen = T, canRobCompress = T),
187    MULHU   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mul, MDUOpType.mulhu , SelImm.X, xWen = T, canRobCompress = T),
188    MULHSU  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mul, MDUOpType.mulhsu, SelImm.X, xWen = T, canRobCompress = T),
189    MULW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mul, MDUOpType.mulw  , SelImm.X, xWen = T, canRobCompress = T),
190
191    DIV     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.div, MDUOpType.div   , SelImm.X, xWen = T, canRobCompress = T),
192    DIVU    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.div, MDUOpType.divu  , SelImm.X, xWen = T, canRobCompress = T),
193    REM     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.div, MDUOpType.rem   , SelImm.X, xWen = T, canRobCompress = T),
194    REMU    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.div, MDUOpType.remu  , SelImm.X, xWen = T, canRobCompress = T),
195    DIVW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.div, MDUOpType.divw  , SelImm.X, xWen = T, canRobCompress = T),
196    DIVUW   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.div, MDUOpType.divuw , SelImm.X, xWen = T, canRobCompress = T),
197    REMW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.div, MDUOpType.remw  , SelImm.X, xWen = T, canRobCompress = T),
198    REMUW   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.div, MDUOpType.remuw , SelImm.X, xWen = T, canRobCompress = T),
199
200    AUIPC   -> XSDecode(SrcType.pc , SrcType.imm, SrcType.X, FuType.jmp, JumpOpType.auipc, SelImm.IMM_U , xWen = T),
201    JAL     -> XSDecode(SrcType.pc , SrcType.imm, SrcType.X, FuType.jmp, JumpOpType.jal  , SelImm.IMM_UJ, xWen = T),
202    JALR    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.jmp, JumpOpType.jalr , SelImm.IMM_I , xWen = T),
203    BEQ     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.brh, BRUOpType.beq   , SelImm.IMM_SB          ),
204    BNE     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.brh, BRUOpType.bne   , SelImm.IMM_SB          ),
205    BGE     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.brh, BRUOpType.bge   , SelImm.IMM_SB          ),
206    BGEU    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.brh, BRUOpType.bgeu  , SelImm.IMM_SB          ),
207    BLT     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.brh, BRUOpType.blt   , SelImm.IMM_SB          ),
208    BLTU    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.brh, BRUOpType.bltu  , SelImm.IMM_SB          ),
209
210    // System, the immediate12 holds the CSR register.
211
212    CSRRW   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.wrt , SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
213    CSRRS   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.set , SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
214    CSRRC   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.clr , SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
215
216    CSRRWI  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.wrti, SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
217    CSRRSI  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.seti, SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
218    CSRRCI  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.clri, SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
219
220    EBREAK  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
221    ECALL   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
222    SRET    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
223    MRET    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
224    MNRET   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
225    DRET    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
226    WFI     -> XSDecode(SrcType.pc , SrcType.imm, SrcType.X, FuType.csr, CSROpType.wfi, SelImm.X    , xWen = T, noSpec = T, blockBack = T),
227
228    SFENCE_VMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.sfence, SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
229    FENCE_I    -> XSDecode(SrcType.pc , SrcType.imm, SrcType.X, FuType.fence, FenceOpType.fencei, SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
230    FENCE      -> XSDecode(SrcType.pc , SrcType.imm, SrcType.X, FuType.fence, FenceOpType.fence , SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
231    PAUSE      -> XSDecode(SrcType.pc , SrcType.imm, SrcType.X, FuType.fence, FenceOpType.fence , SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
232
233    // RV64A
234    AMOADD_W  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoadd_w , SelImm.X, xWen = T, noSpec = T, blockBack = T),
235    AMOXOR_W  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoxor_w , SelImm.X, xWen = T, noSpec = T, blockBack = T),
236    AMOSWAP_W -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoswap_w, SelImm.X, xWen = T, noSpec = T, blockBack = T),
237    AMOAND_W  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoand_w , SelImm.X, xWen = T, noSpec = T, blockBack = T),
238    AMOOR_W   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoor_w  , SelImm.X, xWen = T, noSpec = T, blockBack = T),
239    AMOMIN_W  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomin_w , SelImm.X, xWen = T, noSpec = T, blockBack = T),
240    AMOMINU_W -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amominu_w, SelImm.X, xWen = T, noSpec = T, blockBack = T),
241    AMOMAX_W  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomax_w , SelImm.X, xWen = T, noSpec = T, blockBack = T),
242    AMOMAXU_W -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomaxu_w, SelImm.X, xWen = T, noSpec = T, blockBack = T),
243
244    AMOADD_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoadd_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
245    AMOXOR_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoxor_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
246    AMOSWAP_D -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoswap_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
247    AMOAND_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoand_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
248    AMOOR_D   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoor_d  , SelImm.X, xWen = T, noSpec = T, blockBack = T),
249    AMOMIN_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomin_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
250    AMOMINU_D -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amominu_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
251    AMOMAX_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomax_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
252    AMOMAXU_D -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomaxu_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
253
254    LR_W    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.mou, LSUOpType.lr_w, SelImm.X, xWen = T, noSpec = T, blockBack = T),
255    LR_D    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.mou, LSUOpType.lr_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
256    SC_W    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.sc_w, SelImm.X, xWen = T, noSpec = T, blockBack = T),
257    SC_D    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.sc_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
258  )
259}
260
261object BitmanipDecode extends DecodeConstants{
262  /*
263    Note: Some Bitmanip instruction may have different OP code between rv32 and rv64.
264    Including pseudo instruction like zext.h, and different funct12 like rev8.
265    If some day we need to support change XLEN via CSR, we should care about this.
266   */
267  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
268    // Zba
269    ADD_UW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.adduw   , SelImm.X    , xWen = T, canRobCompress = T),
270    SH1ADD    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh1add  , SelImm.X    , xWen = T, canRobCompress = T),
271    SH1ADD_UW -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh1adduw, SelImm.X    , xWen = T, canRobCompress = T),
272    SH2ADD    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh2add  , SelImm.X    , xWen = T, canRobCompress = T),
273    SH2ADD_UW -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh2adduw, SelImm.X    , xWen = T, canRobCompress = T),
274    SH3ADD    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh3add  , SelImm.X    , xWen = T, canRobCompress = T),
275    SH3ADD_UW -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh3adduw, SelImm.X    , xWen = T, canRobCompress = T),
276    SLLI_UW   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.slliuw  , SelImm.IMM_I, xWen = T, canRobCompress = T),
277
278    // Zbb
279    ANDN      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.andn    , SelImm.X    , xWen = T, canRobCompress = T),
280    ORN       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.orn     , SelImm.X    , xWen = T, canRobCompress = T),
281    XNOR      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.xnor    , SelImm.X    , xWen = T, canRobCompress = T),
282
283    CLZ       -> XSDecode(SrcType.reg, SrcType.DC , SrcType.X, FuType.bku, BKUOpType.clz     , SelImm.X    , xWen = T, canRobCompress = T),
284    CLZW      -> XSDecode(SrcType.reg, SrcType.DC , SrcType.X, FuType.bku, BKUOpType.clzw    , SelImm.X    , xWen = T, canRobCompress = T),
285    CTZ       -> XSDecode(SrcType.reg, SrcType.DC , SrcType.X, FuType.bku, BKUOpType.ctz     , SelImm.X    , xWen = T, canRobCompress = T),
286    CTZW      -> XSDecode(SrcType.reg, SrcType.DC , SrcType.X, FuType.bku, BKUOpType.ctzw    , SelImm.X    , xWen = T, canRobCompress = T),
287
288    CPOP      -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.cpop    , SelImm.X    , xWen = T, canRobCompress = T),
289    CPOPW     -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.cpopw   , SelImm.X    , xWen = T, canRobCompress = T),
290
291    MAX       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.max     , SelImm.X    , xWen = T, canRobCompress = T),
292    MAXU      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.maxu    , SelImm.X    , xWen = T, canRobCompress = T),
293    MIN       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.min     , SelImm.X    , xWen = T, canRobCompress = T),
294    MINU      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.minu    , SelImm.X    , xWen = T, canRobCompress = T),
295
296    SEXT_B    -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.sextb   , SelImm.X    , xWen = T, canRobCompress = T),
297    SEXT_H    -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.sexth   , SelImm.X    , xWen = T, canRobCompress = T),
298    // zext.h in rv64 is shared with packw in Zbkb with rs2 = $0.
299    // If we configured to have no Zbkb, we should add zext.h here.
300
301    ROL       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.rol     , SelImm.X    , xWen = T, canRobCompress = T),
302    ROLW      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.rolw    , SelImm.X    , xWen = T, canRobCompress = T),
303    ROR       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.ror     , SelImm.X    , xWen = T, canRobCompress = T),
304    RORI      -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.ror     , SelImm.IMM_I, xWen = T, canRobCompress = T),
305    RORIW     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.rorw    , SelImm.IMM_I, xWen = T, canRobCompress = T),
306    RORW      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.rorw    , SelImm.X    , xWen = T, canRobCompress = T),
307
308    ORC_B     -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.orcb    , SelImm.X    , xWen = T, canRobCompress = T),
309
310    REV8      -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.rev8    , SelImm.X    , xWen = T, canRobCompress = T),
311
312    // Zbc
313    CLMUL     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.clmul   , SelImm.X    , xWen = T, canRobCompress = T),
314    CLMULH    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.clmulh  , SelImm.X    , xWen = T, canRobCompress = T),
315    CLMULR    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.clmulr  , SelImm.X    , xWen = T, canRobCompress = T),
316
317    // Zbs
318    BCLR      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.bclr    , SelImm.X    , xWen = T, canRobCompress = T),
319    BCLRI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.bclr    , SelImm.IMM_I, xWen = T, canRobCompress = T),
320    BEXT      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.bext    , SelImm.X    , xWen = T, canRobCompress = T),
321    BEXTI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.bext    , SelImm.IMM_I, xWen = T, canRobCompress = T),
322    BINV      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.binv    , SelImm.X    , xWen = T, canRobCompress = T),
323    BINVI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.binv    , SelImm.IMM_I, xWen = T, canRobCompress = T),
324    BSET      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.bset    , SelImm.X    , xWen = T, canRobCompress = T),
325    BSETI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.bset    , SelImm.IMM_I, xWen = T, canRobCompress = T),
326
327    // Zbkb
328    // rol, rolw, ror,rori, roriw, rorw, andn, orn, xnor, rev8 is in Zbb
329    PACK      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.pack    , SelImm.X    , xWen = T, canRobCompress = T),
330    PACKH     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.packh   , SelImm.X    , xWen = T, canRobCompress = T),
331    PACKW     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.packw   , SelImm.X    , xWen = T, canRobCompress = T),
332    BREV8     -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.revb    , SelImm.X    , xWen = T, canRobCompress = T),
333    // If configured to RV32, we should add zip and unzip.
334
335    // Zbkc
336    // clmul, clmulh is in Zbc
337
338    // Zbkx
339    XPERM4    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.xpermn  , SelImm.X    , xWen = T, canRobCompress = T),
340    XPERM8    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.xpermb  , SelImm.X    , xWen = T, canRobCompress = T),
341  )
342}
343
344object ScalarCryptoDecode extends DecodeConstants {
345  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
346    // Zknd: NIST Suite: AES Decryption
347    AES64DS    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64ds   , SelImm.X    , xWen = T, canRobCompress = T),
348    AES64DSM   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64dsm  , SelImm.X    , xWen = T, canRobCompress = T),
349    AES64IM    -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.aes64im   , SelImm.X    , xWen = T, canRobCompress = T),
350    AES64KS1I  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.bku, BKUOpType.aes64ks1i , SelImm.IMM_I, xWen = T, canRobCompress = T),
351    AES64KS2   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64ks2  , SelImm.X    , xWen = T, canRobCompress = T),
352
353    // Zkne: NIST Suite: AES Encryption
354    // aes64ks1i, aes64ks2 is in Zknd
355    AES64ES    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64es   , SelImm.X    , xWen = T, canRobCompress = T),
356    AES64ESM   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64esm  , SelImm.X    , xWen = T, canRobCompress = T),
357
358    // Zknh: NIST Suite: Hash Function Instructions
359    SHA256SIG0 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha256sig0, SelImm.X    , xWen = T, canRobCompress = T),
360    SHA256SIG1 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha256sig1, SelImm.X    , xWen = T, canRobCompress = T),
361    SHA256SUM0 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha256sum0, SelImm.X    , xWen = T, canRobCompress = T),
362    SHA256SUM1 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha256sum1, SelImm.X    , xWen = T, canRobCompress = T),
363    SHA512SIG0 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha512sig0, SelImm.X    , xWen = T, canRobCompress = T),
364    SHA512SIG1 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha512sig1, SelImm.X    , xWen = T, canRobCompress = T),
365    SHA512SUM0 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha512sum0, SelImm.X    , xWen = T, canRobCompress = T),
366    SHA512SUM1 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha512sum1, SelImm.X    , xWen = T, canRobCompress = T),
367
368    // Zksed: ShangMi Suite: SM4 Block Cipher Instructions
369    SM4ED0     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ed0    , SelImm.X    , xWen = T, canRobCompress = T),
370    SM4ED1     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ed1    , SelImm.X    , xWen = T, canRobCompress = T),
371    SM4ED2     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ed2    , SelImm.X    , xWen = T, canRobCompress = T),
372    SM4ED3     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ed3    , SelImm.X    , xWen = T, canRobCompress = T),
373    SM4KS0     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ks0    , SelImm.X    , xWen = T, canRobCompress = T),
374    SM4KS1     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ks1    , SelImm.X    , xWen = T, canRobCompress = T),
375    SM4KS2     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ks2    , SelImm.X    , xWen = T, canRobCompress = T),
376    SM4KS3     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ks3    , SelImm.X    , xWen = T, canRobCompress = T),
377
378    // Zksh: ShangMi Suite: SM3 Hash Function Instructions
379    SM3P0      -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sm3p0     , SelImm.X    , xWen = T, canRobCompress = T),
380    SM3P1      -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sm3p1     , SelImm.X    , xWen = T, canRobCompress = T),
381  )
382}
383
384/**
385 * FP Decode constants
386 */
387object FpDecode extends DecodeConstants{
388  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
389    FLH     -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lh, selImm = SelImm.IMM_I, fWen = T),
390    FLW     -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lw, selImm = SelImm.IMM_I, fWen = T),
391    FLD     -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.ld, selImm = SelImm.IMM_I, fWen = T),
392    FSH     -> FDecode(SrcType.reg, SrcType.fp,  SrcType.X, FuType.stu, LSUOpType.sh, selImm = SelImm.IMM_S          ),
393    FSW     -> FDecode(SrcType.reg, SrcType.fp,  SrcType.X, FuType.stu, LSUOpType.sw, selImm = SelImm.IMM_S          ),
394    FSD     -> FDecode(SrcType.reg, SrcType.fp,  SrcType.X, FuType.stu, LSUOpType.sd, selImm = SelImm.IMM_S          ),
395
396    FMV_D_X -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2v, IF2VectorType.FMX_D_X, fWen = T, canRobCompress = T),
397    FMV_W_X -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2v, IF2VectorType.FMX_W_X, fWen = T, canRobCompress = T),
398    FMV_H_X -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2v, IF2VectorType.FMX_H_X, fWen = T, canRobCompress = T),
399
400    // Int to FP
401    FCVT_S_W  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
402    FCVT_S_WU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
403    FCVT_S_L  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
404    FCVT_S_LU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
405
406    FCVT_D_W  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
407    FCVT_D_WU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
408    FCVT_D_L  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
409    FCVT_D_LU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
410
411    FCVT_H_W  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
412    FCVT_H_WU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
413    FCVT_H_L  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
414    FCVT_H_LU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
415  )
416}
417
418/**
419 * FP Divide SquareRoot Constants
420 */
421object FDivSqrtDecode extends DecodeConstants {
422  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
423    FDIV_S  -> FDecode(SrcType.fp,  SrcType.fp,  SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
424    FDIV_D  -> FDecode(SrcType.fp,  SrcType.fp,  SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
425    FSQRT_S -> FDecode(SrcType.fp,  SrcType.imm, SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
426    FSQRT_D -> FDecode(SrcType.fp,  SrcType.imm, SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
427  )
428}
429
430/**
431 * Svinval extension Constants
432 */
433object SvinvalDecode extends DecodeConstants {
434  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
435    /* sinval_vma is like sfence.vma , but sinval_vma can be dispatched and issued like normal instructions while sfence.vma
436     * must assure it is the ONLY instrucion executing in backend.
437     * Since software cannot promiss all sinval.vma between sfence.w.inval and sfence.inval.ir, we make sinval.vma wait
438     * forward.
439     */
440    SINVAL_VMA        -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.sfence, SelImm.X, noSpec = T, blockBack = T),
441    /* sfecne.w.inval is the begin instrucion of a TLB flush which set *noSpecExec* and *blockBackward* signals
442     * so when it comes to dispatch , it will block all instruction after itself until all instrucions ahead of it in rob commit
443     * then dispatch and issue this instrucion to flush sbuffer to dcache
444     * after this instrucion commits , issue following sinval_vma instructions (out of order) to flush TLB
445     */
446    SFENCE_W_INVAL    -> XSDecode(SrcType.DC, SrcType.DC, SrcType.X, FuType.fence, FenceOpType.nofence, SelImm.X, noSpec = T, blockBack = T),
447    /* sfecne.inval.ir is the end instrucion of a TLB flush which set *noSpecExec* *blockBackward* and *flushPipe* signals
448     * so when it comes to dispatch , it will wait until all sinval_vma ahead of it in rob commit
449     * then dispatch and issue this instrucion
450     * when it commit at the head of rob , flush the pipeline since some instrucions have been fetched to ibuffer using old TLB map
451     */
452    SFENCE_INVAL_IR   -> XSDecode(SrcType.DC, SrcType.DC, SrcType.X, FuType.fence, FenceOpType.nofence, SelImm.X, noSpec = T, blockBack = T, flushPipe = T)
453    /* what is Svinval extension ?
454     *                       ----->             sfecne.w.inval
455     * sfence.vma   vpn1     ----->             sinval_vma   vpn1
456     * sfence.vma   vpn2     ----->             sinval_vma   vpn2
457     *                       ----->             sfecne.inval.ir
458     *
459     * sfence.vma should be executed in-order and it flushes the pipeline after committing
460     * we can parallel sfence instrucions with this extension
461     */
462  )
463}
464
465/*
466 * CBO decode
467 */
468object CBODecode extends DecodeConstants {
469  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
470    CBO_ZERO  -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_zero , SelImm.IMM_S),
471    CBO_CLEAN -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_clean, SelImm.IMM_S),
472    CBO_FLUSH -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_flush, SelImm.IMM_S),
473    CBO_INVAL -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_inval, SelImm.IMM_S)
474  )
475}
476
477/*
478 * Hypervisor decode
479 */
480object HypervisorDecode extends DecodeConstants {
481  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
482    HFENCE_GVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_g, SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
483    HFENCE_VVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_v, SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
484
485    /**
486     * Since software cannot promiss all sinval.vma between sfence.w.inval and sfence.inval.ir, we make sinval.vma wait
487     * forward.
488     */
489    HINVAL_GVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_g, SelImm.X, noSpec = T, blockBack = T),
490    HINVAL_VVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_v, SelImm.X, noSpec = T, blockBack = T),
491    HLV_B       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvb,       SelImm.X, xWen = T),
492    HLV_BU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvbu,      SelImm.X, xWen = T),
493    HLV_D       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvd,       SelImm.X, xWen = T),
494    HLV_H       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvh,       SelImm.X, xWen = T),
495    HLV_HU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvhu,      SelImm.X, xWen = T),
496    HLV_W       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvw,       SelImm.X, xWen = T),
497    HLV_WU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvwu,      SelImm.X, xWen = T),
498    HLVX_HU     -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvxhu,     SelImm.X, xWen = T),
499    HLVX_WU     -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvxwu,     SelImm.X, xWen = T),
500    HSV_B       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvb,       SelImm.X),
501    HSV_D       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvd,       SelImm.X),
502    HSV_H       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvh,       SelImm.X),
503    HSV_W       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvw,       SelImm.X),
504  )
505}
506
507object ZicondDecode extends DecodeConstants {
508  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
509    CZERO_EQZ   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.czero_eqz, SelImm.X, xWen = T, canRobCompress = T),
510    CZERO_NEZ   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.czero_nez, SelImm.X, xWen = T, canRobCompress = T),
511  )
512}
513
514/**
515  * "Zimop" Extension for May-Be-Operations
516  */
517object ZimopDecode extends DecodeConstants {
518  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
519    // temp use addi to decode MOP_R and MOP_RR
520    MOP_R  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.add, SelImm.IMM_I, xWen = T, canRobCompress = T),
521    MOP_RR -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.add, SelImm.IMM_I, xWen = T, canRobCompress = T),
522  )
523}
524
525object ZfaDecode extends DecodeConstants {
526  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
527    FLI_H       -> FDecode(SrcType.no, SrcType.X, SrcType.X, FuType.f2v, FuOpType.X, fWen = T, canRobCompress = T),
528    FLI_S       -> FDecode(SrcType.no, SrcType.X, SrcType.X, FuType.f2v, FuOpType.X, fWen = T, canRobCompress = T),
529    FLI_D       -> FDecode(SrcType.no, SrcType.X, SrcType.X, FuType.f2v, FuOpType.X, fWen = T, canRobCompress = T),
530    FMINM_H     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fminm, fWen = T, canRobCompress = T),
531    FMINM_S     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fminm, fWen = T, canRobCompress = T),
532    FMINM_D     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fminm, fWen = T, canRobCompress = T),
533    FMAXM_H     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fmaxm, fWen = T, canRobCompress = T),
534    FMAXM_S     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fmaxm, fWen = T, canRobCompress = T),
535    FMAXM_D     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fmaxm, fWen = T, canRobCompress = T),
536    FROUND_H    -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.fround,   fWen = T, canRobCompress = T),
537    FROUND_S    -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.fround,   fWen = T, canRobCompress = T),
538    FROUND_D    -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.fround,   fWen = T, canRobCompress = T),
539    FROUNDNX_H  -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.froundnx, fWen = T, canRobCompress = T),
540    FROUNDNX_S  -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.froundnx, fWen = T, canRobCompress = T),
541    FROUNDNX_D  -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.froundnx, fWen = T, canRobCompress = T),
542    FCVTMOD_W_D -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.fcvtmod_w_d, xWen = T, canRobCompress = T),
543    FLEQ_H      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fleq, xWen = T, canRobCompress = T),
544    FLEQ_S      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fleq, xWen = T, canRobCompress = T),
545    FLEQ_D      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fleq, xWen = T, canRobCompress = T),
546    FLTQ_H      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fltq, xWen = T, canRobCompress = T),
547    FLTQ_S      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fltq, xWen = T, canRobCompress = T),
548    FLTQ_D      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fltq, xWen = T, canRobCompress = T),
549  )
550}
551
552/**
553 * XiangShan Trap Decode constants
554 */
555object XSTrapDecode extends DecodeConstants {
556  def TRAP = BitPat("b000000000000?????000000001101011")
557  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
558    TRAP    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.add, SelImm.IMM_I, xWen = T, xsTrap = T, noSpec = T, blockBack = T)
559  )
560}
561
562abstract class Imm(val len: Int) {
563  def toImm32(minBits: UInt): UInt = do_toImm32(minBits(len - 1, 0))
564  def do_toImm32(minBits: UInt): UInt
565  def minBitsFromInstr(instr: UInt): UInt
566}
567
568case class Imm_I() extends Imm(12) {
569  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits(len - 1, 0), 32)
570
571  override def minBitsFromInstr(instr: UInt): UInt =
572    Cat(instr(31, 20))
573}
574
575case class Imm_S() extends Imm(12) {
576  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
577
578  override def minBitsFromInstr(instr: UInt): UInt =
579    Cat(instr(31, 25), instr(11, 7))
580}
581
582case class Imm_B() extends Imm(12) {
583  override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
584
585  override def minBitsFromInstr(instr: UInt): UInt =
586    Cat(instr(31), instr(7), instr(30, 25), instr(11, 8))
587}
588
589case class Imm_U() extends Imm(20){
590  override def do_toImm32(minBits: UInt): UInt = Cat(minBits(len - 1, 0), 0.U(12.W))
591
592  override def minBitsFromInstr(instr: UInt): UInt = {
593    instr(31, 12)
594  }
595}
596
597case class Imm_J() extends Imm(20){
598  override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
599
600  override def minBitsFromInstr(instr: UInt): UInt = {
601    Cat(instr(31), instr(19, 12), instr(20), instr(30, 25), instr(24, 21))
602  }
603}
604
605case class Imm_Z() extends Imm(12 + 5 + 5){
606  override def do_toImm32(minBits: UInt): UInt = minBits
607
608  override def minBitsFromInstr(instr: UInt): UInt = {
609    Cat(instr(11, 7), instr(19, 15), instr(31, 20))
610  }
611
612  def getCSRAddr(imm: UInt): UInt = {
613    require(imm.getWidth == this.len)
614    imm(11, 0)
615  }
616
617  def getRS1(imm: UInt): UInt = {
618    require(imm.getWidth == this.len)
619    imm(16, 12)
620  }
621
622  def getRD(imm: UInt): UInt = {
623    require(imm.getWidth == this.len)
624    imm(21, 17)
625  }
626
627  def getImm5(imm: UInt): UInt = {
628    require(imm.getWidth == this.len)
629    imm(16, 12)
630  }
631}
632
633case class Imm_B6() extends Imm(6){
634  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
635
636  override def minBitsFromInstr(instr: UInt): UInt = {
637    instr(25, 20)
638  }
639}
640
641case class Imm_OPIVIS() extends Imm(5){
642  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
643
644  override def minBitsFromInstr(instr: UInt): UInt = {
645    instr(19, 15)
646  }
647}
648
649case class Imm_OPIVIU() extends Imm(5){
650  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
651
652  override def minBitsFromInstr(instr: UInt): UInt = {
653    instr(19, 15)
654  }
655}
656
657case class Imm_VSETVLI() extends Imm(11){
658  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
659
660  override def minBitsFromInstr(instr: UInt): UInt = {
661    instr(30, 20)
662  }
663  /**
664    * get VType from extended imm
665    * @param extedImm
666    * @return VType
667    */
668  def getVType(extedImm: UInt): InstVType = {
669    val vtype = Wire(new InstVType)
670    vtype := extedImm(10, 0).asTypeOf(new InstVType)
671    vtype
672  }
673}
674
675case class Imm_VSETIVLI() extends Imm(15){
676  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
677
678  override def minBitsFromInstr(instr: UInt): UInt = {
679    val rvInst: XSInstBitFields = instr.asTypeOf(new XSInstBitFields)
680    val uimm5 = rvInst.UIMM_VSETIVLI
681    val vtype8 = rvInst.ZIMM_VSETIVLI
682    Cat(uimm5, vtype8)
683  }
684  /**
685    * get VType from extended imm
686    * @param extedImm
687    * @return VType
688    */
689  def getVType(extedImm: UInt): InstVType = {
690    val vtype = Wire(new InstVType)
691    vtype := extedImm(9, 0).asTypeOf(new InstVType)
692    vtype
693  }
694
695  def getAvl(extedImm: UInt): UInt = {
696    extedImm(14, 10)
697  }
698}
699
700case class Imm_LUI32() extends Imm(32){
701  override def do_toImm32(minBits: UInt): UInt = minBits(31, 0)
702
703  override def minBitsFromInstr(instr: UInt): UInt = {
704    instr(31, 0)
705  }
706}
707
708case class Imm_VRORVI() extends Imm(6){
709  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
710
711  override def minBitsFromInstr(instr: UInt): UInt = {
712    Cat(instr(26), instr(19, 15))
713  }
714}
715
716object ImmUnion {
717  val I = Imm_I()
718  val S = Imm_S()
719  val B = Imm_B()
720  val U = Imm_U()
721  val J = Imm_J()
722  val Z = Imm_Z()
723  val B6 = Imm_B6()
724  val OPIVIS = Imm_OPIVIS()
725  val OPIVIU = Imm_OPIVIU()
726  val VSETVLI = Imm_VSETVLI()
727  val VSETIVLI = Imm_VSETIVLI()
728  val LUI32 = Imm_LUI32()
729  val VRORVI = Imm_VRORVI()
730
731  // do not add special type lui32 to this, keep ImmUnion max len being 20.
732  val imms = Seq(I, S, B, U, J, Z, B6, OPIVIS, OPIVIU, VSETVLI, VSETIVLI, VRORVI)
733  val maxLen = imms.maxBy(_.len).len
734  val immSelMap = Seq(
735    SelImm.IMM_I,
736    SelImm.IMM_S,
737    SelImm.IMM_SB,
738    SelImm.IMM_U,
739    SelImm.IMM_UJ,
740    SelImm.IMM_Z,
741    SelImm.IMM_B6,
742    SelImm.IMM_OPIVIS,
743    SelImm.IMM_OPIVIU,
744    SelImm.IMM_VSETVLI,
745    SelImm.IMM_VSETIVLI,
746    SelImm.IMM_VRORVI,
747  ).zip(imms)
748  println(s"ImmUnion max len: $maxLen")
749}
750
751case class Imm_LUI_LOAD() {
752  def immFromLuiLoad(lui_imm: UInt, load_imm: UInt): UInt = {
753    val loadImm = load_imm(Imm_I().len - 1, 0)
754    Cat(lui_imm(ImmUnion.maxLen - loadImm.getWidth - 1, 0), loadImm)
755  }
756  def getLuiImm(uop: DynInst): UInt = {
757    val loadImmLen = Imm_I().len
758    val imm_u = Cat(uop.psrc(1), uop.psrc(0), uop.imm(ImmUnion.maxLen - 1, loadImmLen))
759    Cat(Imm_U().toImm32(imm_u)(31, loadImmLen), uop.imm(loadImmLen - 1, 0))
760  }
761}
762
763/**
764 * IO bundle for the Decode unit
765 */
766class DecodeUnitDeqIO(implicit p: Parameters) extends XSBundle {
767  val decodedInst = Output(new DecodedInst)
768  val isComplex = Output(Bool())
769  val uopInfo = Output(new UopInfo)
770}
771class DecodeUnitIO(implicit p: Parameters) extends XSBundle {
772  val enq = new Bundle {
773    val ctrlFlow = Input(new StaticInst)
774    val vtype = Input(new VType)
775    val vstart = Input(Vl())
776  }
777//  val vconfig = Input(UInt(XLEN.W))
778  val deq = new DecodeUnitDeqIO
779  val csrCtrl = Input(new CustomCSRCtrlIO)
780  val fromCSR = Input(new CSRToDecode)
781}
782
783/**
784 * Decode unit that takes in a single CtrlFlow and generates a CfCtrl.
785 */
786class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstants {
787  val io = IO(new DecodeUnitIO)
788
789  val ctrl_flow = io.enq.ctrlFlow // input with RVC Expanded
790
791  private val inst: XSInstBitFields = io.enq.ctrlFlow.instr.asTypeOf(new XSInstBitFields)
792
793  val decode_table: Array[(BitPat, List[BitPat])] = XDecode.table ++
794    FpDecode.table ++
795//    FDivSqrtDecode.table ++
796    BitmanipDecode.table ++
797    ScalarCryptoDecode.table ++
798    XSTrapDecode.table ++
799    CBODecode.table ++
800    SvinvalDecode.table ++
801    HypervisorDecode.table ++
802    VecDecoder.table ++
803    ZicondDecode.table ++
804    ZimopDecode.table ++
805    ZfaDecode.table
806
807  require(decode_table.map(_._2.length == 15).reduce(_ && _), "Decode tables have different column size")
808  // assertion for LUI: only LUI should be assigned `selImm === SelImm.IMM_U && fuType === FuType.alu`
809  val luiMatch = (t: Seq[BitPat]) => t(3).value == FuType.alu.ohid && t.reverse.head.value == SelImm.IMM_U.litValue
810  val luiTable = decode_table.filter(t => luiMatch(t._2)).map(_._1).distinct
811  assert(luiTable.length == 1 && luiTable.head == LUI, "Conflicts: LUI is determined by FuType and SelImm in Dispatch")
812
813  // output
814  val decodedInst: DecodedInst = Wire(new DecodedInst()).decode(ctrl_flow.instr, decode_table)
815
816  val fpDecoder = Module(new FPDecoder)
817  fpDecoder.io.instr := ctrl_flow.instr
818  decodedInst.fpu := fpDecoder.io.fpCtrl
819  decodedInst.fpu.wflags := fpDecoder.io.fpCtrl.wflags || decodedInst.wfflags
820
821  decodedInst.connectStaticInst(io.enq.ctrlFlow)
822
823  decodedInst.uopIdx := 0.U
824  decodedInst.firstUop := true.B
825  decodedInst.lastUop := true.B
826  decodedInst.numUops := 1.U
827  decodedInst.numWB   := 1.U
828
829  val isZimop = (BitPat("b1?00??0111??_?????_100_?????_1110011") === ctrl_flow.instr) ||
830                (BitPat("b1?00??1?????_?????_100_?????_1110011") === ctrl_flow.instr)
831
832  val isMove = BitPat("b000000000000_?????_000_?????_0010011") === ctrl_flow.instr
833  // temp decode zimop as move
834  decodedInst.isMove := (isMove || isZimop) && ctrl_flow.instr(RD_MSB, RD_LSB) =/= 0.U && !io.csrCtrl.singlestep
835
836  // fmadd - b1000011
837  // fmsub - b1000111
838  // fnmsub- b1001011
839  // fnmadd- b1001111
840  private val isFMA = inst.OPCODE === BitPat("b100??11")
841  private val isVppu = FuType.isVppu(decodedInst.fuType)
842  private val isVecOPF = FuType.isVecOPF(decodedInst.fuType)
843
844  // read src1~3 location
845  decodedInst.lsrc(0) := inst.RS1
846  decodedInst.lsrc(1) := inst.RS2
847  // src(2) of fma is fs3, src(2) of vector inst is old vd
848  decodedInst.lsrc(2) := Mux(isFMA, inst.FS3, inst.VD)
849  decodedInst.lsrc(3) := V0_IDX.U
850  decodedInst.lsrc(4) := Vl_IDX.U
851
852  // read dest location
853  decodedInst.ldest := inst.RD
854
855  // init v0Wen vlWen
856  decodedInst.v0Wen := false.B
857  decodedInst.vlWen := false.B
858
859  // fill in exception vector
860  val vecException = Module(new VecExceptionGen)
861  vecException.io.inst := io.enq.ctrlFlow.instr
862  vecException.io.decodedInst := decodedInst
863  vecException.io.vtype := decodedInst.vpu.vtype
864  vecException.io.vstart := decodedInst.vpu.vstart
865
866  private val isCboClean = CBO_CLEAN === io.enq.ctrlFlow.instr
867  private val isCboFlush = CBO_FLUSH === io.enq.ctrlFlow.instr
868  private val isCboInval = CBO_INVAL === io.enq.ctrlFlow.instr
869  private val isCboZero  = CBO_ZERO  === io.enq.ctrlFlow.instr
870
871  // Note that rnum of aes64ks1i must be in the range 0x0..0xA. The values 0xB..0xF are reserved.
872  private val isAes64ks1iIllegal =
873    FuType.FuTypeOrR(decodedInst.fuType, FuType.bku) && (decodedInst.fuOpType === BKUOpType.aes64ks1i) && inst.isRnumIllegal
874
875  private val exceptionII =
876    decodedInst.selImm === SelImm.INVALID_INSTR ||
877    vecException.io.illegalInst ||
878    io.fromCSR.illegalInst.sfenceVMA  && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.sfence  ||
879    io.fromCSR.illegalInst.sfencePart && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.nofence ||
880    io.fromCSR.illegalInst.hfenceGVMA && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.hfence_g ||
881    io.fromCSR.illegalInst.hfenceVVMA && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.hfence_v ||
882    io.fromCSR.illegalInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu)   && (LSUOpType.isHlv(decodedInst.fuOpType) || LSUOpType.isHlvx(decodedInst.fuOpType)) ||
883    io.fromCSR.illegalInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.stu)   && LSUOpType.isHsv(decodedInst.fuOpType) ||
884    io.fromCSR.illegalInst.fsIsOff    && (
885      FuType.FuTypeOrR(decodedInst.fuType, FuType.fpOP ++ Seq(FuType.f2v)) ||
886      (FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu) && (decodedInst.fuOpType === LSUOpType.lh || decodedInst.fuOpType === LSUOpType.lw || decodedInst.fuOpType === LSUOpType.ld) ||
887      FuType.FuTypeOrR(decodedInst.fuType, FuType.stu) && (decodedInst.fuOpType === LSUOpType.sh || decodedInst.fuOpType === LSUOpType.sw || decodedInst.fuOpType === LSUOpType.sd)) && decodedInst.instr(2) ||
888      inst.isOPFVF || inst.isOPFVV
889    ) ||
890    io.fromCSR.illegalInst.vsIsOff    && FuType.FuTypeOrR(decodedInst.fuType, FuType.vecAll) ||
891    io.fromCSR.illegalInst.wfi        && FuType.FuTypeOrR(decodedInst.fuType, FuType.csr)   && CSROpType.isWfi(decodedInst.fuOpType) ||
892    (decodedInst.needFrm.scalaNeedFrm || FuType.isScalaNeedFrm(decodedInst.fuType)) && (((decodedInst.fpu.rm === 5.U) || (decodedInst.fpu.rm === 6.U)) || ((decodedInst.fpu.rm === 7.U) && io.fromCSR.illegalInst.frm)) ||
893    (decodedInst.needFrm.vectorNeedFrm || FuType.isVectorNeedFrm(decodedInst.fuType)) && io.fromCSR.illegalInst.frm ||
894    io.fromCSR.illegalInst.cboZ       && isCboZero ||
895    io.fromCSR.illegalInst.cboCF      && (isCboClean || isCboFlush) ||
896    io.fromCSR.illegalInst.cboI       && isCboInval ||
897    isAes64ks1iIllegal
898
899  private val exceptionVI =
900    io.fromCSR.virtualInst.sfenceVMA  && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.sfence ||
901    io.fromCSR.virtualInst.sfencePart && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.nofence ||
902    io.fromCSR.virtualInst.hfence     && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && (decodedInst.fuOpType === FenceOpType.hfence_g || decodedInst.fuOpType === FenceOpType.hfence_v) ||
903    io.fromCSR.virtualInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu)   && (LSUOpType.isHlv(decodedInst.fuOpType) || LSUOpType.isHlvx(decodedInst.fuOpType)) ||
904    io.fromCSR.virtualInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.stu)   && LSUOpType.isHsv(decodedInst.fuOpType) ||
905    io.fromCSR.virtualInst.wfi        && FuType.FuTypeOrR(decodedInst.fuType, FuType.csr)   && CSROpType.isWfi(decodedInst.fuOpType) ||
906    io.fromCSR.virtualInst.cboZ       && isCboZero ||
907    io.fromCSR.virtualInst.cboCF      && (isCboClean || isCboFlush) ||
908    io.fromCSR.virtualInst.cboI       && isCboInval
909
910
911  decodedInst.exceptionVec(illegalInstr) := exceptionII || io.enq.ctrlFlow.exceptionVec(EX_II)
912  decodedInst.exceptionVec(virtualInstr) := exceptionVI
913
914  //update exceptionVec: from frontend trigger's breakpoint exception. To reduce 1 bit of overhead in ibuffer entry.
915  decodedInst.exceptionVec(breakPoint) := TriggerAction.isExp(ctrl_flow.trigger)
916
917  decodedInst.imm := LookupTree(decodedInst.selImm, ImmUnion.immSelMap.map(
918    x => {
919      val minBits = x._2.minBitsFromInstr(ctrl_flow.instr)
920      require(minBits.getWidth == x._2.len)
921      x._1 -> minBits
922    }
923  ))
924
925  private val isLs = FuType.isLoadStore(decodedInst.fuType)
926  private val isVls = FuType.isVls(decodedInst.fuType)
927  private val isStore = FuType.isStore(decodedInst.fuType)
928  private val isAMO = FuType.isAMO(decodedInst.fuType)
929  private val isVStore = FuType.isVStore(decodedInst.fuType)
930  private val isBranch = !decodedInst.preDecodeInfo.notCFI || FuType.isJump(decodedInst.fuType)
931
932  decodedInst.commitType := Cat(isLs | isVls, (isStore && !isAMO) | isVStore | isBranch)
933
934  decodedInst.isVset := FuType.isVset(decodedInst.fuType)
935
936  private val needReverseInsts = Seq(VRSUB_VI, VRSUB_VX, VFRDIV_VF, VFRSUB_VF, VFMV_F_S)
937  private val vextInsts = Seq(VZEXT_VF2, VZEXT_VF4, VZEXT_VF8, VSEXT_VF2, VSEXT_VF4, VSEXT_VF8)
938  private val narrowInsts = Seq(
939    VNSRA_WV, VNSRA_WX, VNSRA_WI, VNSRL_WV, VNSRL_WX, VNSRL_WI,
940    VNCLIP_WV, VNCLIP_WX, VNCLIP_WI, VNCLIPU_WV, VNCLIPU_WX, VNCLIPU_WI,
941  )
942  private val maskDstInsts = Seq(
943    VMADC_VV, VMADC_VX,  VMADC_VI,  VMADC_VVM, VMADC_VXM, VMADC_VIM,
944    VMSBC_VV, VMSBC_VX,  VMSBC_VVM, VMSBC_VXM,
945    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
946    VMSEQ_VV, VMSEQ_VX, VMSEQ_VI, VMSNE_VV, VMSNE_VX, VMSNE_VI,
947    VMSLE_VV, VMSLE_VX, VMSLE_VI, VMSLEU_VV, VMSLEU_VX, VMSLEU_VI,
948    VMSLT_VV, VMSLT_VX, VMSLTU_VV, VMSLTU_VX,
949    VMSGT_VX, VMSGT_VI, VMSGTU_VX, VMSGTU_VI,
950    VMFEQ_VV, VMFEQ_VF, VMFNE_VV, VMFNE_VF, VMFLT_VV, VMFLT_VF, VMFLE_VV, VMFLE_VF, VMFGT_VF, VMFGE_VF,
951  )
952  private val maskOpInsts = Seq(
953    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
954  )
955  private val vmaInsts = Seq(
956    VMACC_VV, VMACC_VX, VNMSAC_VV, VNMSAC_VX, VMADD_VV, VMADD_VX, VNMSUB_VV, VNMSUB_VX,
957    VWMACCU_VV, VWMACCU_VX, VWMACC_VV, VWMACC_VX, VWMACCSU_VV, VWMACCSU_VX, VWMACCUS_VX,
958  )
959  private val wfflagsInsts = Seq(
960    // opfff
961    FADD_S, FSUB_S, FADD_D, FSUB_D, FADD_H, FSUB_H,
962    FEQ_S, FLT_S, FLE_S, FEQ_D, FLT_D, FLE_D, FEQ_H, FLT_H, FLE_H,
963    FMIN_S, FMAX_S, FMIN_D, FMAX_D, FMIN_H, FMAX_H,
964    FMUL_S, FMUL_D, FMUL_H,
965    FDIV_S, FDIV_D, FSQRT_S, FSQRT_D, FDIV_H, FSQRT_H,
966    FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D, FMADD_H, FMSUB_H, FNMADD_H, FNMSUB_H,
967    FSGNJ_S, FSGNJN_S, FSGNJX_S, FSGNJ_H, FSGNJN_H, FSGNJX_H,
968    // opfvv
969    VFADD_VV, VFSUB_VV, VFWADD_VV, VFWSUB_VV, VFWADD_WV, VFWSUB_WV,
970    VFMUL_VV, VFDIV_VV, VFWMUL_VV,
971    VFMACC_VV, VFNMACC_VV, VFMSAC_VV, VFNMSAC_VV, VFMADD_VV, VFNMADD_VV, VFMSUB_VV, VFNMSUB_VV,
972    VFWMACC_VV, VFWNMACC_VV, VFWMSAC_VV, VFWNMSAC_VV,
973    VFSQRT_V,
974    VFMIN_VV, VFMAX_VV,
975    VMFEQ_VV, VMFNE_VV, VMFLT_VV, VMFLE_VV,
976    VFSGNJ_VV, VFSGNJN_VV, VFSGNJX_VV,
977    // opfvf
978    VFADD_VF, VFSUB_VF, VFRSUB_VF, VFWADD_VF, VFWSUB_VF, VFWADD_WF, VFWSUB_WF,
979    VFMUL_VF, VFDIV_VF, VFRDIV_VF, VFWMUL_VF,
980    VFMACC_VF, VFNMACC_VF, VFMSAC_VF, VFNMSAC_VF, VFMADD_VF, VFNMADD_VF, VFMSUB_VF, VFNMSUB_VF,
981    VFWMACC_VF, VFWNMACC_VF, VFWMSAC_VF, VFWNMSAC_VF,
982    VFMIN_VF, VFMAX_VF,
983    VMFEQ_VF, VMFNE_VF, VMFLT_VF, VMFLE_VF, VMFGT_VF, VMFGE_VF,
984    VFSGNJ_VF, VFSGNJN_VF, VFSGNJX_VF,
985    // vfred
986    VFREDOSUM_VS, VFREDUSUM_VS, VFREDMAX_VS, VFREDMIN_VS, VFWREDOSUM_VS, VFWREDUSUM_VS,
987    // fcvt & vfcvt
988    FCVT_S_W, FCVT_S_WU, FCVT_S_L, FCVT_S_LU,
989    FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S,
990    FCVT_D_W, FCVT_D_WU, FCVT_D_L, FCVT_D_LU,
991    FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S,
992    FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H,
993    FCVT_H_W, FCVT_H_WU, FCVT_H_L, FCVT_H_LU,
994    FCVT_W_H, FCVT_WU_H, FCVT_L_H, FCVT_LU_H,
995    VFCVT_XU_F_V, VFCVT_X_F_V, VFCVT_RTZ_XU_F_V, VFCVT_RTZ_X_F_V, VFCVT_F_XU_V, VFCVT_F_X_V,
996    VFWCVT_XU_F_V, VFWCVT_X_F_V, VFWCVT_RTZ_XU_F_V, VFWCVT_RTZ_X_F_V, VFWCVT_F_XU_V, VFWCVT_F_X_V, VFWCVT_F_F_V,
997    VFNCVT_XU_F_W, VFNCVT_X_F_W, VFNCVT_RTZ_XU_F_W, VFNCVT_RTZ_X_F_W, VFNCVT_F_XU_W, VFNCVT_F_X_W, VFNCVT_F_F_W,
998    VFNCVT_ROD_F_F_W, VFRSQRT7_V, VFREC7_V,
999    // zfa
1000    FLEQ_H, FLEQ_S, FLEQ_D, FLTQ_H, FLTQ_S, FLTQ_D,
1001    FMINM_H, FMINM_S, FMINM_D, FMAXM_H, FMAXM_S, FMAXM_D,
1002    FROUND_H, FROUND_S, FROUND_D, FROUNDNX_H, FROUNDNX_S, FROUNDNX_D,
1003    FCVTMOD_W_D,
1004  )
1005
1006  private val scalaNeedFrmInsts = Seq(
1007    FADD_S, FSUB_S, FADD_D, FSUB_D, FADD_H, FSUB_H,
1008    FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S,
1009    FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S,
1010    FCVT_W_H, FCVT_WU_H, FCVT_L_H, FCVT_LU_H,
1011    FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H,
1012    FROUND_H, FROUND_S, FROUND_D, FROUNDNX_H, FROUNDNX_S, FROUNDNX_D,
1013  )
1014
1015  private val vectorNeedFrmInsts = Seq (
1016    VFSLIDE1UP_VF, VFSLIDE1DOWN_VF,
1017  )
1018
1019  decodedInst.wfflags := wfflagsInsts.map(_ === inst.ALL).reduce(_ || _)
1020  decodedInst.needFrm.scalaNeedFrm := scalaNeedFrmInsts.map(_ === inst.ALL).reduce(_ || _)
1021  decodedInst.needFrm.vectorNeedFrm := vectorNeedFrmInsts.map(_ === inst.ALL).reduce(_ || _)
1022  val fpToVecDecoder = Module(new FPToVecDecoder())
1023  fpToVecDecoder.io.instr := inst.asUInt
1024  val isFpToVecInst = fpToVecDecoder.io.vpuCtrl.fpu.isFpToVecInst
1025  decodedInst.vpu := 0.U.asTypeOf(decodedInst.vpu) // Todo: Connect vpu decoder
1026  when(isFpToVecInst){
1027    decodedInst.vpu := fpToVecDecoder.io.vpuCtrl
1028  }.otherwise{
1029    decodedInst.vpu.vill := io.enq.vtype.illegal
1030    decodedInst.vpu.vma := io.enq.vtype.vma
1031    decodedInst.vpu.vta := io.enq.vtype.vta
1032    decodedInst.vpu.vsew := io.enq.vtype.vsew
1033    decodedInst.vpu.vlmul := io.enq.vtype.vlmul
1034    decodedInst.vpu.vm := inst.VM
1035    decodedInst.vpu.nf := inst.NF
1036    decodedInst.vpu.veew := inst.WIDTH
1037    decodedInst.vpu.isReverse := needReverseInsts.map(_ === inst.ALL).reduce(_ || _)
1038    decodedInst.vpu.isExt := vextInsts.map(_ === inst.ALL).reduce(_ || _)
1039    val isNarrow = narrowInsts.map(_ === inst.ALL).reduce(_ || _)
1040    val isDstMask = maskDstInsts.map(_ === inst.ALL).reduce(_ || _)
1041    val isOpMask = maskOpInsts.map(_ === inst.ALL).reduce(_ || _)
1042    val isVlx = decodedInst.fuOpType === VlduType.vloxe || decodedInst.fuOpType === VlduType.vluxe
1043    val isVle = decodedInst.fuOpType === VlduType.vle || decodedInst.fuOpType === VlduType.vleff || decodedInst.fuOpType === VlduType.vlse
1044    val isVlm = decodedInst.fuOpType === VlduType.vlm
1045    val isWritePartVd = decodedInst.uopSplitType === UopSplitType.VEC_VRED || decodedInst.uopSplitType === UopSplitType.VEC_0XV || decodedInst.uopSplitType === UopSplitType.VEC_VWW
1046    val isVma = vmaInsts.map(_ === inst.ALL).reduce(_ || _)
1047    val emulIsFrac = Cat(~decodedInst.vpu.vlmul(2), decodedInst.vpu.vlmul(1, 0)) +& decodedInst.vpu.veew < 4.U +& decodedInst.vpu.vsew
1048    decodedInst.vpu.isNarrow := isNarrow
1049    decodedInst.vpu.isDstMask := isDstMask
1050    decodedInst.vpu.isOpMask := isOpMask
1051    decodedInst.vpu.isDependOldVd := isVppu || isVecOPF || isVStore || (isDstMask && !isOpMask) || isNarrow || isVlx || isVma
1052    decodedInst.vpu.isWritePartVd := isWritePartVd || isVlm || isVle && emulIsFrac
1053    decodedInst.vpu.vstart := io.enq.vstart
1054    decodedInst.vpu.isVleff := decodedInst.fuOpType === VlduType.vleff && inst.NF === 0.U
1055  }
1056  decodedInst.vpu.specVill := io.enq.vtype.illegal
1057  decodedInst.vpu.specVma := io.enq.vtype.vma
1058  decodedInst.vpu.specVta := io.enq.vtype.vta
1059  decodedInst.vpu.specVsew := io.enq.vtype.vsew
1060  decodedInst.vpu.specVlmul := io.enq.vtype.vlmul
1061
1062  decodedInst.vlsInstr := isVls
1063
1064  decodedInst.srcType(3) := Mux(inst.VM === 0.U && !isFpToVecInst, SrcType.vp, SrcType.DC) // mask src
1065  decodedInst.srcType(4) := Mux(!isFpToVecInst, SrcType.vp, SrcType.DC) // vconfig
1066
1067  val uopInfoGen = Module(new UopInfoGen)
1068  uopInfoGen.io.in.preInfo.typeOfSplit := decodedInst.uopSplitType
1069  uopInfoGen.io.in.preInfo.vsew := decodedInst.vpu.vsew
1070  uopInfoGen.io.in.preInfo.vlmul := decodedInst.vpu.vlmul
1071  uopInfoGen.io.in.preInfo.vwidth := inst.RM
1072  uopInfoGen.io.in.preInfo.vmvn := inst.IMM5_OPIVI(2, 0)
1073  uopInfoGen.io.in.preInfo.nf := inst.NF
1074  uopInfoGen.io.in.preInfo.isVlsr := decodedInst.fuOpType === VlduType.vlr || decodedInst.fuOpType === VstuType.vsr
1075  uopInfoGen.io.in.preInfo.isVlsm := decodedInst.fuOpType === VlduType.vlm || decodedInst.fuOpType === VstuType.vsm
1076  io.deq.isComplex := uopInfoGen.io.out.isComplex
1077  // numOfUop should be 1 when vector instruction is illegalInst
1078  io.deq.uopInfo.numOfUop := Mux(vecException.io.illegalInst, 1.U, uopInfoGen.io.out.uopInfo.numOfUop)
1079  io.deq.uopInfo.numOfWB := uopInfoGen.io.out.uopInfo.numOfWB
1080  io.deq.uopInfo.lmul := uopInfoGen.io.out.uopInfo.lmul
1081
1082  val isCsr = inst.OPCODE5Bit === OPCODE5Bit.SYSTEM && inst.FUNCT3(1, 0) =/= 0.U
1083  val isCsrr = isCsr && inst.FUNCT3 === BitPat("b?1?") && inst.RS1 === 0.U
1084  val isCsrw = isCsr && inst.FUNCT3 === BitPat("b?01") && inst.RD  === 0.U
1085  dontTouch(isCsrr)
1086  dontTouch(isCsrw)
1087
1088  // for csrr vl instruction, convert to vsetvl
1089  val isCsrrVlenb = isCsrr && inst.CSRIDX === CSRs.vlenb.U
1090  val isCsrrVl    = isCsrr && inst.CSRIDX === CSRs.vl.U
1091
1092  // decode for SoftPrefetch instructions (prefetch.w / prefetch.r / prefetch.i)
1093  val isSoftPrefetch = inst.OPCODE === BitPat("b0010011") && inst.FUNCT3 === BitPat("b110") && inst.RD === 0.U
1094  val isPreW = isSoftPrefetch && inst.RS2 === 3.U(5.W)
1095  val isPreR = isSoftPrefetch && inst.RS2 === 1.U(5.W)
1096  val isPreI = isSoftPrefetch && inst.RS2 === 0.U(5.W)
1097
1098  // for fli.s|fli.d instruction
1099  val isFLI = inst.FUNCT7 === BitPat("b11110??") && inst.RS2 === 1.U && inst.RM === 0.U && inst.OPCODE5Bit === OPCODE5Bit.OP_FP
1100
1101  when (isCsrrVl) {
1102    // convert to vsetvl instruction
1103    decodedInst.srcType(0) := SrcType.no
1104    decodedInst.srcType(1) := SrcType.no
1105    decodedInst.srcType(2) := SrcType.no
1106    decodedInst.srcType(3) := SrcType.no
1107    decodedInst.srcType(4) := SrcType.vp
1108    decodedInst.lsrc(4)    := Vl_IDX.U
1109    decodedInst.waitForward   := false.B
1110    decodedInst.blockBackward := false.B
1111    decodedInst.exceptionVec(illegalInstr) := io.fromCSR.illegalInst.vsIsOff
1112  }.elsewhen (isCsrrVlenb) {
1113    // convert to addi instruction
1114    decodedInst.srcType(0) := SrcType.reg
1115    decodedInst.srcType(1) := SrcType.imm
1116    decodedInst.srcType(2) := SrcType.no
1117    decodedInst.srcType(3) := SrcType.no
1118    decodedInst.srcType(4) := SrcType.no
1119    decodedInst.selImm := SelImm.IMM_I
1120    decodedInst.waitForward := false.B
1121    decodedInst.blockBackward := false.B
1122    decodedInst.canRobCompress := true.B
1123    decodedInst.exceptionVec(illegalInstr) := io.fromCSR.illegalInst.vsIsOff
1124  }.elsewhen (isPreW || isPreR || isPreI) {
1125    decodedInst.selImm := SelImm.IMM_S
1126    decodedInst.fuType := FuType.ldu.U
1127    decodedInst.canRobCompress := false.B
1128  }.elsewhen (isZimop) {
1129    // set srcType for zimop
1130    decodedInst.srcType(0) := SrcType.reg
1131    decodedInst.srcType(1) := SrcType.imm
1132    // use x0 as src1
1133    decodedInst.lsrc(0) := 0.U
1134  }
1135
1136  io.deq.decodedInst := decodedInst
1137  io.deq.decodedInst.rfWen := (decodedInst.ldest =/= 0.U) && decodedInst.rfWen
1138  io.deq.decodedInst.fuType := Mux1H(Seq(
1139    // keep condition
1140    (!FuType.FuTypeOrR(decodedInst.fuType, FuType.vldu, FuType.vstu) && !isCsrrVl && !isCsrrVlenb) -> decodedInst.fuType,
1141    (isCsrrVl) -> FuType.vsetfwf.U,
1142    (isCsrrVlenb) -> FuType.alu.U,
1143
1144    // change vlsu to vseglsu when NF =/= 0.U
1145    ( FuType.FuTypeOrR(decodedInst.fuType, FuType.vldu, FuType.vstu) && inst.NF === 0.U || (inst.NF =/= 0.U && (inst.MOP === "b00".U && inst.SUMOP === "b01000".U))) -> decodedInst.fuType,
1146    // MOP === b00 && SUMOP === b01000: unit-stride whole register store
1147    // MOP =/= b00                    : strided and indexed store
1148    ( FuType.FuTypeOrR(decodedInst.fuType, FuType.vstu)              && inst.NF =/= 0.U && ((inst.MOP === "b00".U && inst.SUMOP =/= "b01000".U) || inst.MOP =/= "b00".U)) -> FuType.vsegstu.U,
1149    // MOP === b00 && LUMOP === b01000: unit-stride whole register load
1150    // MOP =/= b00                    : strided and indexed load
1151    ( FuType.FuTypeOrR(decodedInst.fuType, FuType.vldu)              && inst.NF =/= 0.U && ((inst.MOP === "b00".U && inst.LUMOP =/= "b01000".U) || inst.MOP =/= "b00".U)) -> FuType.vsegldu.U,
1152  ))
1153  io.deq.decodedInst.imm := MuxCase(decodedInst.imm, Seq(
1154    isCsrrVlenb -> (VLEN / 8).U,
1155    isZimop     -> 0.U,
1156  ))
1157
1158  io.deq.decodedInst.fuOpType := MuxCase(decodedInst.fuOpType, Seq(
1159    isCsrrVl    -> VSETOpType.csrrvl,
1160    isCsrrVlenb -> ALUOpType.add,
1161    isFLI       -> Cat(1.U, inst.FMT, inst.RS1),
1162    (isPreW || isPreR || isPreI) -> Mux1H(Seq(
1163      isPreW -> LSUOpType.prefetch_w,
1164      isPreR -> LSUOpType.prefetch_r,
1165      isPreI -> LSUOpType.prefetch_i,
1166    )),
1167    (isCboInval && io.fromCSR.special.cboI2F) -> LSUOpType.cbo_flush,
1168  ))
1169
1170  // Don't compress in the same Rob entry when crossing Ftq entry boundary
1171  io.deq.decodedInst.canRobCompress := decodedInst.canRobCompress && !io.enq.ctrlFlow.isLastInFtqEntry
1172
1173  //-------------------------------------------------------------
1174  // Debug Info
1175//  XSDebug("in:  instr=%x pc=%x excepVec=%b crossPageIPFFix=%d\n",
1176//    io.enq.ctrl_flow.instr, io.enq.ctrl_flow.pc, io.enq.ctrl_flow.exceptionVec.asUInt,
1177//    io.enq.ctrl_flow.crossPageIPFFix)
1178//  XSDebug("out: srcType(0)=%b srcType(1)=%b srcType(2)=%b lsrc(0)=%d lsrc(1)=%d lsrc(2)=%d ldest=%d fuType=%b fuOpType=%b\n",
1179//    io.deq.cf_ctrl.ctrl.srcType(0), io.deq.cf_ctrl.ctrl.srcType(1), io.deq.cf_ctrl.ctrl.srcType(2),
1180//    io.deq.cf_ctrl.ctrl.lsrc(0), io.deq.cf_ctrl.ctrl.lsrc(1), io.deq.cf_ctrl.ctrl.lsrc(2),
1181//    io.deq.cf_ctrl.ctrl.ldest, io.deq.cf_ctrl.ctrl.fuType, io.deq.cf_ctrl.ctrl.fuOpType)
1182//  XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d imm=%x\n",
1183//    io.deq.cf_ctrl.ctrl.rfWen, io.deq.cf_ctrl.ctrl.fpWen, io.deq.cf_ctrl.ctrl.isXSTrap,
1184//    io.deq.cf_ctrl.ctrl.noSpecExec, io.deq.cf_ctrl.ctrl.blockBackward, io.deq.cf_ctrl.ctrl.flushPipe,
1185//    io.deq.cf_ctrl.ctrl.imm)
1186//  XSDebug("out: excepVec=%b\n", io.deq.cf_ctrl.cf.exceptionVec.asUInt)
1187}
1188