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