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