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