xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala (revision 491c16ade93d4956fec6dde187943d72bb010bc4)
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 */
42trait 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 */
770
771class DecodeUnitEnqIO(implicit p: Parameters) extends XSBundle {
772  val ctrlFlow = Input(new StaticInst)
773  val vtype = Input(new VType)
774  val vstart = Input(Vl())
775}
776
777class DecodeUnitDeqIO(implicit p: Parameters) extends XSBundle {
778  val decodedInst = Output(new DecodedInst)
779  val isComplex = Output(Bool())
780  val uopInfo = Output(new UopInfo)
781}
782
783class DecodeUnitIO(implicit p: Parameters) extends XSBundle {
784  val enq = new DecodeUnitEnqIO
785  //  val vconfig = Input(UInt(XLEN.W))
786  val deq = new DecodeUnitDeqIO
787  val csrCtrl = Input(new CustomCSRCtrlIO)
788  val fromCSR = Input(new CSRToDecode)
789}
790
791/**
792 * Decode unit that takes in a single CtrlFlow and generates a CfCtrl.
793 */
794class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstants {
795  val io = IO(new DecodeUnitIO)
796
797  val ctrl_flow = io.enq.ctrlFlow // input with RVC Expanded
798
799  private val inst: XSInstBitFields = io.enq.ctrlFlow.instr.asTypeOf(new XSInstBitFields)
800
801  val decode_table: Array[(BitPat, List[BitPat])] = XDecode.table ++
802    FpDecode.table ++
803//    FDivSqrtDecode.table ++
804    BitmanipDecode.table ++
805    ScalarCryptoDecode.table ++
806    XSTrapDecode.table ++
807    CBODecode.table ++
808    SvinvalDecode.table ++
809    HypervisorDecode.table ++
810    VecDecoder.table ++
811    ZicondDecode.table ++
812    ZimopDecode.table ++
813    ZfaDecode.table
814
815  require(decode_table.map(_._2.length == 15).reduce(_ && _), "Decode tables have different column size")
816  // assertion for LUI: only LUI should be assigned `selImm === SelImm.IMM_U && fuType === FuType.alu`
817  val luiMatch = (t: Seq[BitPat]) => t(3).value == FuType.alu.ohid && t.reverse.head.value == SelImm.IMM_U.litValue
818  val luiTable = decode_table.filter(t => luiMatch(t._2)).map(_._1).distinct
819  assert(luiTable.length == 1 && luiTable.head == LUI, "Conflicts: LUI is determined by FuType and SelImm in Dispatch")
820
821  // output
822  val decodedInst: DecodedInst = Wire(new DecodedInst()).decode(ctrl_flow.instr, decode_table)
823
824  val fpDecoder = Module(new FPDecoder)
825  fpDecoder.io.instr := ctrl_flow.instr
826  decodedInst.fpu := fpDecoder.io.fpCtrl
827  decodedInst.fpu.wflags := fpDecoder.io.fpCtrl.wflags || decodedInst.wfflags
828
829  decodedInst.connectStaticInst(io.enq.ctrlFlow)
830
831  decodedInst.uopIdx := 0.U
832  decodedInst.firstUop := true.B
833  decodedInst.lastUop := true.B
834  decodedInst.numUops := 1.U
835  decodedInst.numWB   := 1.U
836
837  val isZimop = (BitPat("b1?00??0111??_?????_100_?????_1110011") === ctrl_flow.instr) ||
838                (BitPat("b1?00??1?????_?????_100_?????_1110011") === ctrl_flow.instr)
839
840  val isMove = BitPat("b000000000000_?????_000_?????_0010011") === ctrl_flow.instr
841  // temp decode zimop as move
842  decodedInst.isMove := (isMove || isZimop) && ctrl_flow.instr(RD_MSB, RD_LSB) =/= 0.U && !io.csrCtrl.singlestep
843
844  // fmadd - b1000011
845  // fmsub - b1000111
846  // fnmsub- b1001011
847  // fnmadd- b1001111
848  private val isFMA = inst.OPCODE === BitPat("b100??11")
849  private val isVppu = FuType.isVppu(decodedInst.fuType)
850  private val isVecOPF = FuType.isVecOPF(decodedInst.fuType)
851
852  // read src1~3 location
853  decodedInst.lsrc(0) := inst.RS1
854  decodedInst.lsrc(1) := inst.RS2
855  // src(2) of fma is fs3, src(2) of vector inst is old vd
856  decodedInst.lsrc(2) := Mux(isFMA, inst.FS3, inst.VD)
857  decodedInst.lsrc(3) := V0_IDX.U
858  decodedInst.lsrc(4) := Vl_IDX.U
859
860  // read dest location
861  decodedInst.ldest := inst.RD
862
863  // init v0Wen vlWen
864  decodedInst.v0Wen := false.B
865  decodedInst.vlWen := false.B
866
867  private val isCboClean = CBO_CLEAN === io.enq.ctrlFlow.instr
868  private val isCboFlush = CBO_FLUSH === io.enq.ctrlFlow.instr
869  private val isCboInval = CBO_INVAL === io.enq.ctrlFlow.instr
870  private val isCboZero  = CBO_ZERO  === io.enq.ctrlFlow.instr
871
872  // Note that rnum of aes64ks1i must be in the range 0x0..0xA. The values 0xB..0xF are reserved.
873  private val isAes64ks1iIllegal =
874    FuType.FuTypeOrR(decodedInst.fuType, FuType.bku) && (decodedInst.fuOpType === BKUOpType.aes64ks1i) && inst.isRnumIllegal
875
876  private val isAmocasQ = FuType.FuTypeOrR(decodedInst.fuType, FuType.mou) && decodedInst.fuOpType === LSUOpType.amocas_q
877  private val isAmocasQIllegal = isAmocasQ && (inst.RD(0) === 1.U || inst.RS2(0) === 1.U)
878
879  private val exceptionII =
880    decodedInst.selImm === SelImm.INVALID_INSTR ||
881    io.fromCSR.illegalInst.sfenceVMA  && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.sfence  ||
882    io.fromCSR.illegalInst.sfencePart && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.nofence ||
883    io.fromCSR.illegalInst.hfenceGVMA && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.hfence_g ||
884    io.fromCSR.illegalInst.hfenceVVMA && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.hfence_v ||
885    io.fromCSR.illegalInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu)   && (LSUOpType.isHlv(decodedInst.fuOpType) || LSUOpType.isHlvx(decodedInst.fuOpType)) ||
886    io.fromCSR.illegalInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.stu)   && LSUOpType.isHsv(decodedInst.fuOpType) ||
887    io.fromCSR.illegalInst.fsIsOff    && (
888      FuType.FuTypeOrR(decodedInst.fuType, FuType.fpOP ++ Seq(FuType.f2v)) ||
889      (FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu) && (decodedInst.fuOpType === LSUOpType.lh || decodedInst.fuOpType === LSUOpType.lw || decodedInst.fuOpType === LSUOpType.ld) ||
890      FuType.FuTypeOrR(decodedInst.fuType, FuType.stu) && (decodedInst.fuOpType === LSUOpType.sh || decodedInst.fuOpType === LSUOpType.sw || decodedInst.fuOpType === LSUOpType.sd)) && decodedInst.instr(2) ||
891      inst.isOPFVF || inst.isOPFVV
892    ) ||
893    io.fromCSR.illegalInst.vsIsOff    && FuType.FuTypeOrR(decodedInst.fuType, FuType.vecAll) ||
894    io.fromCSR.illegalInst.wfi        && FuType.FuTypeOrR(decodedInst.fuType, FuType.csr)   && CSROpType.isWfi(decodedInst.fuOpType) ||
895    (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)) ||
896    (decodedInst.needFrm.vectorNeedFrm || FuType.isVectorNeedFrm(decodedInst.fuType)) && io.fromCSR.illegalInst.frm ||
897    io.fromCSR.illegalInst.cboZ       && isCboZero ||
898    io.fromCSR.illegalInst.cboCF      && (isCboClean || isCboFlush) ||
899    io.fromCSR.illegalInst.cboI       && isCboInval ||
900    isAes64ks1iIllegal ||
901    isAmocasQIllegal
902
903  private val exceptionVI =
904    io.fromCSR.virtualInst.sfenceVMA  && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.sfence ||
905    io.fromCSR.virtualInst.sfencePart && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.nofence ||
906    io.fromCSR.virtualInst.hfence     && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && (decodedInst.fuOpType === FenceOpType.hfence_g || decodedInst.fuOpType === FenceOpType.hfence_v) ||
907    io.fromCSR.virtualInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu)   && (LSUOpType.isHlv(decodedInst.fuOpType) || LSUOpType.isHlvx(decodedInst.fuOpType)) ||
908    io.fromCSR.virtualInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.stu)   && LSUOpType.isHsv(decodedInst.fuOpType) ||
909    io.fromCSR.virtualInst.wfi        && FuType.FuTypeOrR(decodedInst.fuType, FuType.csr)   && CSROpType.isWfi(decodedInst.fuOpType) ||
910    io.fromCSR.virtualInst.cboZ       && isCboZero ||
911    io.fromCSR.virtualInst.cboCF      && (isCboClean || isCboFlush) ||
912    io.fromCSR.virtualInst.cboI       && isCboInval
913
914
915  decodedInst.exceptionVec(illegalInstr) := exceptionII || io.enq.ctrlFlow.exceptionVec(EX_II)
916  decodedInst.exceptionVec(virtualInstr) := exceptionVI
917
918  //update exceptionVec: from frontend trigger's breakpoint exception. To reduce 1 bit of overhead in ibuffer entry.
919  decodedInst.exceptionVec(breakPoint) := TriggerAction.isExp(ctrl_flow.trigger)
920
921  decodedInst.imm := LookupTree(decodedInst.selImm, ImmUnion.immSelMap.map(
922    x => {
923      val minBits = x._2.minBitsFromInstr(ctrl_flow.instr)
924      require(minBits.getWidth == x._2.len)
925      x._1 -> minBits
926    }
927  ))
928
929  private val isLs = FuType.isLoadStore(decodedInst.fuType)
930  private val isVls = inst.isVecStore || inst.isVecLoad
931  private val isStore = FuType.isStore(decodedInst.fuType)
932  private val isAMO = FuType.isAMO(decodedInst.fuType)
933  private val isVStore = FuType.isVStore(decodedInst.fuType)
934  private val isBranch = !decodedInst.preDecodeInfo.notCFI || FuType.isJump(decodedInst.fuType)
935
936  decodedInst.commitType := Cat(isLs | isVls, (isStore && !isAMO) | isVStore | isBranch)
937
938  decodedInst.isVset := FuType.isVset(decodedInst.fuType)
939
940  private val needReverseInsts = Seq(VRSUB_VI, VRSUB_VX, VFRDIV_VF, VFRSUB_VF, VFMV_F_S)
941  private val vextInsts = Seq(VZEXT_VF2, VZEXT_VF4, VZEXT_VF8, VSEXT_VF2, VSEXT_VF4, VSEXT_VF8)
942  private val narrowInsts = Seq(
943    VNSRA_WV, VNSRA_WX, VNSRA_WI, VNSRL_WV, VNSRL_WX, VNSRL_WI,
944    VNCLIP_WV, VNCLIP_WX, VNCLIP_WI, VNCLIPU_WV, VNCLIPU_WX, VNCLIPU_WI,
945  )
946  private val maskDstInsts = Seq(
947    VMADC_VV, VMADC_VX,  VMADC_VI,  VMADC_VVM, VMADC_VXM, VMADC_VIM,
948    VMSBC_VV, VMSBC_VX,  VMSBC_VVM, VMSBC_VXM,
949    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
950    VMSEQ_VV, VMSEQ_VX, VMSEQ_VI, VMSNE_VV, VMSNE_VX, VMSNE_VI,
951    VMSLE_VV, VMSLE_VX, VMSLE_VI, VMSLEU_VV, VMSLEU_VX, VMSLEU_VI,
952    VMSLT_VV, VMSLT_VX, VMSLTU_VV, VMSLTU_VX,
953    VMSGT_VX, VMSGT_VI, VMSGTU_VX, VMSGTU_VI,
954    VMFEQ_VV, VMFEQ_VF, VMFNE_VV, VMFNE_VF, VMFLT_VV, VMFLT_VF, VMFLE_VV, VMFLE_VF, VMFGT_VF, VMFGE_VF,
955  )
956  private val maskOpInsts = Seq(
957    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
958  )
959  private val vmaInsts = Seq(
960    VMACC_VV, VMACC_VX, VNMSAC_VV, VNMSAC_VX, VMADD_VV, VMADD_VX, VNMSUB_VV, VNMSUB_VX,
961    VWMACCU_VV, VWMACCU_VX, VWMACC_VV, VWMACC_VX, VWMACCSU_VV, VWMACCSU_VX, VWMACCUS_VX,
962  )
963  private val wfflagsInsts = Seq(
964    // opfff
965    FADD_S, FSUB_S, FADD_D, FSUB_D, FADD_H, FSUB_H,
966    FEQ_S, FLT_S, FLE_S, FEQ_D, FLT_D, FLE_D, FEQ_H, FLT_H, FLE_H,
967    FMIN_S, FMAX_S, FMIN_D, FMAX_D, FMIN_H, FMAX_H,
968    FMUL_S, FMUL_D, FMUL_H,
969    FDIV_S, FDIV_D, FSQRT_S, FSQRT_D, FDIV_H, FSQRT_H,
970    FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D, FMADD_H, FMSUB_H, FNMADD_H, FNMSUB_H,
971    FSGNJ_S, FSGNJN_S, FSGNJX_S, FSGNJ_H, FSGNJN_H, FSGNJX_H,
972    // opfvv
973    VFADD_VV, VFSUB_VV, VFWADD_VV, VFWSUB_VV, VFWADD_WV, VFWSUB_WV,
974    VFMUL_VV, VFDIV_VV, VFWMUL_VV,
975    VFMACC_VV, VFNMACC_VV, VFMSAC_VV, VFNMSAC_VV, VFMADD_VV, VFNMADD_VV, VFMSUB_VV, VFNMSUB_VV,
976    VFWMACC_VV, VFWNMACC_VV, VFWMSAC_VV, VFWNMSAC_VV,
977    VFSQRT_V,
978    VFMIN_VV, VFMAX_VV,
979    VMFEQ_VV, VMFNE_VV, VMFLT_VV, VMFLE_VV,
980    VFSGNJ_VV, VFSGNJN_VV, VFSGNJX_VV,
981    // opfvf
982    VFADD_VF, VFSUB_VF, VFRSUB_VF, VFWADD_VF, VFWSUB_VF, VFWADD_WF, VFWSUB_WF,
983    VFMUL_VF, VFDIV_VF, VFRDIV_VF, VFWMUL_VF,
984    VFMACC_VF, VFNMACC_VF, VFMSAC_VF, VFNMSAC_VF, VFMADD_VF, VFNMADD_VF, VFMSUB_VF, VFNMSUB_VF,
985    VFWMACC_VF, VFWNMACC_VF, VFWMSAC_VF, VFWNMSAC_VF,
986    VFMIN_VF, VFMAX_VF,
987    VMFEQ_VF, VMFNE_VF, VMFLT_VF, VMFLE_VF, VMFGT_VF, VMFGE_VF,
988    VFSGNJ_VF, VFSGNJN_VF, VFSGNJX_VF,
989    // vfred
990    VFREDOSUM_VS, VFREDUSUM_VS, VFREDMAX_VS, VFREDMIN_VS, VFWREDOSUM_VS, VFWREDUSUM_VS,
991    // fcvt & vfcvt
992    FCVT_S_W, FCVT_S_WU, FCVT_S_L, FCVT_S_LU,
993    FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S,
994    FCVT_D_W, FCVT_D_WU, FCVT_D_L, FCVT_D_LU,
995    FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S,
996    FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H,
997    FCVT_H_W, FCVT_H_WU, FCVT_H_L, FCVT_H_LU,
998    FCVT_W_H, FCVT_WU_H, FCVT_L_H, FCVT_LU_H,
999    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,
1000    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,
1001    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,
1002    VFNCVT_ROD_F_F_W, VFRSQRT7_V, VFREC7_V,
1003    // zfa
1004    FLEQ_H, FLEQ_S, FLEQ_D, FLTQ_H, FLTQ_S, FLTQ_D,
1005    FMINM_H, FMINM_S, FMINM_D, FMAXM_H, FMAXM_S, FMAXM_D,
1006    FROUND_H, FROUND_S, FROUND_D, FROUNDNX_H, FROUNDNX_S, FROUNDNX_D,
1007    FCVTMOD_W_D,
1008  )
1009
1010  private val scalaNeedFrmInsts = Seq(
1011    FADD_S, FSUB_S, FADD_D, FSUB_D, FADD_H, FSUB_H,
1012    FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S,
1013    FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S,
1014    FCVT_W_H, FCVT_WU_H, FCVT_L_H, FCVT_LU_H,
1015    FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H,
1016    FROUND_H, FROUND_S, FROUND_D, FROUNDNX_H, FROUNDNX_S, FROUNDNX_D,
1017  )
1018
1019  private val vectorNeedFrmInsts = Seq (
1020    VFSLIDE1UP_VF, VFSLIDE1DOWN_VF,
1021  )
1022
1023  decodedInst.wfflags := wfflagsInsts.map(_ === inst.ALL).reduce(_ || _)
1024  decodedInst.needFrm.scalaNeedFrm := scalaNeedFrmInsts.map(_ === inst.ALL).reduce(_ || _)
1025  decodedInst.needFrm.vectorNeedFrm := vectorNeedFrmInsts.map(_ === inst.ALL).reduce(_ || _)
1026  decodedInst.vpu := 0.U.asTypeOf(decodedInst.vpu) // Todo: Connect vpu decoder
1027  decodedInst.vpu.vill := io.enq.vtype.illegal
1028  decodedInst.vpu.vma := io.enq.vtype.vma
1029  decodedInst.vpu.vta := io.enq.vtype.vta
1030  decodedInst.vpu.vsew := io.enq.vtype.vsew
1031  decodedInst.vpu.vlmul := io.enq.vtype.vlmul
1032  decodedInst.vpu.vm := inst.VM
1033  decodedInst.vpu.nf := inst.NF
1034  decodedInst.vpu.veew := inst.WIDTH
1035  decodedInst.vpu.isReverse := needReverseInsts.map(_ === inst.ALL).reduce(_ || _)
1036  decodedInst.vpu.isExt := vextInsts.map(_ === inst.ALL).reduce(_ || _)
1037  val isNarrow = narrowInsts.map(_ === inst.ALL).reduce(_ || _)
1038  val isDstMask = maskDstInsts.map(_ === inst.ALL).reduce(_ || _)
1039  val isOpMask = maskOpInsts.map(_ === inst.ALL).reduce(_ || _)
1040  val isVload = FuType.isVLoad(decodedInst.fuType)
1041  val isVlx = isVload && (decodedInst.fuOpType === VlduType.vloxe || decodedInst.fuOpType === VlduType.vluxe)
1042  val isVle = isVload && (decodedInst.fuOpType === VlduType.vle || decodedInst.fuOpType === VlduType.vleff || decodedInst.fuOpType === VlduType.vlse)
1043  val isVlm = isVload && (decodedInst.fuOpType === VlduType.vlm)
1044  val isFof = isVload && (decodedInst.fuOpType === VlduType.vleff)
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  val vstartIsNotZero = io.enq.vstart =/= 0.U
1049  decodedInst.vpu.isNarrow := isNarrow
1050  decodedInst.vpu.isDstMask := isDstMask
1051  decodedInst.vpu.isOpMask := isOpMask
1052  decodedInst.vpu.isDependOldVd := isVppu || isVecOPF || isVStore || (isDstMask && !isOpMask) || isNarrow || isVlx || isVma || isFof || vstartIsNotZero
1053  decodedInst.vpu.isWritePartVd := isWritePartVd || isVlm || isVle && emulIsFrac
1054  decodedInst.vpu.vstart := io.enq.vstart
1055  decodedInst.vpu.isVleff := isFof && inst.NF === 0.U
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, SrcType.vp, SrcType.DC) // mask src
1065  decodedInst.srcType(4) := SrcType.vp // vconfig
1066
1067  val uopInfoGen = Module(new UopInfoGen)
1068  uopInfoGen.io.in.preInfo.isVecArith := inst.isVecArith
1069  uopInfoGen.io.in.preInfo.isVecMem := inst.isVecStore || inst.isVecLoad
1070  uopInfoGen.io.in.preInfo.isAmoCAS := inst.isAMOCAS
1071
1072  uopInfoGen.io.in.preInfo.typeOfSplit := decodedInst.uopSplitType
1073  uopInfoGen.io.in.preInfo.vsew := decodedInst.vpu.vsew
1074  uopInfoGen.io.in.preInfo.vlmul := decodedInst.vpu.vlmul
1075  uopInfoGen.io.in.preInfo.vwidth := inst.RM
1076  uopInfoGen.io.in.preInfo.vmvn := inst.IMM5_OPIVI(2, 0)
1077  uopInfoGen.io.in.preInfo.nf := inst.NF
1078  uopInfoGen.io.in.preInfo.isVlsr := decodedInst.fuOpType === VlduType.vlr || decodedInst.fuOpType === VstuType.vsr
1079  uopInfoGen.io.in.preInfo.isVlsm := decodedInst.fuOpType === VlduType.vlm || decodedInst.fuOpType === VstuType.vsm
1080  io.deq.isComplex := uopInfoGen.io.out.isComplex
1081  io.deq.uopInfo.numOfUop := uopInfoGen.io.out.uopInfo.numOfUop
1082  io.deq.uopInfo.numOfWB := uopInfoGen.io.out.uopInfo.numOfWB
1083  io.deq.uopInfo.lmul := uopInfoGen.io.out.uopInfo.lmul
1084
1085  val isCsr = inst.OPCODE5Bit === OPCODE5Bit.SYSTEM && inst.FUNCT3(1, 0) =/= 0.U
1086  val isCsrr = isCsr && inst.FUNCT3 === BitPat("b?1?") && inst.RS1 === 0.U
1087  val isCsrw = isCsr && inst.FUNCT3 === BitPat("b?01") && inst.RD  === 0.U
1088  dontTouch(isCsrr)
1089  dontTouch(isCsrw)
1090
1091  // for csrr vl instruction, convert to vsetvl
1092  val isCsrrVlenb = isCsrr && inst.CSRIDX === CSRs.vlenb.U
1093  val isCsrrVl    = isCsrr && inst.CSRIDX === CSRs.vl.U
1094
1095  // decode for SoftPrefetch instructions (prefetch.w / prefetch.r / prefetch.i)
1096  val isSoftPrefetch = inst.OPCODE === BitPat("b0010011") && inst.FUNCT3 === BitPat("b110") && inst.RD === 0.U
1097  val isPreW = isSoftPrefetch && inst.RS2 === 3.U(5.W)
1098  val isPreR = isSoftPrefetch && inst.RS2 === 1.U(5.W)
1099  val isPreI = isSoftPrefetch && inst.RS2 === 0.U(5.W)
1100
1101  // for fli.s|fli.d instruction
1102  val isFLI = inst.FUNCT7 === BitPat("b11110??") && inst.RS2 === 1.U && inst.RM === 0.U && inst.OPCODE5Bit === OPCODE5Bit.OP_FP
1103
1104  when (isCsrrVl) {
1105    // convert to vsetvl instruction
1106    decodedInst.srcType(0) := SrcType.no
1107    decodedInst.srcType(1) := SrcType.no
1108    decodedInst.srcType(2) := SrcType.no
1109    decodedInst.srcType(3) := SrcType.no
1110    decodedInst.srcType(4) := SrcType.vp
1111    decodedInst.lsrc(4)    := Vl_IDX.U
1112    decodedInst.waitForward   := false.B
1113    decodedInst.blockBackward := false.B
1114    decodedInst.exceptionVec(illegalInstr) := io.fromCSR.illegalInst.vsIsOff
1115  }.elsewhen (isCsrrVlenb) {
1116    // convert to addi instruction
1117    decodedInst.srcType(0) := SrcType.reg
1118    decodedInst.srcType(1) := SrcType.imm
1119    decodedInst.srcType(2) := SrcType.no
1120    decodedInst.srcType(3) := SrcType.no
1121    decodedInst.srcType(4) := SrcType.no
1122    decodedInst.selImm := SelImm.IMM_I
1123    decodedInst.waitForward := false.B
1124    decodedInst.blockBackward := false.B
1125    decodedInst.canRobCompress := true.B
1126    decodedInst.exceptionVec(illegalInstr) := io.fromCSR.illegalInst.vsIsOff
1127  }.elsewhen (isPreW || isPreR || isPreI) {
1128    decodedInst.selImm := SelImm.IMM_S
1129    decodedInst.fuType := FuType.ldu.U
1130    decodedInst.canRobCompress := false.B
1131  }.elsewhen (isZimop) {
1132    // set srcType for zimop
1133    decodedInst.srcType(0) := SrcType.reg
1134    decodedInst.srcType(1) := SrcType.imm
1135    // use x0 as src1
1136    decodedInst.lsrc(0) := 0.U
1137  }
1138
1139  io.deq.decodedInst := decodedInst
1140  io.deq.decodedInst.rfWen := (decodedInst.ldest =/= 0.U) && decodedInst.rfWen
1141  io.deq.decodedInst.fuType := Mux1H(Seq(
1142    // keep condition
1143    (!FuType.FuTypeOrR(decodedInst.fuType, FuType.vldu, FuType.vstu) && !isCsrrVl && !isCsrrVlenb) -> decodedInst.fuType,
1144    (isCsrrVl) -> FuType.vsetfwf.U,
1145    (isCsrrVlenb) -> FuType.alu.U,
1146
1147    // change vlsu to vseglsu when NF =/= 0.U
1148    ( 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,
1149    // MOP === b00 && SUMOP === b01000: unit-stride whole register store
1150    // MOP =/= b00                    : strided and indexed store
1151    ( 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,
1152    // MOP === b00 && LUMOP === b01000: unit-stride whole register load
1153    // MOP =/= b00                    : strided and indexed load
1154    ( 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,
1155  ))
1156  io.deq.decodedInst.imm := MuxCase(decodedInst.imm, Seq(
1157    isCsrrVlenb -> (VLEN / 8).U,
1158    isZimop     -> 0.U,
1159  ))
1160
1161  io.deq.decodedInst.fuOpType := MuxCase(decodedInst.fuOpType, Seq(
1162    isCsrrVl    -> VSETOpType.csrrvl,
1163    isCsrrVlenb -> ALUOpType.add,
1164    isFLI       -> Cat(1.U, inst.FMT, inst.RS1),
1165    (isPreW || isPreR || isPreI) -> Mux1H(Seq(
1166      isPreW -> LSUOpType.prefetch_w,
1167      isPreR -> LSUOpType.prefetch_r,
1168      isPreI -> LSUOpType.prefetch_i,
1169    )),
1170    (isCboInval && io.fromCSR.special.cboI2F) -> LSUOpType.cbo_flush,
1171  ))
1172
1173  // Don't compress in the same Rob entry when crossing Ftq entry boundary
1174  io.deq.decodedInst.canRobCompress := decodedInst.canRobCompress && !io.enq.ctrlFlow.isLastInFtqEntry
1175
1176  //-------------------------------------------------------------
1177  // Debug Info
1178//  XSDebug("in:  instr=%x pc=%x excepVec=%b crossPageIPFFix=%d\n",
1179//    io.enq.ctrl_flow.instr, io.enq.ctrl_flow.pc, io.enq.ctrl_flow.exceptionVec.asUInt,
1180//    io.enq.ctrl_flow.crossPageIPFFix)
1181//  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",
1182//    io.deq.cf_ctrl.ctrl.srcType(0), io.deq.cf_ctrl.ctrl.srcType(1), io.deq.cf_ctrl.ctrl.srcType(2),
1183//    io.deq.cf_ctrl.ctrl.lsrc(0), io.deq.cf_ctrl.ctrl.lsrc(1), io.deq.cf_ctrl.ctrl.lsrc(2),
1184//    io.deq.cf_ctrl.ctrl.ldest, io.deq.cf_ctrl.ctrl.fuType, io.deq.cf_ctrl.ctrl.fuOpType)
1185//  XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d imm=%x\n",
1186//    io.deq.cf_ctrl.ctrl.rfWen, io.deq.cf_ctrl.ctrl.fpWen, io.deq.cf_ctrl.ctrl.isXSTrap,
1187//    io.deq.cf_ctrl.ctrl.noSpecExec, io.deq.cf_ctrl.ctrl.blockBackward, io.deq.cf_ctrl.ctrl.flushPipe,
1188//    io.deq.cf_ctrl.ctrl.imm)
1189//  XSDebug("out: excepVec=%b\n", io.deq.cf_ctrl.cf.exceptionVec.asUInt)
1190}
1191