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