xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala (revision 939a787932102e17cb14773366a1dc3579827eb3)
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
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 , uopSplitType = UopSplitType.SCA_SIM, 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  }
685//  val vconfig = Input(UInt(XLEN.W))
686  val deq = new DecodeUnitDeqIO
687  val csrCtrl = Input(new CustomCSRCtrlIO)
688}
689
690/**
691 * Decode unit that takes in a single CtrlFlow and generates a CfCtrl.
692 */
693class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstants {
694  val io = IO(new DecodeUnitIO)
695
696  val ctrl_flow = io.enq.ctrlFlow // input with RVC Expanded
697
698  private val inst: XSInstBitFields = io.enq.ctrlFlow.instr.asTypeOf(new XSInstBitFields)
699
700  val decode_table: Array[(BitPat, List[BitPat])] = XDecode.table ++
701    FpDecode.table ++
702//    FDivSqrtDecode.table ++
703    BitmanipDecode.table ++
704    ScalarCryptoDecode.table ++
705    XSTrapDecode.table ++
706    CBODecode.table ++
707    SvinvalDecode.table ++
708    HypervisorDecode.table ++
709    VecDecoder.table ++
710    ZicondDecode.table
711
712  require(decode_table.map(_._2.length == 15).reduce(_ && _), "Decode tables have different column size")
713  // assertion for LUI: only LUI should be assigned `selImm === SelImm.IMM_U && fuType === FuType.alu`
714  val luiMatch = (t: Seq[BitPat]) => t(3).value == FuType.alu.ohid && t.reverse.head.value == SelImm.IMM_U.litValue
715  val luiTable = decode_table.filter(t => luiMatch(t._2)).map(_._1).distinct
716  assert(luiTable.length == 1 && luiTable.head == LUI, "Conflicts: LUI is determined by FuType and SelImm in Dispatch")
717
718  // output
719  val decodedInst: DecodedInst = Wire(new DecodedInst()).decode(ctrl_flow.instr, decode_table)
720
721  val fpDecoder = Module(new FPDecoder)
722  fpDecoder.io.instr := ctrl_flow.instr
723  decodedInst.fpu := fpDecoder.io.fpCtrl
724
725  decodedInst.connectStaticInst(io.enq.ctrlFlow)
726
727  decodedInst.uopIdx := 0.U
728  decodedInst.firstUop := true.B
729  decodedInst.lastUop := true.B
730  decodedInst.numUops := 1.U
731  decodedInst.numWB   := 1.U
732
733  val isMove = BitPat("b000000000000_?????_000_?????_0010011") === ctrl_flow.instr
734  decodedInst.isMove := isMove && ctrl_flow.instr(RD_MSB, RD_LSB) =/= 0.U && !io.csrCtrl.singlestep
735
736  // fmadd - b1000011
737  // fmsub - b1000111
738  // fnmsub- b1001011
739  // fnmadd- b1001111
740  private val isFMA = inst.OPCODE === BitPat("b100??11")
741  private val isVppu = FuType.isVppu(decodedInst.fuType)
742  private val isVecOPF = FuType.isVecOPF(decodedInst.fuType)
743
744  // read src1~3 location
745  decodedInst.lsrc(0) := inst.RS1
746  decodedInst.lsrc(1) := inst.RS2
747  // src(2) of fma is fs3, src(2) of vector inst is old vd
748  decodedInst.lsrc(2) := Mux(isFMA, inst.FS3, inst.VD)
749  decodedInst.lsrc(3) := V0_IDX.U
750  decodedInst.lsrc(4) := Vl_IDX.U
751
752  // read dest location
753  decodedInst.ldest := inst.RD
754
755  // init v0Wen vlWen
756  decodedInst.v0Wen := false.B
757  decodedInst.vlWen := false.B
758
759  // fill in exception vector
760  val vecException = Module(new VecExceptionGen)
761  vecException.io.inst := io.enq.ctrlFlow.instr
762  vecException.io.decodedInst := decodedInst
763  vecException.io.vtype := decodedInst.vpu.vtype
764  decodedInst.exceptionVec(illegalInstr) := decodedInst.selImm === SelImm.INVALID_INSTR || vecException.io.illegalInst
765
766  when (!io.csrCtrl.svinval_enable) {
767    val base_ii = decodedInst.selImm === SelImm.INVALID_INSTR || vecException.io.illegalInst
768    val sinval = BitPat("b0001011_?????_?????_000_00000_1110011") === ctrl_flow.instr
769    val w_inval = BitPat("b0001100_00000_00000_000_00000_1110011") === ctrl_flow.instr
770    val inval_ir = BitPat("b0001100_00001_00000_000_00000_1110011") === ctrl_flow.instr
771    val hinval_gvma = HINVAL_GVMA === ctrl_flow.instr
772    val hinval_vvma = HINVAL_VVMA === ctrl_flow.instr
773    val svinval_ii = sinval || w_inval || inval_ir || hinval_gvma || hinval_vvma
774    decodedInst.exceptionVec(illegalInstr) := base_ii || svinval_ii
775    decodedInst.flushPipe := false.B
776  }
777
778  when(io.csrCtrl.virtMode){
779    // Todo: optimize EX_VI decode
780    // vs/vu attempting to exec hyperinst will raise virtual instruction
781    decodedInst.exceptionVec(virtualInstr) := ctrl_flow.instr === HLV_B || ctrl_flow.instr === HLV_BU ||
782      ctrl_flow.instr === HLV_H   || ctrl_flow.instr === HLV_HU ||
783      ctrl_flow.instr === HLVX_HU || ctrl_flow.instr === HLV_W  ||
784      ctrl_flow.instr === HLVX_WU || ctrl_flow.instr === HLV_WU ||
785      ctrl_flow.instr === HLV_D   || ctrl_flow.instr === HSV_B  ||
786      ctrl_flow.instr === HSV_H   || ctrl_flow.instr === HSV_W  ||
787      ctrl_flow.instr === HSV_D   || ctrl_flow.instr === HFENCE_VVMA ||
788      ctrl_flow.instr === HFENCE_GVMA || ctrl_flow.instr === HINVAL_GVMA ||
789      ctrl_flow.instr === HINVAL_VVMA
790  }
791
792  decodedInst.imm := LookupTree(decodedInst.selImm, ImmUnion.immSelMap.map(
793    x => {
794      val minBits = x._2.minBitsFromInstr(ctrl_flow.instr)
795      require(minBits.getWidth == x._2.len)
796      x._1 -> minBits
797    }
798  ))
799
800  private val isLs = FuType.isLoadStore(decodedInst.fuType)
801  private val isVls = FuType.isVls(decodedInst.fuType)
802  private val isStore = FuType.isStore(decodedInst.fuType)
803  private val isAMO = FuType.isAMO(decodedInst.fuType)
804  private val isVStore = FuType.isVStore(decodedInst.fuType)
805  private val isBranch = !decodedInst.preDecodeInfo.notCFI || FuType.isJump(decodedInst.fuType)
806
807  decodedInst.commitType := Cat(isLs | isVls, (isStore && !isAMO) | isVStore | isBranch)
808
809  decodedInst.isVset := FuType.isVset(decodedInst.fuType)
810
811  private val needReverseInsts = Seq(VRSUB_VI, VRSUB_VX, VFRDIV_VF, VFRSUB_VF, VFMV_F_S)
812  private val vextInsts = Seq(VZEXT_VF2, VZEXT_VF4, VZEXT_VF8, VSEXT_VF2, VSEXT_VF4, VSEXT_VF8)
813  private val narrowInsts = Seq(
814    VNSRA_WV, VNSRA_WX, VNSRA_WI, VNSRL_WV, VNSRL_WX, VNSRL_WI,
815    VNCLIP_WV, VNCLIP_WX, VNCLIP_WI, VNCLIPU_WV, VNCLIPU_WX, VNCLIPU_WI,
816  )
817  private val maskDstInsts = Seq(
818    VMADC_VV, VMADC_VX,  VMADC_VI,  VMADC_VVM, VMADC_VXM, VMADC_VIM,
819    VMSBC_VV, VMSBC_VX,  VMSBC_VVM, VMSBC_VXM,
820    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
821    VMSEQ_VV, VMSEQ_VX, VMSEQ_VI, VMSNE_VV, VMSNE_VX, VMSNE_VI,
822    VMSLE_VV, VMSLE_VX, VMSLE_VI, VMSLEU_VV, VMSLEU_VX, VMSLEU_VI,
823    VMSLT_VV, VMSLT_VX, VMSLTU_VV, VMSLTU_VX,
824    VMSGT_VX, VMSGT_VI, VMSGTU_VX, VMSGTU_VI,
825    VMFEQ_VV, VMFEQ_VF, VMFNE_VV, VMFNE_VF, VMFLT_VV, VMFLT_VF, VMFLE_VV, VMFLE_VF, VMFGT_VF, VMFGE_VF,
826  )
827  private val maskOpInsts = Seq(
828    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
829  )
830  private val vmaInsts = Seq(
831    VMACC_VV, VMACC_VX, VNMSAC_VV, VNMSAC_VX, VMADD_VV, VMADD_VX, VNMSUB_VV, VNMSUB_VX,
832    VWMACCU_VV, VWMACCU_VX, VWMACC_VV, VWMACC_VX, VWMACCSU_VV, VWMACCSU_VX, VWMACCUS_VX,
833  )
834  private val wfflagsInsts = Seq(
835    // opfff
836    FADD_S, FSUB_S, FADD_D, FSUB_D,
837    FEQ_S, FLT_S, FLE_S, FEQ_D, FLT_D, FLE_D,
838    FMIN_S, FMAX_S, FMIN_D, FMAX_D,
839    FMUL_S, FMUL_D,
840    FDIV_S, FDIV_D, FSQRT_S, FSQRT_D,
841    FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D,
842    FSGNJ_S, FSGNJN_S, FSGNJX_S,
843    // opfvv
844    VFADD_VV, VFSUB_VV, VFWADD_VV, VFWSUB_VV, VFWADD_WV, VFWSUB_WV,
845    VFMUL_VV, VFDIV_VV, VFWMUL_VV,
846    VFMACC_VV, VFNMACC_VV, VFMSAC_VV, VFNMSAC_VV, VFMADD_VV, VFNMADD_VV, VFMSUB_VV, VFNMSUB_VV,
847    VFWMACC_VV, VFWNMACC_VV, VFWMSAC_VV, VFWNMSAC_VV,
848    VFSQRT_V,
849    VFMIN_VV, VFMAX_VV,
850    VMFEQ_VV, VMFNE_VV, VMFLT_VV, VMFLE_VV,
851    VFSGNJ_VV, VFSGNJN_VV, VFSGNJX_VV,
852    // opfvf
853    VFADD_VF, VFSUB_VF, VFRSUB_VF, VFWADD_VF, VFWSUB_VF, VFWADD_WF, VFWSUB_WF,
854    VFMUL_VF, VFDIV_VF, VFRDIV_VF, VFWMUL_VF,
855    VFMACC_VF, VFNMACC_VF, VFMSAC_VF, VFNMSAC_VF, VFMADD_VF, VFNMADD_VF, VFMSUB_VF, VFNMSUB_VF,
856    VFWMACC_VF, VFWNMACC_VF, VFWMSAC_VF, VFWNMSAC_VF,
857    VFMIN_VF, VFMAX_VF,
858    VMFEQ_VF, VMFNE_VF, VMFLT_VF, VMFLE_VF, VMFGT_VF, VMFGE_VF,
859    VFSGNJ_VF, VFSGNJN_VF, VFSGNJX_VF,
860    // vfred
861    VFREDOSUM_VS, VFREDUSUM_VS, VFREDMAX_VS, VFREDMIN_VS, VFWREDOSUM_VS, VFWREDUSUM_VS,
862    // fcvt & vfcvt
863    FCVT_S_W, FCVT_S_WU, FCVT_S_L, FCVT_S_LU,
864    FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S,
865    FCVT_D_W, FCVT_D_WU, FCVT_D_L, FCVT_D_LU,
866    FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S,
867    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,
868    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,
869    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,
870    VFNCVT_ROD_F_F_W, VFRSQRT7_V, VFREC7_V,
871  )
872  decodedInst.wfflags := wfflagsInsts.map(_ === inst.ALL).reduce(_ || _)
873  val fpToVecDecoder = Module(new FPToVecDecoder())
874  fpToVecDecoder.io.instr := inst.asUInt
875  val isFpToVecInst = fpToVecDecoder.io.vpuCtrl.fpu.isFpToVecInst
876  decodedInst.vpu := 0.U.asTypeOf(decodedInst.vpu) // Todo: Connect vpu decoder
877  when(isFpToVecInst){
878    decodedInst.vpu := fpToVecDecoder.io.vpuCtrl
879  }.otherwise{
880    decodedInst.vpu.vill := io.enq.vtype.illegal
881    decodedInst.vpu.vma := io.enq.vtype.vma
882    decodedInst.vpu.vta := io.enq.vtype.vta
883    decodedInst.vpu.vsew := io.enq.vtype.vsew
884    decodedInst.vpu.vlmul := io.enq.vtype.vlmul
885    decodedInst.vpu.vm := inst.VM
886    decodedInst.vpu.nf := inst.NF
887    decodedInst.vpu.veew := inst.WIDTH
888    decodedInst.vpu.isReverse := needReverseInsts.map(_ === inst.ALL).reduce(_ || _)
889    decodedInst.vpu.isExt := vextInsts.map(_ === inst.ALL).reduce(_ || _)
890    val isNarrow = narrowInsts.map(_ === inst.ALL).reduce(_ || _)
891    val isDstMask = maskDstInsts.map(_ === inst.ALL).reduce(_ || _)
892    val isOpMask = maskOpInsts.map(_ === inst.ALL).reduce(_ || _)
893    val isVlx = decodedInst.fuOpType === VlduType.vloxe || decodedInst.fuOpType === VlduType.vluxe
894    val isWritePartVd = decodedInst.uopSplitType === UopSplitType.VEC_VRED || decodedInst.uopSplitType === UopSplitType.VEC_0XV
895    val isVma = vmaInsts.map(_ === inst.ALL).reduce(_ || _)
896    decodedInst.vpu.isNarrow := isNarrow
897    decodedInst.vpu.isDstMask := isDstMask
898    decodedInst.vpu.isOpMask := isOpMask
899    decodedInst.vpu.isDependOldvd := isVppu || isVecOPF || isVStore || (isDstMask && !isOpMask) || isNarrow || isVlx || isVma
900    decodedInst.vpu.isWritePartVd := isWritePartVd
901  }
902
903  decodedInst.vlsInstr := isVls
904
905  decodedInst.srcType(3) := Mux(inst.VM === 0.U && !isFpToVecInst, SrcType.vp, SrcType.DC) // mask src
906  decodedInst.srcType(4) := Mux(!isFpToVecInst, SrcType.vp, SrcType.DC) // vconfig
907
908  val uopInfoGen = Module(new UopInfoGen)
909  uopInfoGen.io.in.preInfo.typeOfSplit := decodedInst.uopSplitType
910  uopInfoGen.io.in.preInfo.vsew := decodedInst.vpu.vsew
911  uopInfoGen.io.in.preInfo.vlmul := decodedInst.vpu.vlmul
912  uopInfoGen.io.in.preInfo.vwidth := inst.RM
913  uopInfoGen.io.in.preInfo.vmvn := inst.IMM5_OPIVI(2, 0)
914  uopInfoGen.io.in.preInfo.nf := inst.NF
915  uopInfoGen.io.in.preInfo.isVlsr := decodedInst.fuOpType === VlduType.vlr || decodedInst.fuOpType === VstuType.vsr
916  uopInfoGen.io.in.preInfo.isVlsm := decodedInst.fuOpType === VlduType.vlm || decodedInst.fuOpType === VstuType.vsm
917  io.deq.isComplex := uopInfoGen.io.out.isComplex
918  io.deq.uopInfo.numOfUop := uopInfoGen.io.out.uopInfo.numOfUop
919  io.deq.uopInfo.numOfWB := uopInfoGen.io.out.uopInfo.numOfWB
920  io.deq.uopInfo.lmul := uopInfoGen.io.out.uopInfo.lmul
921
922  // for csrr vl instruction, convert to vsetvl
923  val Vl = 0xC20.U
924  val isCsrrVl = FuType.FuTypeOrR(decodedInst.fuType, FuType.csr) && decodedInst.fuOpType === CSROpType.set && inst.CSRIDX === Vl
925  when (isCsrrVl) {
926    decodedInst.srcType(0) := SrcType.no
927    decodedInst.srcType(1) := SrcType.no
928    decodedInst.srcType(2) := SrcType.no
929    decodedInst.srcType(3) := SrcType.no
930    decodedInst.srcType(4) := SrcType.vp
931    decodedInst.lsrc(4) := Vl_IDX.U
932    decodedInst.blockBackward := false.B
933  }
934
935  io.deq.decodedInst := decodedInst
936  io.deq.decodedInst.rfWen := (decodedInst.ldest =/= 0.U) && decodedInst.rfWen
937  // change vlsu to vseglsu when NF =/= 0.U
938  io.deq.decodedInst.fuType := Mux1H(Seq(
939    ( isCsrrVl) -> FuType.vsetfwf.U,
940    (!FuType.FuTypeOrR(decodedInst.fuType, FuType.vldu, FuType.vstu) && !isCsrrVl      ) -> decodedInst.fuType,
941    ( 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,
942    // MOP === b00 && SUMOP === b01000: unit-stride whole register store
943    // MOP =/= b00                    : strided and indexed store
944    ( 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,
945    // MOP === b00 && LUMOP === b01000: unit-stride whole register load
946    // MOP =/= b00                    : strided and indexed load
947    ( 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,
948  ))
949  //-------------------------------------------------------------
950  // Debug Info
951//  XSDebug("in:  instr=%x pc=%x excepVec=%b crossPageIPFFix=%d\n",
952//    io.enq.ctrl_flow.instr, io.enq.ctrl_flow.pc, io.enq.ctrl_flow.exceptionVec.asUInt,
953//    io.enq.ctrl_flow.crossPageIPFFix)
954//  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",
955//    io.deq.cf_ctrl.ctrl.srcType(0), io.deq.cf_ctrl.ctrl.srcType(1), io.deq.cf_ctrl.ctrl.srcType(2),
956//    io.deq.cf_ctrl.ctrl.lsrc(0), io.deq.cf_ctrl.ctrl.lsrc(1), io.deq.cf_ctrl.ctrl.lsrc(2),
957//    io.deq.cf_ctrl.ctrl.ldest, io.deq.cf_ctrl.ctrl.fuType, io.deq.cf_ctrl.ctrl.fuOpType)
958//  XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d imm=%x\n",
959//    io.deq.cf_ctrl.ctrl.rfWen, io.deq.cf_ctrl.ctrl.fpWen, io.deq.cf_ctrl.ctrl.isXSTrap,
960//    io.deq.cf_ctrl.ctrl.noSpecExec, io.deq.cf_ctrl.ctrl.blockBackward, io.deq.cf_ctrl.ctrl.flushPipe,
961//    io.deq.cf_ctrl.ctrl.imm)
962//  XSDebug("out: excepVec=%b\n", io.deq.cf_ctrl.cf.exceptionVec.asUInt)
963}
964