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