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