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