xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala (revision a9627d0e4245fdb3ed29ed6343a9f880ac137e3e)
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
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_Z, xWen = T, noSpec = T, blockBack = T),
210    CSRRS   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.set , SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
211    CSRRC   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.clr , SelImm.IMM_Z, 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 + 5){
552  override def do_toImm32(minBits: UInt): UInt = minBits
553
554  override def minBitsFromInstr(instr: UInt): UInt = {
555    Cat(instr(11, 7), instr(19, 15), instr(31, 20))
556  }
557
558  def getCSRAddr(imm: UInt): UInt = {
559    require(imm.getWidth == this.len)
560    imm(11, 0)
561  }
562
563  def getRS1(imm: UInt): UInt = {
564    require(imm.getWidth == this.len)
565    imm(16, 12)
566  }
567
568  def getRD(imm: UInt): UInt = {
569    require(imm.getWidth == this.len)
570    imm(21, 17)
571  }
572
573  def getImm5(imm: UInt): UInt = {
574    require(imm.getWidth == this.len)
575    imm(16, 12)
576  }
577}
578
579case class Imm_B6() extends Imm(6){
580  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
581
582  override def minBitsFromInstr(instr: UInt): UInt = {
583    instr(25, 20)
584  }
585}
586
587case class Imm_OPIVIS() extends Imm(5){
588  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
589
590  override def minBitsFromInstr(instr: UInt): UInt = {
591    instr(19, 15)
592  }
593}
594
595case class Imm_OPIVIU() extends Imm(5){
596  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
597
598  override def minBitsFromInstr(instr: UInt): UInt = {
599    instr(19, 15)
600  }
601}
602
603case class Imm_VSETVLI() extends Imm(11){
604  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
605
606  override def minBitsFromInstr(instr: UInt): UInt = {
607    instr(30, 20)
608  }
609  /**
610    * get VType from extended imm
611    * @param extedImm
612    * @return VType
613    */
614  def getVType(extedImm: UInt): InstVType = {
615    val vtype = Wire(new InstVType)
616    vtype := extedImm(10, 0).asTypeOf(new InstVType)
617    vtype
618  }
619}
620
621case class Imm_VSETIVLI() extends Imm(15){
622  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
623
624  override def minBitsFromInstr(instr: UInt): UInt = {
625    val rvInst: XSInstBitFields = instr.asTypeOf(new XSInstBitFields)
626    val uimm5 = rvInst.UIMM_VSETIVLI
627    val vtype8 = rvInst.ZIMM_VSETIVLI
628    Cat(uimm5, vtype8)
629  }
630  /**
631    * get VType from extended imm
632    * @param extedImm
633    * @return VType
634    */
635  def getVType(extedImm: UInt): InstVType = {
636    val vtype = Wire(new InstVType)
637    vtype := extedImm(9, 0).asTypeOf(new InstVType)
638    vtype
639  }
640
641  def getAvl(extedImm: UInt): UInt = {
642    extedImm(14, 10)
643  }
644}
645
646case class Imm_LUI32() extends Imm(32){
647  override def do_toImm32(minBits: UInt): UInt = minBits(31, 0)
648
649  override def minBitsFromInstr(instr: UInt): UInt = {
650    instr(31, 0)
651  }
652}
653
654case class Imm_VRORVI() extends Imm(6){
655  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
656
657  override def minBitsFromInstr(instr: UInt): UInt = {
658    Cat(instr(26), instr(19, 15))
659  }
660}
661
662object ImmUnion {
663  val I = Imm_I()
664  val S = Imm_S()
665  val B = Imm_B()
666  val U = Imm_U()
667  val J = Imm_J()
668  val Z = Imm_Z()
669  val B6 = Imm_B6()
670  val OPIVIS = Imm_OPIVIS()
671  val OPIVIU = Imm_OPIVIU()
672  val VSETVLI = Imm_VSETVLI()
673  val VSETIVLI = Imm_VSETIVLI()
674  val LUI32 = Imm_LUI32()
675  val VRORVI = Imm_VRORVI()
676
677  // do not add special type lui32 to this, keep ImmUnion max len being 20.
678  val imms = Seq(I, S, B, U, J, Z, B6, OPIVIS, OPIVIU, VSETVLI, VSETIVLI, VRORVI)
679  val maxLen = imms.maxBy(_.len).len
680  val immSelMap = Seq(
681    SelImm.IMM_I,
682    SelImm.IMM_S,
683    SelImm.IMM_SB,
684    SelImm.IMM_U,
685    SelImm.IMM_UJ,
686    SelImm.IMM_Z,
687    SelImm.IMM_B6,
688    SelImm.IMM_OPIVIS,
689    SelImm.IMM_OPIVIU,
690    SelImm.IMM_VSETVLI,
691    SelImm.IMM_VSETIVLI,
692    SelImm.IMM_VRORVI,
693  ).zip(imms)
694  println(s"ImmUnion max len: $maxLen")
695}
696
697case class Imm_LUI_LOAD() {
698  def immFromLuiLoad(lui_imm: UInt, load_imm: UInt): UInt = {
699    val loadImm = load_imm(Imm_I().len - 1, 0)
700    Cat(lui_imm(ImmUnion.maxLen - loadImm.getWidth - 1, 0), loadImm)
701  }
702  def getLuiImm(uop: DynInst): UInt = {
703    val loadImmLen = Imm_I().len
704    val imm_u = Cat(uop.psrc(1), uop.psrc(0), uop.imm(ImmUnion.maxLen - 1, loadImmLen))
705    Cat(Imm_U().toImm32(imm_u)(31, loadImmLen), uop.imm(loadImmLen - 1, 0))
706  }
707}
708
709/**
710 * IO bundle for the Decode unit
711 */
712class DecodeUnitDeqIO(implicit p: Parameters) extends XSBundle {
713  val decodedInst = Output(new DecodedInst)
714  val isComplex = Output(Bool())
715  val uopInfo = Output(new UopInfo)
716}
717class DecodeUnitIO(implicit p: Parameters) extends XSBundle {
718  val enq = new Bundle {
719    val ctrlFlow = Input(new StaticInst)
720    val vtype = Input(new VType)
721    val vstart = Input(Vl())
722  }
723//  val vconfig = Input(UInt(XLEN.W))
724  val deq = new DecodeUnitDeqIO
725  val csrCtrl = Input(new CustomCSRCtrlIO)
726  val fromCSR = Input(new CSRToDecode)
727}
728
729/**
730 * Decode unit that takes in a single CtrlFlow and generates a CfCtrl.
731 */
732class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstants {
733  val io = IO(new DecodeUnitIO)
734
735  val ctrl_flow = io.enq.ctrlFlow // input with RVC Expanded
736
737  private val inst: XSInstBitFields = io.enq.ctrlFlow.instr.asTypeOf(new XSInstBitFields)
738
739  val decode_table: Array[(BitPat, List[BitPat])] = XDecode.table ++
740    FpDecode.table ++
741//    FDivSqrtDecode.table ++
742    BitmanipDecode.table ++
743    ScalarCryptoDecode.table ++
744    XSTrapDecode.table ++
745    CBODecode.table ++
746    SvinvalDecode.table ++
747    HypervisorDecode.table ++
748    VecDecoder.table ++
749    ZicondDecode.table
750
751  require(decode_table.map(_._2.length == 15).reduce(_ && _), "Decode tables have different column size")
752  // assertion for LUI: only LUI should be assigned `selImm === SelImm.IMM_U && fuType === FuType.alu`
753  val luiMatch = (t: Seq[BitPat]) => t(3).value == FuType.alu.ohid && t.reverse.head.value == SelImm.IMM_U.litValue
754  val luiTable = decode_table.filter(t => luiMatch(t._2)).map(_._1).distinct
755  assert(luiTable.length == 1 && luiTable.head == LUI, "Conflicts: LUI is determined by FuType and SelImm in Dispatch")
756
757  // output
758  val decodedInst: DecodedInst = Wire(new DecodedInst()).decode(ctrl_flow.instr, decode_table)
759
760  val fpDecoder = Module(new FPDecoder)
761  fpDecoder.io.instr := ctrl_flow.instr
762  decodedInst.fpu := fpDecoder.io.fpCtrl
763  decodedInst.fpu.wflags := fpDecoder.io.fpCtrl.wflags || decodedInst.wfflags
764
765  decodedInst.connectStaticInst(io.enq.ctrlFlow)
766
767  decodedInst.uopIdx := 0.U
768  decodedInst.firstUop := true.B
769  decodedInst.lastUop := true.B
770  decodedInst.numUops := 1.U
771  decodedInst.numWB   := 1.U
772
773  val isMove = BitPat("b000000000000_?????_000_?????_0010011") === ctrl_flow.instr
774  decodedInst.isMove := isMove && ctrl_flow.instr(RD_MSB, RD_LSB) =/= 0.U && !io.csrCtrl.singlestep
775
776  // fmadd - b1000011
777  // fmsub - b1000111
778  // fnmsub- b1001011
779  // fnmadd- b1001111
780  private val isFMA = inst.OPCODE === BitPat("b100??11")
781  private val isVppu = FuType.isVppu(decodedInst.fuType)
782  private val isVecOPF = FuType.isVecOPF(decodedInst.fuType)
783
784  // read src1~3 location
785  decodedInst.lsrc(0) := inst.RS1
786  decodedInst.lsrc(1) := inst.RS2
787  // src(2) of fma is fs3, src(2) of vector inst is old vd
788  decodedInst.lsrc(2) := Mux(isFMA, inst.FS3, inst.VD)
789  decodedInst.lsrc(3) := V0_IDX.U
790  decodedInst.lsrc(4) := Vl_IDX.U
791
792  // read dest location
793  decodedInst.ldest := inst.RD
794
795  // init v0Wen vlWen
796  decodedInst.v0Wen := false.B
797  decodedInst.vlWen := false.B
798
799  // fill in exception vector
800  val vecException = Module(new VecExceptionGen)
801  vecException.io.inst := io.enq.ctrlFlow.instr
802  vecException.io.decodedInst := decodedInst
803  vecException.io.vtype := decodedInst.vpu.vtype
804  vecException.io.vstart := decodedInst.vpu.vstart
805
806  private val exceptionII =
807    decodedInst.selImm === SelImm.INVALID_INSTR ||
808    vecException.io.illegalInst ||
809    io.fromCSR.illegalInst.sfenceVMA  && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.sfence  ||
810    io.fromCSR.illegalInst.sfencePart && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.nofence ||
811    io.fromCSR.illegalInst.hfenceGVMA && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.hfence_g ||
812    io.fromCSR.illegalInst.hfenceVVMA && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.hfence_v ||
813    io.fromCSR.illegalInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu)   && (LSUOpType.isHlv(decodedInst.fuOpType) || LSUOpType.isHlvx(decodedInst.fuOpType)) ||
814    io.fromCSR.illegalInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.stu)   && LSUOpType.isHsv(decodedInst.fuOpType) ||
815    io.fromCSR.illegalInst.fsIsOff    && (FuType.FuTypeOrR(decodedInst.fuType, FuType.fpOP ++ Seq(FuType.f2v)) ||
816                                          (FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu) && (decodedInst.fuOpType === LSUOpType.lw || decodedInst.fuOpType === LSUOpType.ld) ||
817                                           FuType.FuTypeOrR(decodedInst.fuType, FuType.stu) && (decodedInst.fuOpType === LSUOpType.sw || decodedInst.fuOpType === LSUOpType.sd)) && decodedInst.instr(2) ||
818                                           isVecOPF) ||
819    io.fromCSR.illegalInst.vsIsOff    && FuType.FuTypeOrR(decodedInst.fuType, FuType.vecAll) ||
820    io.fromCSR.illegalInst.wfi        && FuType.FuTypeOrR(decodedInst.fuType, FuType.csr)   && CSROpType.isWfi(decodedInst.fuOpType) ||
821    (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)) ||
822    (decodedInst.needFrm.vectorNeedFrm || FuType.isVectorNeedFrm(decodedInst.fuType)) && io.fromCSR.illegalInst.frm
823
824  private val exceptionVI =
825    io.fromCSR.virtualInst.sfenceVMA  && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.sfence ||
826    io.fromCSR.virtualInst.sfencePart && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && decodedInst.fuOpType === FenceOpType.nofence ||
827    io.fromCSR.virtualInst.hfence     && FuType.FuTypeOrR(decodedInst.fuType, FuType.fence) && (decodedInst.fuOpType === FenceOpType.hfence_g || decodedInst.fuOpType === FenceOpType.hfence_v) ||
828    io.fromCSR.virtualInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.ldu)   && (LSUOpType.isHlv(decodedInst.fuOpType) || LSUOpType.isHlvx(decodedInst.fuOpType)) ||
829    io.fromCSR.virtualInst.hlsv       && FuType.FuTypeOrR(decodedInst.fuType, FuType.stu)   && LSUOpType.isHsv(decodedInst.fuOpType) ||
830    io.fromCSR.virtualInst.wfi        && FuType.FuTypeOrR(decodedInst.fuType, FuType.csr)   && CSROpType.isWfi(decodedInst.fuOpType)
831
832  decodedInst.exceptionVec(illegalInstr) := exceptionII || io.enq.ctrlFlow.exceptionVec(EX_II)
833  decodedInst.exceptionVec(virtualInstr) := exceptionVI
834
835  //update exceptionVec: from frontend trigger's breakpoint exception. To reduce 1 bit of overhead in ibuffer entry.
836  decodedInst.exceptionVec(breakPoint) := TriggerAction.isExp(ctrl_flow.trigger)
837
838  decodedInst.imm := LookupTree(decodedInst.selImm, ImmUnion.immSelMap.map(
839    x => {
840      val minBits = x._2.minBitsFromInstr(ctrl_flow.instr)
841      require(minBits.getWidth == x._2.len)
842      x._1 -> minBits
843    }
844  ))
845
846  private val isLs = FuType.isLoadStore(decodedInst.fuType)
847  private val isVls = FuType.isVls(decodedInst.fuType)
848  private val isStore = FuType.isStore(decodedInst.fuType)
849  private val isAMO = FuType.isAMO(decodedInst.fuType)
850  private val isVStore = FuType.isVStore(decodedInst.fuType)
851  private val isBranch = !decodedInst.preDecodeInfo.notCFI || FuType.isJump(decodedInst.fuType)
852
853  decodedInst.commitType := Cat(isLs | isVls, (isStore && !isAMO) | isVStore | isBranch)
854
855  decodedInst.isVset := FuType.isVset(decodedInst.fuType)
856
857  private val needReverseInsts = Seq(VRSUB_VI, VRSUB_VX, VFRDIV_VF, VFRSUB_VF, VFMV_F_S)
858  private val vextInsts = Seq(VZEXT_VF2, VZEXT_VF4, VZEXT_VF8, VSEXT_VF2, VSEXT_VF4, VSEXT_VF8)
859  private val narrowInsts = Seq(
860    VNSRA_WV, VNSRA_WX, VNSRA_WI, VNSRL_WV, VNSRL_WX, VNSRL_WI,
861    VNCLIP_WV, VNCLIP_WX, VNCLIP_WI, VNCLIPU_WV, VNCLIPU_WX, VNCLIPU_WI,
862  )
863  private val maskDstInsts = Seq(
864    VMADC_VV, VMADC_VX,  VMADC_VI,  VMADC_VVM, VMADC_VXM, VMADC_VIM,
865    VMSBC_VV, VMSBC_VX,  VMSBC_VVM, VMSBC_VXM,
866    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
867    VMSEQ_VV, VMSEQ_VX, VMSEQ_VI, VMSNE_VV, VMSNE_VX, VMSNE_VI,
868    VMSLE_VV, VMSLE_VX, VMSLE_VI, VMSLEU_VV, VMSLEU_VX, VMSLEU_VI,
869    VMSLT_VV, VMSLT_VX, VMSLTU_VV, VMSLTU_VX,
870    VMSGT_VX, VMSGT_VI, VMSGTU_VX, VMSGTU_VI,
871    VMFEQ_VV, VMFEQ_VF, VMFNE_VV, VMFNE_VF, VMFLT_VV, VMFLT_VF, VMFLE_VV, VMFLE_VF, VMFGT_VF, VMFGE_VF,
872  )
873  private val maskOpInsts = Seq(
874    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
875  )
876  private val vmaInsts = Seq(
877    VMACC_VV, VMACC_VX, VNMSAC_VV, VNMSAC_VX, VMADD_VV, VMADD_VX, VNMSUB_VV, VNMSUB_VX,
878    VWMACCU_VV, VWMACCU_VX, VWMACC_VV, VWMACC_VX, VWMACCSU_VV, VWMACCSU_VX, VWMACCUS_VX,
879  )
880  private val wfflagsInsts = Seq(
881    // opfff
882    FADD_S, FSUB_S, FADD_D, FSUB_D,
883    FEQ_S, FLT_S, FLE_S, FEQ_D, FLT_D, FLE_D,
884    FMIN_S, FMAX_S, FMIN_D, FMAX_D,
885    FMUL_S, FMUL_D,
886    FDIV_S, FDIV_D, FSQRT_S, FSQRT_D,
887    FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D,
888    FSGNJ_S, FSGNJN_S, FSGNJX_S,
889    // opfvv
890    VFADD_VV, VFSUB_VV, VFWADD_VV, VFWSUB_VV, VFWADD_WV, VFWSUB_WV,
891    VFMUL_VV, VFDIV_VV, VFWMUL_VV,
892    VFMACC_VV, VFNMACC_VV, VFMSAC_VV, VFNMSAC_VV, VFMADD_VV, VFNMADD_VV, VFMSUB_VV, VFNMSUB_VV,
893    VFWMACC_VV, VFWNMACC_VV, VFWMSAC_VV, VFWNMSAC_VV,
894    VFSQRT_V,
895    VFMIN_VV, VFMAX_VV,
896    VMFEQ_VV, VMFNE_VV, VMFLT_VV, VMFLE_VV,
897    VFSGNJ_VV, VFSGNJN_VV, VFSGNJX_VV,
898    // opfvf
899    VFADD_VF, VFSUB_VF, VFRSUB_VF, VFWADD_VF, VFWSUB_VF, VFWADD_WF, VFWSUB_WF,
900    VFMUL_VF, VFDIV_VF, VFRDIV_VF, VFWMUL_VF,
901    VFMACC_VF, VFNMACC_VF, VFMSAC_VF, VFNMSAC_VF, VFMADD_VF, VFNMADD_VF, VFMSUB_VF, VFNMSUB_VF,
902    VFWMACC_VF, VFWNMACC_VF, VFWMSAC_VF, VFWNMSAC_VF,
903    VFMIN_VF, VFMAX_VF,
904    VMFEQ_VF, VMFNE_VF, VMFLT_VF, VMFLE_VF, VMFGT_VF, VMFGE_VF,
905    VFSGNJ_VF, VFSGNJN_VF, VFSGNJX_VF,
906    // vfred
907    VFREDOSUM_VS, VFREDUSUM_VS, VFREDMAX_VS, VFREDMIN_VS, VFWREDOSUM_VS, VFWREDUSUM_VS,
908    // fcvt & vfcvt
909    FCVT_S_W, FCVT_S_WU, FCVT_S_L, FCVT_S_LU,
910    FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S,
911    FCVT_D_W, FCVT_D_WU, FCVT_D_L, FCVT_D_LU,
912    FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S,
913    FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H,
914    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,
915    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,
916    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,
917    VFNCVT_ROD_F_F_W, VFRSQRT7_V, VFREC7_V,
918  )
919
920  private val scalaNeedFrmInsts = Seq(
921    FADD_S, FSUB_S, FADD_D, FSUB_D,
922    FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S,
923    FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S,
924  )
925
926  private val vectorNeedFrmInsts = Seq (
927    VFSLIDE1UP_VF, VFSLIDE1DOWN_VF,
928  )
929
930  decodedInst.wfflags := wfflagsInsts.map(_ === inst.ALL).reduce(_ || _)
931  decodedInst.needFrm.scalaNeedFrm := scalaNeedFrmInsts.map(_ === inst.ALL).reduce(_ || _)
932  decodedInst.needFrm.vectorNeedFrm := vectorNeedFrmInsts.map(_ === inst.ALL).reduce(_ || _)
933  val fpToVecDecoder = Module(new FPToVecDecoder())
934  fpToVecDecoder.io.instr := inst.asUInt
935  val isFpToVecInst = fpToVecDecoder.io.vpuCtrl.fpu.isFpToVecInst
936  decodedInst.vpu := 0.U.asTypeOf(decodedInst.vpu) // Todo: Connect vpu decoder
937  when(isFpToVecInst){
938    decodedInst.vpu := fpToVecDecoder.io.vpuCtrl
939  }.otherwise{
940    decodedInst.vpu.vill := io.enq.vtype.illegal
941    decodedInst.vpu.vma := io.enq.vtype.vma
942    decodedInst.vpu.vta := io.enq.vtype.vta
943    decodedInst.vpu.vsew := io.enq.vtype.vsew
944    decodedInst.vpu.vlmul := io.enq.vtype.vlmul
945    decodedInst.vpu.vm := inst.VM
946    decodedInst.vpu.nf := inst.NF
947    decodedInst.vpu.veew := inst.WIDTH
948    decodedInst.vpu.isReverse := needReverseInsts.map(_ === inst.ALL).reduce(_ || _)
949    decodedInst.vpu.isExt := vextInsts.map(_ === inst.ALL).reduce(_ || _)
950    val isNarrow = narrowInsts.map(_ === inst.ALL).reduce(_ || _)
951    val isDstMask = maskDstInsts.map(_ === inst.ALL).reduce(_ || _)
952    val isOpMask = maskOpInsts.map(_ === inst.ALL).reduce(_ || _)
953    val isVlx = decodedInst.fuOpType === VlduType.vloxe || decodedInst.fuOpType === VlduType.vluxe
954    val isVle = decodedInst.fuOpType === VlduType.vle || decodedInst.fuOpType === VlduType.vleff || decodedInst.fuOpType === VlduType.vlse
955    val isVlm = decodedInst.fuOpType === VlduType.vlm
956    val isWritePartVd = decodedInst.uopSplitType === UopSplitType.VEC_VRED || decodedInst.uopSplitType === UopSplitType.VEC_0XV
957    val isVma = vmaInsts.map(_ === inst.ALL).reduce(_ || _)
958    val emulIsFrac = Cat(~decodedInst.vpu.vlmul(2), decodedInst.vpu.vlmul(1, 0)) +& decodedInst.vpu.veew < 4.U +& decodedInst.vpu.vsew
959    decodedInst.vpu.isNarrow := isNarrow
960    decodedInst.vpu.isDstMask := isDstMask
961    decodedInst.vpu.isOpMask := isOpMask
962    decodedInst.vpu.isDependOldvd := isVppu || isVecOPF || isVStore || (isDstMask && !isOpMask) || isNarrow || isVlx || isVma
963    decodedInst.vpu.isWritePartVd := isWritePartVd || isVlm || isVle && emulIsFrac
964    decodedInst.vpu.vstart := io.enq.vstart
965  }
966  decodedInst.vpu.specVill := io.enq.vtype.illegal
967  decodedInst.vpu.specVma := io.enq.vtype.vma
968  decodedInst.vpu.specVta := io.enq.vtype.vta
969  decodedInst.vpu.specVsew := io.enq.vtype.vsew
970  decodedInst.vpu.specVlmul := io.enq.vtype.vlmul
971
972  decodedInst.vlsInstr := isVls
973
974  decodedInst.srcType(3) := Mux(inst.VM === 0.U && !isFpToVecInst, SrcType.vp, SrcType.DC) // mask src
975  decodedInst.srcType(4) := Mux(!isFpToVecInst, SrcType.vp, SrcType.DC) // vconfig
976
977  val uopInfoGen = Module(new UopInfoGen)
978  uopInfoGen.io.in.preInfo.typeOfSplit := decodedInst.uopSplitType
979  uopInfoGen.io.in.preInfo.vsew := decodedInst.vpu.vsew
980  uopInfoGen.io.in.preInfo.vlmul := decodedInst.vpu.vlmul
981  uopInfoGen.io.in.preInfo.vwidth := inst.RM
982  uopInfoGen.io.in.preInfo.vmvn := inst.IMM5_OPIVI(2, 0)
983  uopInfoGen.io.in.preInfo.nf := inst.NF
984  uopInfoGen.io.in.preInfo.isVlsr := decodedInst.fuOpType === VlduType.vlr || decodedInst.fuOpType === VstuType.vsr
985  uopInfoGen.io.in.preInfo.isVlsm := decodedInst.fuOpType === VlduType.vlm || decodedInst.fuOpType === VstuType.vsm
986  io.deq.isComplex := uopInfoGen.io.out.isComplex
987  // numOfUop should be 1 when vector instruction is illegalInst
988  io.deq.uopInfo.numOfUop := Mux(vecException.io.illegalInst, 1.U, uopInfoGen.io.out.uopInfo.numOfUop)
989  io.deq.uopInfo.numOfWB := uopInfoGen.io.out.uopInfo.numOfWB
990  io.deq.uopInfo.lmul := uopInfoGen.io.out.uopInfo.lmul
991
992  val isCSR = inst.OPCODE5Bit === OPCODE5Bit.SYSTEM && inst.FUNCT3(1, 0) =/= 0.U
993  val isCSRR = isCSR && inst.FUNCT3 === BitPat("b?1?") && inst.RS1 === 0.U
994  val isCSRW = isCSR && inst.FUNCT3 === BitPat("b?10") && inst.RD  === 0.U
995  dontTouch(isCSRR)
996  dontTouch(isCSRW)
997
998  // for csrr vl instruction, convert to vsetvl
999  val isCsrrVlenb = isCSRR && inst.CSRIDX === CSRs.vlenb.U
1000  val isCsrrVl    = isCSRR && inst.CSRIDX === CSRs.vl.U
1001
1002  // decode for SoftPrefetch instructions (prefetch.w / prefetch.r / prefetch.i)
1003  val isSoftPrefetch = inst.OPCODE === BitPat("b0010011") && inst.FUNCT3 === BitPat("b110") && inst.RD === 0.U
1004  val isPreW = isSoftPrefetch && inst.RS2 === 3.U(5.W)
1005  val isPreR = isSoftPrefetch && inst.RS2 === 1.U(5.W)
1006  val isPreI = isSoftPrefetch && inst.RS2 === 0.U(5.W)
1007
1008  when (isCsrrVl) {
1009    // convert to vsetvl instruction
1010    decodedInst.srcType(0) := SrcType.no
1011    decodedInst.srcType(1) := SrcType.no
1012    decodedInst.srcType(2) := SrcType.no
1013    decodedInst.srcType(3) := SrcType.no
1014    decodedInst.srcType(4) := SrcType.vp
1015    decodedInst.lsrc(4)    := Vl_IDX.U
1016    decodedInst.waitForward   := false.B
1017    decodedInst.blockBackward := false.B
1018    decodedInst.exceptionVec(illegalInstr) := io.fromCSR.illegalInst.vsIsOff
1019  }.elsewhen(isCsrrVlenb){
1020    // convert to addi instruction
1021    decodedInst.srcType(0) := SrcType.reg
1022    decodedInst.srcType(1) := SrcType.imm
1023    decodedInst.srcType(2) := SrcType.no
1024    decodedInst.srcType(3) := SrcType.no
1025    decodedInst.srcType(4) := SrcType.no
1026    decodedInst.selImm := SelImm.IMM_I
1027    decodedInst.waitForward := false.B
1028    decodedInst.blockBackward := false.B
1029    decodedInst.canRobCompress := true.B
1030    decodedInst.exceptionVec(illegalInstr) := io.fromCSR.illegalInst.vsIsOff
1031  }.elsewhen(isPreW || isPreR || isPreI){
1032    decodedInst.selImm := SelImm.IMM_S
1033    decodedInst.fuType := FuType.ldu.U
1034    decodedInst.canRobCompress := false.B
1035    decodedInst.fuOpType := Mux1H(Seq(
1036      isPreW -> LSUOpType.prefetch_w,
1037      isPreR -> LSUOpType.prefetch_r,
1038      isPreI -> LSUOpType.prefetch_i,
1039    ))
1040
1041  }
1042
1043  io.deq.decodedInst := decodedInst
1044  io.deq.decodedInst.rfWen := (decodedInst.ldest =/= 0.U) && decodedInst.rfWen
1045  io.deq.decodedInst.fuType := Mux1H(Seq(
1046    // keep condition
1047    (!FuType.FuTypeOrR(decodedInst.fuType, FuType.vldu, FuType.vstu) && !isCsrrVl && !isCsrrVlenb) -> decodedInst.fuType,
1048    (isCsrrVl) -> FuType.vsetfwf.U,
1049    (isCsrrVlenb) -> FuType.alu.U,
1050
1051    // change vlsu to vseglsu when NF =/= 0.U
1052    ( 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,
1053    // MOP === b00 && SUMOP === b01000: unit-stride whole register store
1054    // MOP =/= b00                    : strided and indexed store
1055    ( 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,
1056    // MOP === b00 && LUMOP === b01000: unit-stride whole register load
1057    // MOP =/= b00                    : strided and indexed load
1058    ( 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,
1059  ))
1060  io.deq.decodedInst.imm := Mux(isCsrrVlenb, (VLEN / 8).U, decodedInst.imm)
1061
1062  io.deq.decodedInst.fuOpType := MuxCase(decodedInst.fuOpType, Seq(
1063    isCsrrVl    -> VSETOpType.csrrvl,
1064    isCsrrVlenb -> ALUOpType.add,
1065  ))
1066
1067  io.deq.decodedInst.blockBackward := MuxCase(decodedInst.blockBackward, Seq(
1068    isCSRR -> false.B,
1069  ))
1070  //-------------------------------------------------------------
1071  // Debug Info
1072//  XSDebug("in:  instr=%x pc=%x excepVec=%b crossPageIPFFix=%d\n",
1073//    io.enq.ctrl_flow.instr, io.enq.ctrl_flow.pc, io.enq.ctrl_flow.exceptionVec.asUInt,
1074//    io.enq.ctrl_flow.crossPageIPFFix)
1075//  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",
1076//    io.deq.cf_ctrl.ctrl.srcType(0), io.deq.cf_ctrl.ctrl.srcType(1), io.deq.cf_ctrl.ctrl.srcType(2),
1077//    io.deq.cf_ctrl.ctrl.lsrc(0), io.deq.cf_ctrl.ctrl.lsrc(1), io.deq.cf_ctrl.ctrl.lsrc(2),
1078//    io.deq.cf_ctrl.ctrl.ldest, io.deq.cf_ctrl.ctrl.fuType, io.deq.cf_ctrl.ctrl.fuOpType)
1079//  XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d imm=%x\n",
1080//    io.deq.cf_ctrl.ctrl.rfWen, io.deq.cf_ctrl.ctrl.fpWen, io.deq.cf_ctrl.ctrl.isXSTrap,
1081//    io.deq.cf_ctrl.ctrl.noSpecExec, io.deq.cf_ctrl.ctrl.blockBackward, io.deq.cf_ctrl.ctrl.flushPipe,
1082//    io.deq.cf_ctrl.ctrl.imm)
1083//  XSDebug("out: excepVec=%b\n", io.deq.cf_ctrl.cf.exceptionVec.asUInt)
1084}
1085