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