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