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