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