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