xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala (revision 99f369f9af5e6460594190dced390d936b62b309)
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    AMOCAS_W  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amocas_w, SelImm.X, uopSplitType = UopSplitType.AMO_CAS_W, xWen = T, noSpec = T, blockBack = T),
244
245    AMOADD_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoadd_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
246    AMOXOR_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoxor_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
247    AMOSWAP_D -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoswap_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
248    AMOAND_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoand_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
249    AMOOR_D   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amoor_d  , SelImm.X, xWen = T, noSpec = T, blockBack = T),
250    AMOMIN_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomin_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
251    AMOMINU_D -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amominu_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
252    AMOMAX_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomax_d , SelImm.X, xWen = T, noSpec = T, blockBack = T),
253    AMOMAXU_D -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amomaxu_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
254    AMOCAS_D  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amocas_d, SelImm.X, uopSplitType = UopSplitType.AMO_CAS_D, xWen = T, noSpec = T, blockBack = T),
255
256    AMOCAS_Q  -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.amocas_q, SelImm.X, uopSplitType = UopSplitType.AMO_CAS_Q, xWen = T, noSpec = T, blockBack = T),
257
258    LR_W    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.mou, LSUOpType.lr_w, SelImm.X, xWen = T, noSpec = T, blockBack = T),
259    LR_D    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.mou, LSUOpType.lr_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
260    SC_W    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.sc_w, SelImm.X, xWen = T, noSpec = T, blockBack = T),
261    SC_D    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.mou, LSUOpType.sc_d, SelImm.X, xWen = T, noSpec = T, blockBack = T),
262  )
263}
264
265object BitmanipDecode extends DecodeConstants{
266  /*
267    Note: Some Bitmanip instruction may have different OP code between rv32 and rv64.
268    Including pseudo instruction like zext.h, and different funct12 like rev8.
269    If some day we need to support change XLEN via CSR, we should care about this.
270   */
271  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
272    // Zba
273    ADD_UW    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.adduw   , SelImm.X    , xWen = T, canRobCompress = T),
274    SH1ADD    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh1add  , SelImm.X    , xWen = T, canRobCompress = T),
275    SH1ADD_UW -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh1adduw, SelImm.X    , xWen = T, canRobCompress = T),
276    SH2ADD    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh2add  , SelImm.X    , xWen = T, canRobCompress = T),
277    SH2ADD_UW -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh2adduw, SelImm.X    , xWen = T, canRobCompress = T),
278    SH3ADD    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh3add  , SelImm.X    , xWen = T, canRobCompress = T),
279    SH3ADD_UW -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.sh3adduw, SelImm.X    , xWen = T, canRobCompress = T),
280    SLLI_UW   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.slliuw  , SelImm.IMM_I, xWen = T, canRobCompress = T),
281
282    // Zbb
283    ANDN      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.andn    , SelImm.X    , xWen = T, canRobCompress = T),
284    ORN       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.orn     , SelImm.X    , xWen = T, canRobCompress = T),
285    XNOR      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.xnor    , SelImm.X    , xWen = T, canRobCompress = T),
286
287    CLZ       -> XSDecode(SrcType.reg, SrcType.DC , SrcType.X, FuType.bku, BKUOpType.clz     , SelImm.X    , xWen = T, canRobCompress = T),
288    CLZW      -> XSDecode(SrcType.reg, SrcType.DC , SrcType.X, FuType.bku, BKUOpType.clzw    , SelImm.X    , xWen = T, canRobCompress = T),
289    CTZ       -> XSDecode(SrcType.reg, SrcType.DC , SrcType.X, FuType.bku, BKUOpType.ctz     , SelImm.X    , xWen = T, canRobCompress = T),
290    CTZW      -> XSDecode(SrcType.reg, SrcType.DC , SrcType.X, FuType.bku, BKUOpType.ctzw    , SelImm.X    , xWen = T, canRobCompress = T),
291
292    CPOP      -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.cpop    , SelImm.X    , xWen = T, canRobCompress = T),
293    CPOPW     -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.cpopw   , SelImm.X    , xWen = T, canRobCompress = T),
294
295    MAX       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.max     , SelImm.X    , xWen = T, canRobCompress = T),
296    MAXU      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.maxu    , SelImm.X    , xWen = T, canRobCompress = T),
297    MIN       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.min     , SelImm.X    , xWen = T, canRobCompress = T),
298    MINU      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.minu    , SelImm.X    , xWen = T, canRobCompress = T),
299
300    SEXT_B    -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.sextb   , SelImm.X    , xWen = T, canRobCompress = T),
301    SEXT_H    -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.sexth   , SelImm.X    , xWen = T, canRobCompress = T),
302    // zext.h in rv64 is shared with packw in Zbkb with rs2 = $0.
303    // If we configured to have no Zbkb, we should add zext.h here.
304
305    ROL       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.rol     , SelImm.X    , xWen = T, canRobCompress = T),
306    ROLW      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.rolw    , SelImm.X    , xWen = T, canRobCompress = T),
307    ROR       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.ror     , SelImm.X    , xWen = T, canRobCompress = T),
308    RORI      -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.ror     , SelImm.IMM_I, xWen = T, canRobCompress = T),
309    RORIW     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.rorw    , SelImm.IMM_I, xWen = T, canRobCompress = T),
310    RORW      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.rorw    , SelImm.X    , xWen = T, canRobCompress = T),
311
312    ORC_B     -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.orcb    , SelImm.X    , xWen = T, canRobCompress = T),
313
314    REV8      -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.rev8    , SelImm.X    , xWen = T, canRobCompress = T),
315
316    // Zbc
317    CLMUL     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.clmul   , SelImm.X    , xWen = T, canRobCompress = T),
318    CLMULH    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.clmulh  , SelImm.X    , xWen = T, canRobCompress = T),
319    CLMULR    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.clmulr  , SelImm.X    , xWen = T, canRobCompress = T),
320
321    // Zbs
322    BCLR      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.bclr    , SelImm.X    , xWen = T, canRobCompress = T),
323    BCLRI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.bclr    , SelImm.IMM_I, xWen = T, canRobCompress = T),
324    BEXT      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.bext    , SelImm.X    , xWen = T, canRobCompress = T),
325    BEXTI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.bext    , SelImm.IMM_I, xWen = T, canRobCompress = T),
326    BINV      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.binv    , SelImm.X    , xWen = T, canRobCompress = T),
327    BINVI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.binv    , SelImm.IMM_I, xWen = T, canRobCompress = T),
328    BSET      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.bset    , SelImm.X    , xWen = T, canRobCompress = T),
329    BSETI     -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.bset    , SelImm.IMM_I, xWen = T, canRobCompress = T),
330
331    // Zbkb
332    // rol, rolw, ror,rori, roriw, rorw, andn, orn, xnor, rev8 is in Zbb
333    PACK      -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.pack    , SelImm.X    , xWen = T, canRobCompress = T),
334    PACKH     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.packh   , SelImm.X    , xWen = T, canRobCompress = T),
335    PACKW     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.packw   , SelImm.X    , xWen = T, canRobCompress = T),
336    BREV8     -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.alu, ALUOpType.revb    , SelImm.X    , xWen = T, canRobCompress = T),
337    // If configured to RV32, we should add zip and unzip.
338
339    // Zbkc
340    // clmul, clmulh is in Zbc
341
342    // Zbkx
343    XPERM4    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.xpermn  , SelImm.X    , xWen = T, canRobCompress = T),
344    XPERM8    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.xpermb  , SelImm.X    , xWen = T, canRobCompress = T),
345  )
346}
347
348object ScalarCryptoDecode extends DecodeConstants {
349  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
350    // Zknd: NIST Suite: AES Decryption
351    AES64DS    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64ds   , SelImm.X    , xWen = T, canRobCompress = T),
352    AES64DSM   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64dsm  , SelImm.X    , xWen = T, canRobCompress = T),
353    AES64IM    -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.aes64im   , SelImm.X    , xWen = T, canRobCompress = T),
354    AES64KS1I  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.bku, BKUOpType.aes64ks1i , SelImm.IMM_I, xWen = T, canRobCompress = T),
355    AES64KS2   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64ks2  , SelImm.X    , xWen = T, canRobCompress = T),
356
357    // Zkne: NIST Suite: AES Encryption
358    // aes64ks1i, aes64ks2 is in Zknd
359    AES64ES    -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64es   , SelImm.X    , xWen = T, canRobCompress = T),
360    AES64ESM   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.aes64esm  , SelImm.X    , xWen = T, canRobCompress = T),
361
362    // Zknh: NIST Suite: Hash Function Instructions
363    SHA256SIG0 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha256sig0, SelImm.X    , xWen = T, canRobCompress = T),
364    SHA256SIG1 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha256sig1, SelImm.X    , xWen = T, canRobCompress = T),
365    SHA256SUM0 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha256sum0, SelImm.X    , xWen = T, canRobCompress = T),
366    SHA256SUM1 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha256sum1, SelImm.X    , xWen = T, canRobCompress = T),
367    SHA512SIG0 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha512sig0, SelImm.X    , xWen = T, canRobCompress = T),
368    SHA512SIG1 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha512sig1, SelImm.X    , xWen = T, canRobCompress = T),
369    SHA512SUM0 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha512sum0, SelImm.X    , xWen = T, canRobCompress = T),
370    SHA512SUM1 -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sha512sum1, SelImm.X    , xWen = T, canRobCompress = T),
371
372    // Zksed: ShangMi Suite: SM4 Block Cipher Instructions
373    SM4ED0     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ed0    , SelImm.X    , xWen = T, canRobCompress = T),
374    SM4ED1     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ed1    , SelImm.X    , xWen = T, canRobCompress = T),
375    SM4ED2     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ed2    , SelImm.X    , xWen = T, canRobCompress = T),
376    SM4ED3     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ed3    , SelImm.X    , xWen = T, canRobCompress = T),
377    SM4KS0     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ks0    , SelImm.X    , xWen = T, canRobCompress = T),
378    SM4KS1     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ks1    , SelImm.X    , xWen = T, canRobCompress = T),
379    SM4KS2     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ks2    , SelImm.X    , xWen = T, canRobCompress = T),
380    SM4KS3     -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.bku, BKUOpType.sm4ks3    , SelImm.X    , xWen = T, canRobCompress = T),
381
382    // Zksh: ShangMi Suite: SM3 Hash Function Instructions
383    SM3P0      -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sm3p0     , SelImm.X    , xWen = T, canRobCompress = T),
384    SM3P1      -> XSDecode(SrcType.reg, SrcType.DC,  SrcType.X, FuType.bku, BKUOpType.sm3p1     , SelImm.X    , xWen = T, canRobCompress = T),
385  )
386}
387
388/**
389 * FP Decode constants
390 */
391object FpDecode extends DecodeConstants{
392  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
393    FLH     -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lh, selImm = SelImm.IMM_I, fWen = T),
394    FLW     -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lw, selImm = SelImm.IMM_I, fWen = T),
395    FLD     -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.ld, selImm = SelImm.IMM_I, fWen = T),
396    FSH     -> FDecode(SrcType.reg, SrcType.fp,  SrcType.X, FuType.stu, LSUOpType.sh, selImm = SelImm.IMM_S          ),
397    FSW     -> FDecode(SrcType.reg, SrcType.fp,  SrcType.X, FuType.stu, LSUOpType.sw, selImm = SelImm.IMM_S          ),
398    FSD     -> FDecode(SrcType.reg, SrcType.fp,  SrcType.X, FuType.stu, LSUOpType.sd, selImm = SelImm.IMM_S          ),
399
400    FMV_D_X -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2v, IF2VectorType.FMX_D_X, fWen = T, canRobCompress = T),
401    FMV_W_X -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2v, IF2VectorType.FMX_W_X, fWen = T, canRobCompress = T),
402    FMV_H_X -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2v, IF2VectorType.FMX_H_X, fWen = T, canRobCompress = T),
403
404    // Int to FP
405    FCVT_S_W  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
406    FCVT_S_WU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
407    FCVT_S_L  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
408    FCVT_S_LU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
409
410    FCVT_D_W  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
411    FCVT_D_WU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
412    FCVT_D_L  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
413    FCVT_D_LU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
414
415    FCVT_H_W  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
416    FCVT_H_WU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
417    FCVT_H_L  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
418    FCVT_H_LU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
419  )
420}
421
422/**
423 * FP Divide SquareRoot Constants
424 */
425object FDivSqrtDecode extends DecodeConstants {
426  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
427    FDIV_S  -> FDecode(SrcType.fp,  SrcType.fp,  SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
428    FDIV_D  -> FDecode(SrcType.fp,  SrcType.fp,  SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
429    FSQRT_S -> FDecode(SrcType.fp,  SrcType.imm, SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
430    FSQRT_D -> FDecode(SrcType.fp,  SrcType.imm, SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
431  )
432}
433
434/**
435 * Svinval extension Constants
436 */
437object SvinvalDecode extends DecodeConstants {
438  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
439    /* sinval_vma is like sfence.vma , but sinval_vma can be dispatched and issued like normal instructions while sfence.vma
440     * must assure it is the ONLY instrucion executing in backend.
441     * Since software cannot promiss all sinval.vma between sfence.w.inval and sfence.inval.ir, we make sinval.vma wait
442     * forward.
443     */
444    SINVAL_VMA        -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.sfence, SelImm.X, noSpec = T, blockBack = T),
445    /* sfecne.w.inval is the begin instrucion of a TLB flush which set *noSpecExec* and *blockBackward* signals
446     * so when it comes to dispatch , it will block all instruction after itself until all instrucions ahead of it in rob commit
447     * then dispatch and issue this instrucion to flush sbuffer to dcache
448     * after this instrucion commits , issue following sinval_vma instructions (out of order) to flush TLB
449     */
450    SFENCE_W_INVAL    -> XSDecode(SrcType.DC, SrcType.DC, SrcType.X, FuType.fence, FenceOpType.nofence, SelImm.X, noSpec = T, blockBack = T),
451    /* sfecne.inval.ir is the end instrucion of a TLB flush which set *noSpecExec* *blockBackward* and *flushPipe* signals
452     * so when it comes to dispatch , it will wait until all sinval_vma ahead of it in rob commit
453     * then dispatch and issue this instrucion
454     * when it commit at the head of rob , flush the pipeline since some instrucions have been fetched to ibuffer using old TLB map
455     */
456    SFENCE_INVAL_IR   -> XSDecode(SrcType.DC, SrcType.DC, SrcType.X, FuType.fence, FenceOpType.nofence, SelImm.X, noSpec = T, blockBack = T, flushPipe = T)
457    /* what is Svinval extension ?
458     *                       ----->             sfecne.w.inval
459     * sfence.vma   vpn1     ----->             sinval_vma   vpn1
460     * sfence.vma   vpn2     ----->             sinval_vma   vpn2
461     *                       ----->             sfecne.inval.ir
462     *
463     * sfence.vma should be executed in-order and it flushes the pipeline after committing
464     * we can parallel sfence instrucions with this extension
465     */
466  )
467}
468
469/*
470 * CBO decode
471 */
472object CBODecode extends DecodeConstants {
473  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
474    CBO_ZERO  -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_zero , SelImm.IMM_S),
475    CBO_CLEAN -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_clean, SelImm.IMM_S),
476    CBO_FLUSH -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_flush, SelImm.IMM_S),
477    CBO_INVAL -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_inval, SelImm.IMM_S)
478  )
479}
480
481/*
482 * Hypervisor decode
483 */
484object HypervisorDecode extends DecodeConstants {
485  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
486    HFENCE_GVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_g, SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
487    HFENCE_VVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_v, SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
488
489    /**
490     * Since software cannot promiss all sinval.vma between sfence.w.inval and sfence.inval.ir, we make sinval.vma wait
491     * forward.
492     */
493    HINVAL_GVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_g, SelImm.X, noSpec = T, blockBack = T),
494    HINVAL_VVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_v, SelImm.X, noSpec = T, blockBack = T),
495    HLV_B       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvb,       SelImm.X, xWen = T),
496    HLV_BU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvbu,      SelImm.X, xWen = T),
497    HLV_D       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvd,       SelImm.X, xWen = T),
498    HLV_H       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvh,       SelImm.X, xWen = T),
499    HLV_HU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvhu,      SelImm.X, xWen = T),
500    HLV_W       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvw,       SelImm.X, xWen = T),
501    HLV_WU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvwu,      SelImm.X, xWen = T),
502    HLVX_HU     -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvxhu,     SelImm.X, xWen = T),
503    HLVX_WU     -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvxwu,     SelImm.X, xWen = T),
504    HSV_B       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvb,       SelImm.X),
505    HSV_D       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvd,       SelImm.X),
506    HSV_H       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvh,       SelImm.X),
507    HSV_W       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvw,       SelImm.X),
508  )
509}
510
511object ZicondDecode extends DecodeConstants {
512  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
513    CZERO_EQZ   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.czero_eqz, SelImm.X, xWen = T, canRobCompress = T),
514    CZERO_NEZ   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.czero_nez, SelImm.X, xWen = T, canRobCompress = T),
515  )
516}
517
518/**
519  * "Zimop" Extension for May-Be-Operations
520  */
521object ZimopDecode extends DecodeConstants {
522  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
523    // temp use addi to decode MOP_R and MOP_RR
524    MOP_R  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.add, SelImm.IMM_I, xWen = T, canRobCompress = T),
525    MOP_RR -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.add, SelImm.IMM_I, xWen = T, canRobCompress = T),
526  )
527}
528
529object ZfaDecode extends DecodeConstants {
530  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
531    FLI_H       -> FDecode(SrcType.no, SrcType.X, SrcType.X, FuType.f2v, FuOpType.X, fWen = T, canRobCompress = T),
532    FLI_S       -> FDecode(SrcType.no, SrcType.X, SrcType.X, FuType.f2v, FuOpType.X, fWen = T, canRobCompress = T),
533    FLI_D       -> FDecode(SrcType.no, SrcType.X, SrcType.X, FuType.f2v, FuOpType.X, fWen = T, canRobCompress = T),
534    FMINM_H     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fminm, fWen = T, canRobCompress = T),
535    FMINM_S     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fminm, fWen = T, canRobCompress = T),
536    FMINM_D     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fminm, fWen = T, canRobCompress = T),
537    FMAXM_H     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fmaxm, fWen = T, canRobCompress = T),
538    FMAXM_S     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fmaxm, fWen = T, canRobCompress = T),
539    FMAXM_D     -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fmaxm, fWen = T, canRobCompress = T),
540    FROUND_H    -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.fround,   fWen = T, canRobCompress = T),
541    FROUND_S    -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.fround,   fWen = T, canRobCompress = T),
542    FROUND_D    -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.fround,   fWen = T, canRobCompress = T),
543    FROUNDNX_H  -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.froundnx, fWen = T, canRobCompress = T),
544    FROUNDNX_S  -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.froundnx, fWen = T, canRobCompress = T),
545    FROUNDNX_D  -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.froundnx, fWen = T, canRobCompress = T),
546    FCVTMOD_W_D -> FDecode(SrcType.fp, SrcType.X,  SrcType.X, FuType.fcvt, VfcvtType.fcvtmod_w_d, xWen = T, canRobCompress = T),
547    FLEQ_H      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fleq, xWen = T, canRobCompress = T),
548    FLEQ_S      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fleq, xWen = T, canRobCompress = T),
549    FLEQ_D      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fleq, xWen = T, canRobCompress = T),
550    FLTQ_H      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fltq, xWen = T, canRobCompress = T),
551    FLTQ_S      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fltq, xWen = T, canRobCompress = T),
552    FLTQ_D      -> FDecode(SrcType.fp, SrcType.fp, SrcType.X, FuType.falu, VfaluType.fltq, xWen = T, canRobCompress = T),
553  )
554}
555
556/**
557 * XiangShan Trap Decode constants
558 */
559object XSTrapDecode extends DecodeConstants {
560  def TRAP = BitPat("b000000000000?????000000001101011")
561  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
562    TRAP    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.add, SelImm.IMM_I, xWen = T, xsTrap = T, noSpec = T, blockBack = T)
563  )
564}
565
566abstract class Imm(val len: Int) {
567  def toImm32(minBits: UInt): UInt = do_toImm32(minBits(len - 1, 0))
568  def do_toImm32(minBits: UInt): UInt
569  def minBitsFromInstr(instr: UInt): UInt
570}
571
572case class Imm_I() extends Imm(12) {
573  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits(len - 1, 0), 32)
574
575  override def minBitsFromInstr(instr: UInt): UInt =
576    Cat(instr(31, 20))
577}
578
579case class Imm_S() extends Imm(12) {
580  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
581
582  override def minBitsFromInstr(instr: UInt): UInt =
583    Cat(instr(31, 25), instr(11, 7))
584}
585
586case class Imm_B() extends Imm(12) {
587  override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
588
589  override def minBitsFromInstr(instr: UInt): UInt =
590    Cat(instr(31), instr(7), instr(30, 25), instr(11, 8))
591}
592
593case class Imm_U() extends Imm(20){
594  override def do_toImm32(minBits: UInt): UInt = Cat(minBits(len - 1, 0), 0.U(12.W))
595
596  override def minBitsFromInstr(instr: UInt): UInt = {
597    instr(31, 12)
598  }
599}
600
601case class Imm_J() extends Imm(20){
602  override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
603
604  override def minBitsFromInstr(instr: UInt): UInt = {
605    Cat(instr(31), instr(19, 12), instr(20), instr(30, 25), instr(24, 21))
606  }
607}
608
609case class Imm_Z() extends Imm(12 + 5 + 5){
610  override def do_toImm32(minBits: UInt): UInt = minBits
611
612  override def minBitsFromInstr(instr: UInt): UInt = {
613    Cat(instr(11, 7), instr(19, 15), instr(31, 20))
614  }
615
616  def getCSRAddr(imm: UInt): UInt = {
617    require(imm.getWidth == this.len)
618    imm(11, 0)
619  }
620
621  def getRS1(imm: UInt): UInt = {
622    require(imm.getWidth == this.len)
623    imm(16, 12)
624  }
625
626  def getRD(imm: UInt): UInt = {
627    require(imm.getWidth == this.len)
628    imm(21, 17)
629  }
630
631  def getImm5(imm: UInt): UInt = {
632    require(imm.getWidth == this.len)
633    imm(16, 12)
634  }
635}
636
637case class Imm_B6() extends Imm(6){
638  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
639
640  override def minBitsFromInstr(instr: UInt): UInt = {
641    instr(25, 20)
642  }
643}
644
645case class Imm_OPIVIS() extends Imm(5){
646  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
647
648  override def minBitsFromInstr(instr: UInt): UInt = {
649    instr(19, 15)
650  }
651}
652
653case class Imm_OPIVIU() extends Imm(5){
654  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
655
656  override def minBitsFromInstr(instr: UInt): UInt = {
657    instr(19, 15)
658  }
659}
660
661case class Imm_VSETVLI() extends Imm(11){
662  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
663
664  override def minBitsFromInstr(instr: UInt): UInt = {
665    instr(30, 20)
666  }
667  /**
668    * get VType from extended imm
669    * @param extedImm
670    * @return VType
671    */
672  def getVType(extedImm: UInt): InstVType = {
673    val vtype = Wire(new InstVType)
674    vtype := extedImm(10, 0).asTypeOf(new InstVType)
675    vtype
676  }
677}
678
679case class Imm_VSETIVLI() extends Imm(15){
680  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
681
682  override def minBitsFromInstr(instr: UInt): UInt = {
683    val rvInst: XSInstBitFields = instr.asTypeOf(new XSInstBitFields)
684    val uimm5 = rvInst.UIMM_VSETIVLI
685    val vtype8 = rvInst.ZIMM_VSETIVLI
686    Cat(uimm5, vtype8)
687  }
688  /**
689    * get VType from extended imm
690    * @param extedImm
691    * @return VType
692    */
693  def getVType(extedImm: UInt): InstVType = {
694    val vtype = Wire(new InstVType)
695    vtype := extedImm(9, 0).asTypeOf(new InstVType)
696    vtype
697  }
698
699  def getAvl(extedImm: UInt): UInt = {
700    extedImm(14, 10)
701  }
702}
703
704case class Imm_LUI32() extends Imm(32){
705  override def do_toImm32(minBits: UInt): UInt = minBits(31, 0)
706
707  override def minBitsFromInstr(instr: UInt): UInt = {
708    instr(31, 0)
709  }
710}
711
712case class Imm_VRORVI() extends Imm(6){
713  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
714
715  override def minBitsFromInstr(instr: UInt): UInt = {
716    Cat(instr(26), instr(19, 15))
717  }
718}
719
720object ImmUnion {
721  val I = Imm_I()
722  val S = Imm_S()
723  val B = Imm_B()
724  val U = Imm_U()
725  val J = Imm_J()
726  val Z = Imm_Z()
727  val B6 = Imm_B6()
728  val OPIVIS = Imm_OPIVIS()
729  val OPIVIU = Imm_OPIVIU()
730  val VSETVLI = Imm_VSETVLI()
731  val VSETIVLI = Imm_VSETIVLI()
732  val LUI32 = Imm_LUI32()
733  val VRORVI = Imm_VRORVI()
734
735  // do not add special type lui32 to this, keep ImmUnion max len being 20.
736  val imms = Seq(I, S, B, U, J, Z, B6, OPIVIS, OPIVIU, VSETVLI, VSETIVLI, VRORVI)
737  val maxLen = imms.maxBy(_.len).len
738  val immSelMap = Seq(
739    SelImm.IMM_I,
740    SelImm.IMM_S,
741    SelImm.IMM_SB,
742    SelImm.IMM_U,
743    SelImm.IMM_UJ,
744    SelImm.IMM_Z,
745    SelImm.IMM_B6,
746    SelImm.IMM_OPIVIS,
747    SelImm.IMM_OPIVIU,
748    SelImm.IMM_VSETVLI,
749    SelImm.IMM_VSETIVLI,
750    SelImm.IMM_VRORVI,
751  ).zip(imms)
752  println(s"ImmUnion max len: $maxLen")
753}
754
755case class Imm_LUI_LOAD() {
756  def immFromLuiLoad(lui_imm: UInt, load_imm: UInt): UInt = {
757    val loadImm = load_imm(Imm_I().len - 1, 0)
758    Cat(lui_imm(ImmUnion.maxLen - loadImm.getWidth - 1, 0), loadImm)
759  }
760  def getLuiImm(uop: DynInst): UInt = {
761    val loadImmLen = Imm_I().len
762    val imm_u = Cat(uop.psrc(1), uop.psrc(0), uop.imm(ImmUnion.maxLen - 1, loadImmLen))
763    Cat(Imm_U().toImm32(imm_u)(31, loadImmLen), uop.imm(loadImmLen - 1, 0))
764  }
765}
766
767/**
768 * IO bundle for the Decode unit
769 */
770class DecodeUnitDeqIO(implicit p: Parameters) extends XSBundle {
771  val decodedInst = Output(new DecodedInst)
772  val isComplex = Output(Bool())
773  val uopInfo = Output(new UopInfo)
774}
775class DecodeUnitIO(implicit p: Parameters) extends XSBundle {
776  val enq = new Bundle {
777    val ctrlFlow = Input(new StaticInst)
778    val vtype = Input(new VType)
779    val vstart = Input(Vl())
780  }
781//  val vconfig = Input(UInt(XLEN.W))
782  val deq = new DecodeUnitDeqIO
783  val csrCtrl = Input(new CustomCSRCtrlIO)
784  val fromCSR = Input(new CSRToDecode)
785}
786
787/**
788 * Decode unit that takes in a single CtrlFlow and generates a CfCtrl.
789 */
790class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstants {
791  val io = IO(new DecodeUnitIO)
792
793  val ctrl_flow = io.enq.ctrlFlow // input with RVC Expanded
794
795  private val inst: XSInstBitFields = io.enq.ctrlFlow.instr.asTypeOf(new XSInstBitFields)
796
797  val decode_table: Array[(BitPat, List[BitPat])] = XDecode.table ++
798    FpDecode.table ++
799//    FDivSqrtDecode.table ++
800    BitmanipDecode.table ++
801    ScalarCryptoDecode.table ++
802    XSTrapDecode.table ++
803    CBODecode.table ++
804    SvinvalDecode.table ++
805    HypervisorDecode.table ++
806    VecDecoder.table ++
807    ZicondDecode.table ++
808    ZimopDecode.table ++
809    ZfaDecode.table
810
811  require(decode_table.map(_._2.length == 15).reduce(_ && _), "Decode tables have different column size")
812  // assertion for LUI: only LUI should be assigned `selImm === SelImm.IMM_U && fuType === FuType.alu`
813  val luiMatch = (t: Seq[BitPat]) => t(3).value == FuType.alu.ohid && t.reverse.head.value == SelImm.IMM_U.litValue
814  val luiTable = decode_table.filter(t => luiMatch(t._2)).map(_._1).distinct
815  assert(luiTable.length == 1 && luiTable.head == LUI, "Conflicts: LUI is determined by FuType and SelImm in Dispatch")
816
817  // output
818  val decodedInst: DecodedInst = Wire(new DecodedInst()).decode(ctrl_flow.instr, decode_table)
819
820  val fpDecoder = Module(new FPDecoder)
821  fpDecoder.io.instr := ctrl_flow.instr
822  decodedInst.fpu := fpDecoder.io.fpCtrl
823  decodedInst.fpu.wflags := fpDecoder.io.fpCtrl.wflags || decodedInst.wfflags
824
825  decodedInst.connectStaticInst(io.enq.ctrlFlow)
826
827  decodedInst.uopIdx := 0.U
828  decodedInst.firstUop := true.B
829  decodedInst.lastUop := true.B
830  decodedInst.numUops := 1.U
831  decodedInst.numWB   := 1.U
832
833  val isZimop = (BitPat("b1?00??0111??_?????_100_?????_1110011") === ctrl_flow.instr) ||
834                (BitPat("b1?00??1?????_?????_100_?????_1110011") === ctrl_flow.instr)
835
836  val isMove = BitPat("b000000000000_?????_000_?????_0010011") === ctrl_flow.instr
837  // temp decode zimop as move
838  decodedInst.isMove := (isMove || isZimop) && ctrl_flow.instr(RD_MSB, RD_LSB) =/= 0.U && !io.csrCtrl.singlestep
839
840  // fmadd - b1000011
841  // fmsub - b1000111
842  // fnmsub- b1001011
843  // fnmadd- b1001111
844  private val isFMA = inst.OPCODE === BitPat("b100??11")
845  private val isVppu = FuType.isVppu(decodedInst.fuType)
846  private val isVecOPF = FuType.isVecOPF(decodedInst.fuType)
847
848  // read src1~3 location
849  decodedInst.lsrc(0) := inst.RS1
850  decodedInst.lsrc(1) := inst.RS2
851  // src(2) of fma is fs3, src(2) of vector inst is old vd
852  decodedInst.lsrc(2) := Mux(isFMA, inst.FS3, inst.VD)
853  decodedInst.lsrc(3) := V0_IDX.U
854  decodedInst.lsrc(4) := Vl_IDX.U
855
856  // read dest location
857  decodedInst.ldest := inst.RD
858
859  // init v0Wen vlWen
860  decodedInst.v0Wen := false.B
861  decodedInst.vlWen := false.B
862
863  private val isCboClean = CBO_CLEAN === io.enq.ctrlFlow.instr
864  private val isCboFlush = CBO_FLUSH === io.enq.ctrlFlow.instr
865  private val isCboInval = CBO_INVAL === io.enq.ctrlFlow.instr
866  private val isCboZero  = CBO_ZERO  === io.enq.ctrlFlow.instr
867
868  // Note that rnum of aes64ks1i must be in the range 0x0..0xA. The values 0xB..0xF are reserved.
869  private val isAes64ks1iIllegal =
870    FuType.FuTypeOrR(decodedInst.fuType, FuType.bku) && (decodedInst.fuOpType === BKUOpType.aes64ks1i) && inst.isRnumIllegal
871
872  private val isAmocasQ = FuType.FuTypeOrR(decodedInst.fuType, FuType.mou) && decodedInst.fuOpType === LSUOpType.amocas_q
873  private val isAmocasQIllegal = isAmocasQ && (inst.RD(0) === 1.U || inst.RS2(0) === 1.U)
874
875  private val exceptionII =
876    decodedInst.selImm === SelImm.INVALID_INSTR ||
877    io.fromCSR.illegalInst.sfenceVMA  && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.sfence  ||
878    io.fromCSR.illegalInst.sfencePart && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.nofence ||
879    io.fromCSR.illegalInst.hfenceGVMA && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.hfence_g ||
880    io.fromCSR.illegalInst.hfenceVVMA && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.hfence_v ||
881    io.fromCSR.illegalInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu)   && (LSUOpType.isHlv(decodedInst.fuOpType) || LSUOpType.isHlvx(decodedInst.fuOpType)) ||
882    io.fromCSR.illegalInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.stu)   && LSUOpType.isHsv(decodedInst.fuOpType) ||
883    io.fromCSR.illegalInst.fsIsOff    && (
884      FuType.FuTypeOrR(decodedInst.fuType, FuType.fpOP ++ Seq(FuType.f2v)) ||
885      (FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu) && (decodedInst.fuOpType === LSUOpType.lh || decodedInst.fuOpType === LSUOpType.lw || decodedInst.fuOpType === LSUOpType.ld) ||
886      FuType.FuTypeOrR(decodedInst.fuType, FuType.stu) && (decodedInst.fuOpType === LSUOpType.sh || decodedInst.fuOpType === LSUOpType.sw || decodedInst.fuOpType === LSUOpType.sd)) && decodedInst.instr(2) ||
887      inst.isOPFVF || inst.isOPFVV
888    ) ||
889    io.fromCSR.illegalInst.vsIsOff    && FuType.FuTypeOrR(decodedInst.fuType, FuType.vecAll) ||
890    io.fromCSR.illegalInst.wfi        && FuType.FuTypeOrR(decodedInst.fuType, FuType.csr)   && CSROpType.isWfi(decodedInst.fuOpType) ||
891    (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)) ||
892    (decodedInst.needFrm.vectorNeedFrm || FuType.isVectorNeedFrm(decodedInst.fuType)) && io.fromCSR.illegalInst.frm ||
893    io.fromCSR.illegalInst.cboZ       && isCboZero ||
894    io.fromCSR.illegalInst.cboCF      && (isCboClean || isCboFlush) ||
895    io.fromCSR.illegalInst.cboI       && isCboInval ||
896    isAes64ks1iIllegal ||
897    isAmocasQIllegal
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 = inst.isVecStore || inst.isVecLoad
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  decodedInst.vpu := 0.U.asTypeOf(decodedInst.vpu) // Todo: Connect vpu decoder
1023  decodedInst.vpu.vill := io.enq.vtype.illegal
1024  decodedInst.vpu.vma := io.enq.vtype.vma
1025  decodedInst.vpu.vta := io.enq.vtype.vta
1026  decodedInst.vpu.vsew := io.enq.vtype.vsew
1027  decodedInst.vpu.vlmul := io.enq.vtype.vlmul
1028  decodedInst.vpu.vm := inst.VM
1029  decodedInst.vpu.nf := inst.NF
1030  decodedInst.vpu.veew := inst.WIDTH
1031  decodedInst.vpu.isReverse := needReverseInsts.map(_ === inst.ALL).reduce(_ || _)
1032  decodedInst.vpu.isExt := vextInsts.map(_ === inst.ALL).reduce(_ || _)
1033  val isNarrow = narrowInsts.map(_ === inst.ALL).reduce(_ || _)
1034  val isDstMask = maskDstInsts.map(_ === inst.ALL).reduce(_ || _)
1035  val isOpMask = maskOpInsts.map(_ === inst.ALL).reduce(_ || _)
1036  val isVload = FuType.isVLoad(decodedInst.fuType)
1037  val isVlx = isVload && (decodedInst.fuOpType === VlduType.vloxe || decodedInst.fuOpType === VlduType.vluxe)
1038  val isVle = isVload && (decodedInst.fuOpType === VlduType.vle || decodedInst.fuOpType === VlduType.vleff || decodedInst.fuOpType === VlduType.vlse)
1039  val isVlm = isVload && (decodedInst.fuOpType === VlduType.vlm)
1040  val isFof = isVload && (decodedInst.fuOpType === VlduType.vleff)
1041  val isWritePartVd = decodedInst.uopSplitType === UopSplitType.VEC_VRED || decodedInst.uopSplitType === UopSplitType.VEC_0XV || decodedInst.uopSplitType === UopSplitType.VEC_VWW
1042  val isVma = vmaInsts.map(_ === inst.ALL).reduce(_ || _)
1043  val emulIsFrac = Cat(~decodedInst.vpu.vlmul(2), decodedInst.vpu.vlmul(1, 0)) +& decodedInst.vpu.veew < 4.U +& decodedInst.vpu.vsew
1044  val vstartIsNotZero = io.enq.vstart =/= 0.U
1045  decodedInst.vpu.isNarrow := isNarrow
1046  decodedInst.vpu.isDstMask := isDstMask
1047  decodedInst.vpu.isOpMask := isOpMask
1048  decodedInst.vpu.isDependOldVd := isVppu || isVecOPF || isVStore || (isDstMask && !isOpMask) || isNarrow || isVlx || isVma || isFof || vstartIsNotZero
1049  decodedInst.vpu.isWritePartVd := isWritePartVd || isVlm || isVle && emulIsFrac
1050  decodedInst.vpu.vstart := io.enq.vstart
1051  decodedInst.vpu.isVleff := isFof && inst.NF === 0.U
1052  decodedInst.vpu.specVill := io.enq.vtype.illegal
1053  decodedInst.vpu.specVma := io.enq.vtype.vma
1054  decodedInst.vpu.specVta := io.enq.vtype.vta
1055  decodedInst.vpu.specVsew := io.enq.vtype.vsew
1056  decodedInst.vpu.specVlmul := io.enq.vtype.vlmul
1057
1058  decodedInst.vlsInstr := isVls
1059
1060  decodedInst.srcType(3) := Mux(inst.VM === 0.U, SrcType.vp, SrcType.DC) // mask src
1061  decodedInst.srcType(4) := SrcType.vp // vconfig
1062
1063  val uopInfoGen = Module(new UopInfoGen)
1064  uopInfoGen.io.in.preInfo.isVecArith := inst.isVecArith
1065  uopInfoGen.io.in.preInfo.isVecMem := inst.isVecStore || inst.isVecLoad
1066  uopInfoGen.io.in.preInfo.isAmoCAS := inst.isAMOCAS
1067
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  io.deq.uopInfo.numOfUop := uopInfoGen.io.out.uopInfo.numOfUop
1078  io.deq.uopInfo.numOfWB := uopInfoGen.io.out.uopInfo.numOfWB
1079  io.deq.uopInfo.lmul := uopInfoGen.io.out.uopInfo.lmul
1080
1081  val isCsr = inst.OPCODE5Bit === OPCODE5Bit.SYSTEM && inst.FUNCT3(1, 0) =/= 0.U
1082  val isCsrr = isCsr && inst.FUNCT3 === BitPat("b?1?") && inst.RS1 === 0.U
1083  val isCsrw = isCsr && inst.FUNCT3 === BitPat("b?01") && inst.RD  === 0.U
1084  dontTouch(isCsrr)
1085  dontTouch(isCsrw)
1086
1087  // for csrr vl instruction, convert to vsetvl
1088  val isCsrrVlenb = isCsrr && inst.CSRIDX === CSRs.vlenb.U
1089  val isCsrrVl    = isCsrr && inst.CSRIDX === CSRs.vl.U
1090
1091  // decode for SoftPrefetch instructions (prefetch.w / prefetch.r / prefetch.i)
1092  val isSoftPrefetch = inst.OPCODE === BitPat("b0010011") && inst.FUNCT3 === BitPat("b110") && inst.RD === 0.U
1093  val isPreW = isSoftPrefetch && inst.RS2 === 3.U(5.W)
1094  val isPreR = isSoftPrefetch && inst.RS2 === 1.U(5.W)
1095  val isPreI = isSoftPrefetch && inst.RS2 === 0.U(5.W)
1096
1097  // for fli.s|fli.d instruction
1098  val isFLI = inst.FUNCT7 === BitPat("b11110??") && inst.RS2 === 1.U && inst.RM === 0.U && inst.OPCODE5Bit === OPCODE5Bit.OP_FP
1099
1100  when (isCsrrVl) {
1101    // convert to vsetvl instruction
1102    decodedInst.srcType(0) := SrcType.no
1103    decodedInst.srcType(1) := SrcType.no
1104    decodedInst.srcType(2) := SrcType.no
1105    decodedInst.srcType(3) := SrcType.no
1106    decodedInst.srcType(4) := SrcType.vp
1107    decodedInst.lsrc(4)    := Vl_IDX.U
1108    decodedInst.waitForward   := false.B
1109    decodedInst.blockBackward := false.B
1110    decodedInst.exceptionVec(illegalInstr) := io.fromCSR.illegalInst.vsIsOff
1111  }.elsewhen (isCsrrVlenb) {
1112    // convert to addi instruction
1113    decodedInst.srcType(0) := SrcType.reg
1114    decodedInst.srcType(1) := SrcType.imm
1115    decodedInst.srcType(2) := SrcType.no
1116    decodedInst.srcType(3) := SrcType.no
1117    decodedInst.srcType(4) := SrcType.no
1118    decodedInst.selImm := SelImm.IMM_I
1119    decodedInst.waitForward := false.B
1120    decodedInst.blockBackward := false.B
1121    decodedInst.canRobCompress := true.B
1122    decodedInst.exceptionVec(illegalInstr) := io.fromCSR.illegalInst.vsIsOff
1123  }.elsewhen (isPreW || isPreR || isPreI) {
1124    decodedInst.selImm := SelImm.IMM_S
1125    decodedInst.fuType := FuType.ldu.U
1126    decodedInst.canRobCompress := false.B
1127  }.elsewhen (isZimop) {
1128    // set srcType for zimop
1129    decodedInst.srcType(0) := SrcType.reg
1130    decodedInst.srcType(1) := SrcType.imm
1131    // use x0 as src1
1132    decodedInst.lsrc(0) := 0.U
1133  }
1134
1135  io.deq.decodedInst := decodedInst
1136  io.deq.decodedInst.rfWen := (decodedInst.ldest =/= 0.U) && decodedInst.rfWen
1137  io.deq.decodedInst.fuType := Mux1H(Seq(
1138    // keep condition
1139    (!FuType.FuTypeOrR(decodedInst.fuType, FuType.vldu, FuType.vstu) && !isCsrrVl && !isCsrrVlenb) -> decodedInst.fuType,
1140    (isCsrrVl) -> FuType.vsetfwf.U,
1141    (isCsrrVlenb) -> FuType.alu.U,
1142
1143    // change vlsu to vseglsu when NF =/= 0.U
1144    ( 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,
1145    // MOP === b00 && SUMOP === b01000: unit-stride whole register store
1146    // MOP =/= b00                    : strided and indexed store
1147    ( 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,
1148    // MOP === b00 && LUMOP === b01000: unit-stride whole register load
1149    // MOP =/= b00                    : strided and indexed load
1150    ( 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,
1151  ))
1152  io.deq.decodedInst.imm := MuxCase(decodedInst.imm, Seq(
1153    isCsrrVlenb -> (VLEN / 8).U,
1154    isZimop     -> 0.U,
1155  ))
1156
1157  io.deq.decodedInst.fuOpType := MuxCase(decodedInst.fuOpType, Seq(
1158    isCsrrVl    -> VSETOpType.csrrvl,
1159    isCsrrVlenb -> ALUOpType.add,
1160    isFLI       -> Cat(1.U, inst.FMT, inst.RS1),
1161    (isPreW || isPreR || isPreI) -> Mux1H(Seq(
1162      isPreW -> LSUOpType.prefetch_w,
1163      isPreR -> LSUOpType.prefetch_r,
1164      isPreI -> LSUOpType.prefetch_i,
1165    )),
1166    (isCboInval && io.fromCSR.special.cboI2F) -> LSUOpType.cbo_flush,
1167  ))
1168
1169  // Don't compress in the same Rob entry when crossing Ftq entry boundary
1170  io.deq.decodedInst.canRobCompress := decodedInst.canRobCompress && !io.enq.ctrlFlow.isLastInFtqEntry
1171
1172  //-------------------------------------------------------------
1173  // Debug Info
1174//  XSDebug("in:  instr=%x pc=%x excepVec=%b crossPageIPFFix=%d\n",
1175//    io.enq.ctrl_flow.instr, io.enq.ctrl_flow.pc, io.enq.ctrl_flow.exceptionVec.asUInt,
1176//    io.enq.ctrl_flow.crossPageIPFFix)
1177//  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",
1178//    io.deq.cf_ctrl.ctrl.srcType(0), io.deq.cf_ctrl.ctrl.srcType(1), io.deq.cf_ctrl.ctrl.srcType(2),
1179//    io.deq.cf_ctrl.ctrl.lsrc(0), io.deq.cf_ctrl.ctrl.lsrc(1), io.deq.cf_ctrl.ctrl.lsrc(2),
1180//    io.deq.cf_ctrl.ctrl.ldest, io.deq.cf_ctrl.ctrl.fuType, io.deq.cf_ctrl.ctrl.fuOpType)
1181//  XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d imm=%x\n",
1182//    io.deq.cf_ctrl.ctrl.rfWen, io.deq.cf_ctrl.ctrl.fpWen, io.deq.cf_ctrl.ctrl.isXSTrap,
1183//    io.deq.cf_ctrl.ctrl.noSpecExec, io.deq.cf_ctrl.ctrl.blockBackward, io.deq.cf_ctrl.ctrl.flushPipe,
1184//    io.deq.cf_ctrl.ctrl.imm)
1185//  XSDebug("out: excepVec=%b\n", io.deq.cf_ctrl.cf.exceptionVec.asUInt)
1186}
1187