xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala (revision 6306fe335c2bca9aa17b8975c11e0e6116b494fd)
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.Instructions._
23import freechips.rocketchip.util.uintToBitPat
24import utility._
25import utils._
26import xiangshan.ExceptionNO.{illegalInstr, virtualInstr}
27import xiangshan._
28import xiangshan.backend.fu.FuType
29import xiangshan.backend.Bundles.{DecodedInst, DynInst, StaticInst}
30import xiangshan.backend.decode.isa.PseudoInstructions
31import xiangshan.backend.decode.isa.bitfield.{InstVType, XSInstBitFields}
32import xiangshan.backend.fu.vector.Bundles.{VType, Vl}
33
34/**
35 * Abstract trait giving defaults and other relevant values to different Decode constants/
36 */
37abstract trait DecodeConstants {
38  // This X should be used only in 1-bit signal. Otherwise, use BitPat("b???") to align with the width of UInt.
39  def X = BitPat("b0")
40  def N = BitPat("b0")
41  def Y = BitPat("b1")
42  def T = true
43  def F = false
44
45  def decodeDefault: List[BitPat] = // illegal instruction
46    //   srcType(0) srcType(1) srcType(2) fuType    fuOpType    rfWen
47    //   |          |          |          |         |           |  fpWen
48    //   |          |          |          |         |           |  |  vecWen
49    //   |          |          |          |         |           |  |  |  isXSTrap
50    //   |          |          |          |         |           |  |  |  |  noSpecExec
51    //   |          |          |          |         |           |  |  |  |  |  blockBackward
52    //   |          |          |          |         |           |  |  |  |  |  |  flushPipe
53    //   |          |          |          |         |           |  |  |  |  |  |  |  canRobCompress
54    //   |          |          |          |         |           |  |  |  |  |  |  |  |  uopSplitType
55    //   |          |          |          |         |           |  |  |  |  |  |  |  |  |             selImm
56    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
57
58  val decodeArray: Array[(BitPat, XSDecodeBase)]
59  final def table: Array[(BitPat, List[BitPat])] = decodeArray.map(x => (x._1, x._2.generate()))
60}
61
62trait DecodeUnitConstants
63{
64  // abstract out instruction decode magic numbers
65  val RD_MSB  = 11
66  val RD_LSB  = 7
67  val RS1_MSB = 19
68  val RS1_LSB = 15
69  val RS2_MSB = 24
70  val RS2_LSB = 20
71  val RS3_MSB = 31
72  val RS3_LSB = 27
73}
74
75/**
76 * Decoded control signals
77 * See xiangshan/package.scala, xiangshan/backend/package.scala, Bundle.scala
78 */
79
80abstract class XSDecodeBase {
81  def X = BitPat("b?")
82  def N = BitPat("b0")
83  def Y = BitPat("b1")
84  def T = true
85  def F = false
86  def generate() : List[BitPat]
87}
88
89case class XSDecode(
90  src1: BitPat, src2: BitPat, src3: BitPat,
91  fu: FuType.OHType, fuOp: BitPat, selImm: BitPat,
92  uopSplitType: BitPat = UopSplitType.X,
93  xWen: Boolean = false,
94  fWen: Boolean = false,
95  vWen: Boolean = false,
96  mWen: Boolean = false,
97  xsTrap: Boolean = false,
98  noSpec: Boolean = false,
99  blockBack: Boolean = false,
100  flushPipe: Boolean = false,
101  canRobCompress: Boolean = false,
102) extends XSDecodeBase {
103  def generate() : List[BitPat] = {
104    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)
105  }
106}
107
108case class FDecode(
109  src1: BitPat, src2: BitPat, src3: BitPat,
110  fu: FuType.OHType, fuOp: BitPat, selImm: BitPat = SelImm.X,
111  uopSplitType: BitPat = UopSplitType.X,
112  xWen: Boolean = false,
113  fWen: Boolean = false,
114  vWen: Boolean = false,
115  mWen: Boolean = false,
116  xsTrap: Boolean = false,
117  noSpec: Boolean = false,
118  blockBack: Boolean = false,
119  flushPipe: Boolean = false,
120  canRobCompress: Boolean = false,
121) extends XSDecodeBase {
122  def generate() : List[BitPat] = {
123    XSDecode(src1, src2, src3, fu, fuOp, selImm, uopSplitType, xWen, fWen, vWen, mWen, xsTrap, noSpec, blockBack, flushPipe, canRobCompress).generate()
124  }
125}
126
127/**
128 * Overall Decode constants
129 */
130object XDecode extends DecodeConstants {
131  import PseudoInstructions.{CSRRC_RO, CSRRS_RO}
132
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    // CSR RO should be ahead of CSRRS and CSRRC, since decoder don't handle the inclusive relation-ship among the patterns.
210    CSRRS_RO -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.ro, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
211    CSRRC_RO -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.ro, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
212
213    CSRRW   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.wrt , SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
214    CSRRS   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.set , SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
215    CSRRC   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.clr , SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
216
217    CSRRWI  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.wrti, SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
218    CSRRSI  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.seti, SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
219    CSRRCI  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.clri, SelImm.IMM_Z, xWen = T, noSpec = T, blockBack = T),
220
221    EBREAK  -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
222    ECALL   -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
223    SRET    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.csr, CSROpType.jmp, SelImm.IMM_I, xWen = T, noSpec = T, blockBack = T),
224    MRET    -> 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    FLW     -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.lw, selImm = SelImm.IMM_I, fWen = T),
389    FLD     -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.ldu, LSUOpType.ld, selImm = SelImm.IMM_I, fWen = T),
390    FSW     -> FDecode(SrcType.reg, SrcType.fp,  SrcType.X, FuType.stu, LSUOpType.sw, selImm = SelImm.IMM_S          ),
391    FSD     -> FDecode(SrcType.reg, SrcType.fp,  SrcType.X, FuType.stu, LSUOpType.sd, selImm = SelImm.IMM_S          ),
392
393    FMV_D_X -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2v, IF2VectorType.FMX_D_X, fWen = T, canRobCompress = T),
394    FMV_W_X -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2v, IF2VectorType.FMX_W_X, fWen = T, canRobCompress = T),
395
396    // Int to FP
397    FCVT_S_W  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
398    FCVT_S_WU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
399    FCVT_S_L  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
400    FCVT_S_LU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
401
402    FCVT_D_W  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
403    FCVT_D_WU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
404    FCVT_D_L  -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
405    FCVT_D_LU -> FDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.i2f, FuOpType.X, fWen = T, canRobCompress = T),
406
407  )
408}
409
410/**
411 * FP Divide SquareRoot Constants
412 */
413object FDivSqrtDecode extends DecodeConstants {
414  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
415    FDIV_S  -> FDecode(SrcType.fp,  SrcType.fp,  SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
416    FDIV_D  -> FDecode(SrcType.fp,  SrcType.fp,  SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
417    FSQRT_S -> FDecode(SrcType.fp,  SrcType.imm, SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
418    FSQRT_D -> FDecode(SrcType.fp,  SrcType.imm, SrcType.X, FuType.fDivSqrt, FuOpType.X, fWen = T, canRobCompress = T),
419  )
420}
421
422/**
423 * Svinval extension Constants
424 */
425object SvinvalDecode extends DecodeConstants {
426  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
427    /* sinval_vma is like sfence.vma , but sinval_vma can be dispatched and issued like normal instructions while sfence.vma
428     * must assure it is the ONLY instrucion executing in backend.
429     */
430    SINVAL_VMA        -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.sfence, SelImm.X),
431    /* sfecne.w.inval is the begin instrucion of a TLB flush which set *noSpecExec* and *blockBackward* signals
432     * so when it comes to dispatch , it will block all instruction after itself until all instrucions ahead of it in rob commit
433     * then dispatch and issue this instrucion to flush sbuffer to dcache
434     * after this instrucion commits , issue following sinval_vma instructions (out of order) to flush TLB
435     */
436    SFENCE_W_INVAL    -> XSDecode(SrcType.DC, SrcType.DC, SrcType.X, FuType.fence, FenceOpType.nofence, SelImm.X, noSpec = T, blockBack = T),
437    /* sfecne.inval.ir is the end instrucion of a TLB flush which set *noSpecExec* *blockBackward* and *flushPipe* signals
438     * so when it comes to dispatch , it will wait until all sinval_vma ahead of it in rob commit
439     * then dispatch and issue this instrucion
440     * when it commit at the head of rob , flush the pipeline since some instrucions have been fetched to ibuffer using old TLB map
441     */
442    SFENCE_INVAL_IR   -> XSDecode(SrcType.DC, SrcType.DC, SrcType.X, FuType.fence, FenceOpType.nofence, SelImm.X, noSpec = T, blockBack = T, flushPipe = T)
443    /* what is Svinval extension ?
444     *                       ----->             sfecne.w.inval
445     * sfence.vma   vpn1     ----->             sinval_vma   vpn1
446     * sfence.vma   vpn2     ----->             sinval_vma   vpn2
447     *                       ----->             sfecne.inval.ir
448     *
449     * sfence.vma should be executed in-order and it flushes the pipeline after committing
450     * we can parallel sfence instrucions with this extension
451     */
452  )
453}
454
455/*
456 * CBO decode
457 */
458object CBODecode extends DecodeConstants {
459  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
460    CBO_ZERO  -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_zero , SelImm.IMM_S),
461    CBO_CLEAN -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_clean, SelImm.IMM_S),
462    CBO_FLUSH -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_flush, SelImm.IMM_S),
463    CBO_INVAL -> XSDecode(SrcType.reg, SrcType.DC, SrcType.X, FuType.stu, LSUOpType.cbo_inval, SelImm.IMM_S)
464  )
465}
466
467/*
468 * Hypervisor decode
469 */
470object HypervisorDecode extends DecodeConstants {
471  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
472    HFENCE_GVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_g, SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
473    HFENCE_VVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_v, SelImm.X, noSpec = T, blockBack = T, flushPipe = T),
474    HINVAL_GVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_g, SelImm.X),
475    HINVAL_VVMA -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.fence, FenceOpType.hfence_v, SelImm.X),
476    HLV_B       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvb,       SelImm.X, xWen = T),
477    HLV_BU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvbu,      SelImm.X, xWen = T),
478    HLV_D       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvd,       SelImm.X, xWen = T),
479    HLV_H       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvh,       SelImm.X, xWen = T),
480    HLV_HU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvhu,      SelImm.X, xWen = T),
481    HLV_W       -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvw,       SelImm.X, xWen = T),
482    HLV_WU      -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvwu,      SelImm.X, xWen = T),
483    HLVX_HU     -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvxhu,     SelImm.X, xWen = T),
484    HLVX_WU     -> XSDecode(SrcType.reg, SrcType.X,   SrcType.X, FuType.ldu,   LSUOpType.hlvxwu,     SelImm.X, xWen = T),
485    HSV_B       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvb,       SelImm.X),
486    HSV_D       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvd,       SelImm.X),
487    HSV_H       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvh,       SelImm.X),
488    HSV_W       -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.stu,   LSUOpType.hsvw,       SelImm.X),
489  )
490}
491
492object ZicondDecode extends DecodeConstants {
493  override val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
494    CZERO_EQZ   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.czero_eqz, SelImm.X, xWen = T, canRobCompress = T),
495    CZERO_NEZ   -> XSDecode(SrcType.reg, SrcType.reg, SrcType.X, FuType.alu, ALUOpType.czero_nez, SelImm.X, xWen = T, canRobCompress = T),
496  )
497}
498
499/**
500 * XiangShan Trap Decode constants
501 */
502object XSTrapDecode extends DecodeConstants {
503  def TRAP = BitPat("b000000000000?????000000001101011")
504  val decodeArray: Array[(BitPat, XSDecodeBase)] = Array(
505    TRAP    -> XSDecode(SrcType.reg, SrcType.imm, SrcType.X, FuType.alu, ALUOpType.add, SelImm.IMM_I, xWen = T, xsTrap = T, noSpec = T, blockBack = T)
506  )
507}
508
509abstract class Imm(val len: Int) {
510  def toImm32(minBits: UInt): UInt = do_toImm32(minBits(len - 1, 0))
511  def do_toImm32(minBits: UInt): UInt
512  def minBitsFromInstr(instr: UInt): UInt
513}
514
515case class Imm_I() extends Imm(12) {
516  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits(len - 1, 0), 32)
517
518  override def minBitsFromInstr(instr: UInt): UInt =
519    Cat(instr(31, 20))
520}
521
522case class Imm_S() extends Imm(12) {
523  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
524
525  override def minBitsFromInstr(instr: UInt): UInt =
526    Cat(instr(31, 25), instr(11, 7))
527}
528
529case class Imm_B() extends Imm(12) {
530  override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
531
532  override def minBitsFromInstr(instr: UInt): UInt =
533    Cat(instr(31), instr(7), instr(30, 25), instr(11, 8))
534}
535
536case class Imm_U() extends Imm(20){
537  override def do_toImm32(minBits: UInt): UInt = Cat(minBits(len - 1, 0), 0.U(12.W))
538
539  override def minBitsFromInstr(instr: UInt): UInt = {
540    instr(31, 12)
541  }
542}
543
544case class Imm_J() extends Imm(20){
545  override def do_toImm32(minBits: UInt): UInt = SignExt(Cat(minBits, 0.U(1.W)), 32)
546
547  override def minBitsFromInstr(instr: UInt): UInt = {
548    Cat(instr(31), instr(19, 12), instr(20), instr(30, 25), instr(24, 21))
549  }
550}
551
552case class Imm_Z() extends Imm(12 + 5){
553  override def do_toImm32(minBits: UInt): UInt = minBits
554
555  override def minBitsFromInstr(instr: UInt): UInt = {
556    Cat(instr(19, 15), instr(31, 20))
557  }
558}
559
560case class Imm_B6() extends Imm(6){
561  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
562
563  override def minBitsFromInstr(instr: UInt): UInt = {
564    instr(25, 20)
565  }
566}
567
568case class Imm_OPIVIS() extends Imm(5){
569  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
570
571  override def minBitsFromInstr(instr: UInt): UInt = {
572    instr(19, 15)
573  }
574}
575
576case class Imm_OPIVIU() extends Imm(5){
577  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
578
579  override def minBitsFromInstr(instr: UInt): UInt = {
580    instr(19, 15)
581  }
582}
583
584case class Imm_VSETVLI() extends Imm(11){
585  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
586
587  override def minBitsFromInstr(instr: UInt): UInt = {
588    instr(30, 20)
589  }
590  /**
591    * get VType from extended imm
592    * @param extedImm
593    * @return VType
594    */
595  def getVType(extedImm: UInt): InstVType = {
596    val vtype = Wire(new InstVType)
597    vtype := extedImm(10, 0).asTypeOf(new InstVType)
598    vtype
599  }
600}
601
602case class Imm_VSETIVLI() extends Imm(15){
603  override def do_toImm32(minBits: UInt): UInt = SignExt(minBits, 32)
604
605  override def minBitsFromInstr(instr: UInt): UInt = {
606    val rvInst: XSInstBitFields = instr.asTypeOf(new XSInstBitFields)
607    val uimm5 = rvInst.UIMM_VSETIVLI
608    val vtype8 = rvInst.ZIMM_VSETIVLI
609    Cat(uimm5, vtype8)
610  }
611  /**
612    * get VType from extended imm
613    * @param extedImm
614    * @return VType
615    */
616  def getVType(extedImm: UInt): InstVType = {
617    val vtype = Wire(new InstVType)
618    vtype := extedImm(9, 0).asTypeOf(new InstVType)
619    vtype
620  }
621
622  def getAvl(extedImm: UInt): UInt = {
623    extedImm(14, 10)
624  }
625}
626
627case class Imm_LUI32() extends Imm(32){
628  override def do_toImm32(minBits: UInt): UInt = minBits(31, 0)
629
630  override def minBitsFromInstr(instr: UInt): UInt = {
631    instr(31, 0)
632  }
633}
634
635case class Imm_VRORVI() extends Imm(6){
636  override def do_toImm32(minBits: UInt): UInt = ZeroExt(minBits, 32)
637
638  override def minBitsFromInstr(instr: UInt): UInt = {
639    Cat(instr(26), instr(19, 15))
640  }
641}
642
643object ImmUnion {
644  val I = Imm_I()
645  val S = Imm_S()
646  val B = Imm_B()
647  val U = Imm_U()
648  val J = Imm_J()
649  val Z = Imm_Z()
650  val B6 = Imm_B6()
651  val OPIVIS = Imm_OPIVIS()
652  val OPIVIU = Imm_OPIVIU()
653  val VSETVLI = Imm_VSETVLI()
654  val VSETIVLI = Imm_VSETIVLI()
655  val LUI32 = Imm_LUI32()
656  val VRORVI = Imm_VRORVI()
657
658  // do not add special type lui32 to this, keep ImmUnion max len being 20.
659  val imms = Seq(I, S, B, U, J, Z, B6, OPIVIS, OPIVIU, VSETVLI, VSETIVLI, VRORVI)
660  val maxLen = imms.maxBy(_.len).len
661  val immSelMap = Seq(
662    SelImm.IMM_I,
663    SelImm.IMM_S,
664    SelImm.IMM_SB,
665    SelImm.IMM_U,
666    SelImm.IMM_UJ,
667    SelImm.IMM_Z,
668    SelImm.IMM_B6,
669    SelImm.IMM_OPIVIS,
670    SelImm.IMM_OPIVIU,
671    SelImm.IMM_VSETVLI,
672    SelImm.IMM_VSETIVLI,
673    SelImm.IMM_VRORVI,
674  ).zip(imms)
675  println(s"ImmUnion max len: $maxLen")
676}
677
678case class Imm_LUI_LOAD() {
679  def immFromLuiLoad(lui_imm: UInt, load_imm: UInt): UInt = {
680    val loadImm = load_imm(Imm_I().len - 1, 0)
681    Cat(lui_imm(ImmUnion.maxLen - loadImm.getWidth - 1, 0), loadImm)
682  }
683  def getLuiImm(uop: DynInst): UInt = {
684    val loadImmLen = Imm_I().len
685    val imm_u = Cat(uop.psrc(1), uop.psrc(0), uop.imm(ImmUnion.maxLen - 1, loadImmLen))
686    Cat(Imm_U().toImm32(imm_u)(31, loadImmLen), uop.imm(loadImmLen - 1, 0))
687  }
688}
689
690/**
691 * IO bundle for the Decode unit
692 */
693class DecodeUnitDeqIO(implicit p: Parameters) extends XSBundle {
694  val decodedInst = Output(new DecodedInst)
695  val isComplex = Output(Bool())
696  val uopInfo = Output(new UopInfo)
697}
698class DecodeUnitIO(implicit p: Parameters) extends XSBundle {
699  val enq = new Bundle {
700    val ctrlFlow = Input(new StaticInst)
701    val vtype = Input(new VType)
702    val vstart = Input(Vl())
703  }
704//  val vconfig = Input(UInt(XLEN.W))
705  val deq = new DecodeUnitDeqIO
706  val csrCtrl = Input(new CustomCSRCtrlIO)
707}
708
709/**
710 * Decode unit that takes in a single CtrlFlow and generates a CfCtrl.
711 */
712class DecodeUnit(implicit p: Parameters) extends XSModule with DecodeUnitConstants {
713  val io = IO(new DecodeUnitIO)
714
715  val ctrl_flow = io.enq.ctrlFlow // input with RVC Expanded
716
717  private val inst: XSInstBitFields = io.enq.ctrlFlow.instr.asTypeOf(new XSInstBitFields)
718
719  val decode_table: Array[(BitPat, List[BitPat])] = XDecode.table ++
720    FpDecode.table ++
721//    FDivSqrtDecode.table ++
722    BitmanipDecode.table ++
723    ScalarCryptoDecode.table ++
724    XSTrapDecode.table ++
725    CBODecode.table ++
726    SvinvalDecode.table ++
727    HypervisorDecode.table ++
728    VecDecoder.table ++
729    ZicondDecode.table
730
731  require(decode_table.map(_._2.length == 15).reduce(_ && _), "Decode tables have different column size")
732  // assertion for LUI: only LUI should be assigned `selImm === SelImm.IMM_U && fuType === FuType.alu`
733  val luiMatch = (t: Seq[BitPat]) => t(3).value == FuType.alu.ohid && t.reverse.head.value == SelImm.IMM_U.litValue
734  val luiTable = decode_table.filter(t => luiMatch(t._2)).map(_._1).distinct
735  assert(luiTable.length == 1 && luiTable.head == LUI, "Conflicts: LUI is determined by FuType and SelImm in Dispatch")
736
737  // output
738  val decodedInst: DecodedInst = Wire(new DecodedInst()).decode(ctrl_flow.instr, decode_table)
739
740  val fpDecoder = Module(new FPDecoder)
741  fpDecoder.io.instr := ctrl_flow.instr
742  decodedInst.fpu := fpDecoder.io.fpCtrl
743
744  decodedInst.connectStaticInst(io.enq.ctrlFlow)
745
746  decodedInst.uopIdx := 0.U
747  decodedInst.firstUop := true.B
748  decodedInst.lastUop := true.B
749  decodedInst.numUops := 1.U
750  decodedInst.numWB   := 1.U
751
752  val isMove = BitPat("b000000000000_?????_000_?????_0010011") === ctrl_flow.instr
753  decodedInst.isMove := isMove && ctrl_flow.instr(RD_MSB, RD_LSB) =/= 0.U && !io.csrCtrl.singlestep
754
755  // fmadd - b1000011
756  // fmsub - b1000111
757  // fnmsub- b1001011
758  // fnmadd- b1001111
759  private val isFMA = inst.OPCODE === BitPat("b100??11")
760  private val isVppu = FuType.isVppu(decodedInst.fuType)
761  private val isVecOPF = FuType.isVecOPF(decodedInst.fuType)
762
763  // read src1~3 location
764  decodedInst.lsrc(0) := inst.RS1
765  decodedInst.lsrc(1) := inst.RS2
766  // src(2) of fma is fs3, src(2) of vector inst is old vd
767  decodedInst.lsrc(2) := Mux(isFMA, inst.FS3, inst.VD)
768  decodedInst.lsrc(3) := V0_IDX.U
769  decodedInst.lsrc(4) := Vl_IDX.U
770
771  // read dest location
772  decodedInst.ldest := inst.RD
773
774  // init v0Wen vlWen
775  decodedInst.v0Wen := false.B
776  decodedInst.vlWen := false.B
777
778  // fill in exception vector
779  val vecException = Module(new VecExceptionGen)
780  vecException.io.inst := io.enq.ctrlFlow.instr
781  vecException.io.decodedInst := decodedInst
782  vecException.io.vtype := decodedInst.vpu.vtype
783  vecException.io.vstart := decodedInst.vpu.vstart
784  decodedInst.exceptionVec(illegalInstr) := decodedInst.selImm === SelImm.INVALID_INSTR || vecException.io.illegalInst
785
786  when(io.csrCtrl.virtMode){
787    // Todo: optimize EX_VI decode
788    // vs/vu attempting to exec hyperinst will raise virtual instruction
789    decodedInst.exceptionVec(virtualInstr) := ctrl_flow.instr === HLV_B || ctrl_flow.instr === HLV_BU ||
790      ctrl_flow.instr === HLV_H   || ctrl_flow.instr === HLV_HU ||
791      ctrl_flow.instr === HLVX_HU || ctrl_flow.instr === HLV_W  ||
792      ctrl_flow.instr === HLVX_WU || ctrl_flow.instr === HLV_WU ||
793      ctrl_flow.instr === HLV_D   || ctrl_flow.instr === HSV_B  ||
794      ctrl_flow.instr === HSV_H   || ctrl_flow.instr === HSV_W  ||
795      ctrl_flow.instr === HSV_D   || ctrl_flow.instr === HFENCE_VVMA ||
796      ctrl_flow.instr === HFENCE_GVMA || ctrl_flow.instr === HINVAL_GVMA ||
797      ctrl_flow.instr === HINVAL_VVMA
798  }
799
800  decodedInst.imm := LookupTree(decodedInst.selImm, ImmUnion.immSelMap.map(
801    x => {
802      val minBits = x._2.minBitsFromInstr(ctrl_flow.instr)
803      require(minBits.getWidth == x._2.len)
804      x._1 -> minBits
805    }
806  ))
807
808  private val isLs = FuType.isLoadStore(decodedInst.fuType)
809  private val isVls = FuType.isVls(decodedInst.fuType)
810  private val isStore = FuType.isStore(decodedInst.fuType)
811  private val isAMO = FuType.isAMO(decodedInst.fuType)
812  private val isVStore = FuType.isVStore(decodedInst.fuType)
813  private val isBranch = !decodedInst.preDecodeInfo.notCFI || FuType.isJump(decodedInst.fuType)
814
815  decodedInst.commitType := Cat(isLs | isVls, (isStore && !isAMO) | isVStore | isBranch)
816
817  decodedInst.isVset := FuType.isVset(decodedInst.fuType)
818
819  private val needReverseInsts = Seq(VRSUB_VI, VRSUB_VX, VFRDIV_VF, VFRSUB_VF, VFMV_F_S)
820  private val vextInsts = Seq(VZEXT_VF2, VZEXT_VF4, VZEXT_VF8, VSEXT_VF2, VSEXT_VF4, VSEXT_VF8)
821  private val narrowInsts = Seq(
822    VNSRA_WV, VNSRA_WX, VNSRA_WI, VNSRL_WV, VNSRL_WX, VNSRL_WI,
823    VNCLIP_WV, VNCLIP_WX, VNCLIP_WI, VNCLIPU_WV, VNCLIPU_WX, VNCLIPU_WI,
824  )
825  private val maskDstInsts = Seq(
826    VMADC_VV, VMADC_VX,  VMADC_VI,  VMADC_VVM, VMADC_VXM, VMADC_VIM,
827    VMSBC_VV, VMSBC_VX,  VMSBC_VVM, VMSBC_VXM,
828    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
829    VMSEQ_VV, VMSEQ_VX, VMSEQ_VI, VMSNE_VV, VMSNE_VX, VMSNE_VI,
830    VMSLE_VV, VMSLE_VX, VMSLE_VI, VMSLEU_VV, VMSLEU_VX, VMSLEU_VI,
831    VMSLT_VV, VMSLT_VX, VMSLTU_VV, VMSLTU_VX,
832    VMSGT_VX, VMSGT_VI, VMSGTU_VX, VMSGTU_VI,
833    VMFEQ_VV, VMFEQ_VF, VMFNE_VV, VMFNE_VF, VMFLT_VV, VMFLT_VF, VMFLE_VV, VMFLE_VF, VMFGT_VF, VMFGE_VF,
834  )
835  private val maskOpInsts = Seq(
836    VMAND_MM, VMNAND_MM, VMANDN_MM, VMXOR_MM, VMOR_MM, VMNOR_MM, VMORN_MM, VMXNOR_MM,
837  )
838  private val vmaInsts = Seq(
839    VMACC_VV, VMACC_VX, VNMSAC_VV, VNMSAC_VX, VMADD_VV, VMADD_VX, VNMSUB_VV, VNMSUB_VX,
840    VWMACCU_VV, VWMACCU_VX, VWMACC_VV, VWMACC_VX, VWMACCSU_VV, VWMACCSU_VX, VWMACCUS_VX,
841  )
842  private val wfflagsInsts = Seq(
843    // opfff
844    FADD_S, FSUB_S, FADD_D, FSUB_D,
845    FEQ_S, FLT_S, FLE_S, FEQ_D, FLT_D, FLE_D,
846    FMIN_S, FMAX_S, FMIN_D, FMAX_D,
847    FMUL_S, FMUL_D,
848    FDIV_S, FDIV_D, FSQRT_S, FSQRT_D,
849    FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D,
850    FSGNJ_S, FSGNJN_S, FSGNJX_S,
851    // opfvv
852    VFADD_VV, VFSUB_VV, VFWADD_VV, VFWSUB_VV, VFWADD_WV, VFWSUB_WV,
853    VFMUL_VV, VFDIV_VV, VFWMUL_VV,
854    VFMACC_VV, VFNMACC_VV, VFMSAC_VV, VFNMSAC_VV, VFMADD_VV, VFNMADD_VV, VFMSUB_VV, VFNMSUB_VV,
855    VFWMACC_VV, VFWNMACC_VV, VFWMSAC_VV, VFWNMSAC_VV,
856    VFSQRT_V,
857    VFMIN_VV, VFMAX_VV,
858    VMFEQ_VV, VMFNE_VV, VMFLT_VV, VMFLE_VV,
859    VFSGNJ_VV, VFSGNJN_VV, VFSGNJX_VV,
860    // opfvf
861    VFADD_VF, VFSUB_VF, VFRSUB_VF, VFWADD_VF, VFWSUB_VF, VFWADD_WF, VFWSUB_WF,
862    VFMUL_VF, VFDIV_VF, VFRDIV_VF, VFWMUL_VF,
863    VFMACC_VF, VFNMACC_VF, VFMSAC_VF, VFNMSAC_VF, VFMADD_VF, VFNMADD_VF, VFMSUB_VF, VFNMSUB_VF,
864    VFWMACC_VF, VFWNMACC_VF, VFWMSAC_VF, VFWNMSAC_VF,
865    VFMIN_VF, VFMAX_VF,
866    VMFEQ_VF, VMFNE_VF, VMFLT_VF, VMFLE_VF, VMFGT_VF, VMFGE_VF,
867    VFSGNJ_VF, VFSGNJN_VF, VFSGNJX_VF,
868    // vfred
869    VFREDOSUM_VS, VFREDUSUM_VS, VFREDMAX_VS, VFREDMIN_VS, VFWREDOSUM_VS, VFWREDUSUM_VS,
870    // fcvt & vfcvt
871    FCVT_S_W, FCVT_S_WU, FCVT_S_L, FCVT_S_LU,
872    FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S,
873    FCVT_D_W, FCVT_D_WU, FCVT_D_L, FCVT_D_LU,
874    FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S,
875    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,
876    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,
877    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,
878    VFNCVT_ROD_F_F_W, VFRSQRT7_V, VFREC7_V,
879  )
880  decodedInst.wfflags := wfflagsInsts.map(_ === inst.ALL).reduce(_ || _)
881  val fpToVecDecoder = Module(new FPToVecDecoder())
882  fpToVecDecoder.io.instr := inst.asUInt
883  val isFpToVecInst = fpToVecDecoder.io.vpuCtrl.fpu.isFpToVecInst
884  decodedInst.vpu := 0.U.asTypeOf(decodedInst.vpu) // Todo: Connect vpu decoder
885  when(isFpToVecInst){
886    decodedInst.vpu := fpToVecDecoder.io.vpuCtrl
887  }.otherwise{
888    decodedInst.vpu.vill := io.enq.vtype.illegal
889    decodedInst.vpu.vma := io.enq.vtype.vma
890    decodedInst.vpu.vta := io.enq.vtype.vta
891    decodedInst.vpu.vsew := io.enq.vtype.vsew
892    decodedInst.vpu.vlmul := io.enq.vtype.vlmul
893    decodedInst.vpu.vm := inst.VM
894    decodedInst.vpu.nf := inst.NF
895    decodedInst.vpu.veew := inst.WIDTH
896    decodedInst.vpu.isReverse := needReverseInsts.map(_ === inst.ALL).reduce(_ || _)
897    decodedInst.vpu.isExt := vextInsts.map(_ === inst.ALL).reduce(_ || _)
898    val isNarrow = narrowInsts.map(_ === inst.ALL).reduce(_ || _)
899    val isDstMask = maskDstInsts.map(_ === inst.ALL).reduce(_ || _)
900    val isOpMask = maskOpInsts.map(_ === inst.ALL).reduce(_ || _)
901    val isVlx = decodedInst.fuOpType === VlduType.vloxe || decodedInst.fuOpType === VlduType.vluxe
902    val isVle = decodedInst.fuOpType === VlduType.vle || decodedInst.fuOpType === VlduType.vleff || decodedInst.fuOpType === VlduType.vlse
903    val isVlm = decodedInst.fuOpType === VlduType.vlm
904    val isWritePartVd = decodedInst.uopSplitType === UopSplitType.VEC_VRED || decodedInst.uopSplitType === UopSplitType.VEC_0XV
905    val isVma = vmaInsts.map(_ === inst.ALL).reduce(_ || _)
906    val emulIsFrac = Cat(~decodedInst.vpu.vlmul(2), decodedInst.vpu.vlmul(1, 0)) +& decodedInst.vpu.veew < 4.U +& decodedInst.vpu.vsew
907    decodedInst.vpu.isNarrow := isNarrow
908    decodedInst.vpu.isDstMask := isDstMask
909    decodedInst.vpu.isOpMask := isOpMask
910    decodedInst.vpu.isDependOldvd := isVppu || isVecOPF || isVStore || (isDstMask && !isOpMask) || isNarrow || isVlx || isVma
911    decodedInst.vpu.isWritePartVd := isWritePartVd || isVlm || isVle && emulIsFrac
912    decodedInst.vpu.vstart := io.enq.vstart
913  }
914
915  decodedInst.vlsInstr := isVls
916
917  decodedInst.srcType(3) := Mux(inst.VM === 0.U && !isFpToVecInst, SrcType.vp, SrcType.DC) // mask src
918  decodedInst.srcType(4) := Mux(!isFpToVecInst, SrcType.vp, SrcType.DC) // vconfig
919
920  val uopInfoGen = Module(new UopInfoGen)
921  uopInfoGen.io.in.preInfo.typeOfSplit := decodedInst.uopSplitType
922  uopInfoGen.io.in.preInfo.vsew := decodedInst.vpu.vsew
923  uopInfoGen.io.in.preInfo.vlmul := decodedInst.vpu.vlmul
924  uopInfoGen.io.in.preInfo.vwidth := inst.RM
925  uopInfoGen.io.in.preInfo.vmvn := inst.IMM5_OPIVI(2, 0)
926  uopInfoGen.io.in.preInfo.nf := inst.NF
927  uopInfoGen.io.in.preInfo.isVlsr := decodedInst.fuOpType === VlduType.vlr || decodedInst.fuOpType === VstuType.vsr
928  uopInfoGen.io.in.preInfo.isVlsm := decodedInst.fuOpType === VlduType.vlm || decodedInst.fuOpType === VstuType.vsm
929  io.deq.isComplex := uopInfoGen.io.out.isComplex
930  io.deq.uopInfo.numOfUop := uopInfoGen.io.out.uopInfo.numOfUop
931  io.deq.uopInfo.numOfWB := uopInfoGen.io.out.uopInfo.numOfWB
932  io.deq.uopInfo.lmul := uopInfoGen.io.out.uopInfo.lmul
933
934  // for csrr vl instruction, convert to vsetvl
935  val Vl = 0xC20.U
936  val Vlenb = 0xC22.U
937  val isCsrInst = FuType.FuTypeOrR(decodedInst.fuType, FuType.csr)
938  //  rs1 is x0 or uimm == 0
939  val isCsrRead = (decodedInst.fuOpType === CSROpType.set || decodedInst.fuOpType === CSROpType.clr) && inst.RS1 === 0.U
940  val isCsrrVl = isCsrInst && isCsrRead && inst.CSRIDX === Vl
941  val isCsrrVlenb = isCsrInst && isCsrRead && inst.CSRIDX === Vlenb
942  when (isCsrrVl) {
943    // convert to vsetvl instruction
944    decodedInst.srcType(0) := SrcType.no
945    decodedInst.srcType(1) := SrcType.no
946    decodedInst.srcType(2) := SrcType.no
947    decodedInst.srcType(3) := SrcType.no
948    decodedInst.srcType(4) := SrcType.vp
949    decodedInst.lsrc(4) := Vl_IDX.U
950    decodedInst.waitForward := false.B
951    decodedInst.blockBackward := false.B
952  }.elsewhen(isCsrrVlenb){
953    // convert to addi instruction
954    decodedInst.srcType(0) := SrcType.reg
955    decodedInst.srcType(1) := SrcType.imm
956    decodedInst.srcType(2) := SrcType.no
957    decodedInst.srcType(3) := SrcType.no
958    decodedInst.srcType(4) := SrcType.no
959    decodedInst.selImm := SelImm.IMM_I
960    decodedInst.waitForward := false.B
961    decodedInst.blockBackward := false.B
962    decodedInst.canRobCompress := true.B
963  }
964
965  io.deq.decodedInst := decodedInst
966  io.deq.decodedInst.rfWen := (decodedInst.ldest =/= 0.U) && decodedInst.rfWen
967  // change vlsu to vseglsu when NF =/= 0.U
968  io.deq.decodedInst.fuType := Mux1H(Seq(
969    ( isCsrrVl) -> FuType.vsetfwf.U,
970    ( isCsrrVlenb) -> FuType.alu.U,
971    (!FuType.FuTypeOrR(decodedInst.fuType, FuType.vldu, FuType.vstu) && !isCsrrVl && !isCsrrVlenb) -> decodedInst.fuType,
972    ( 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,
973    // MOP === b00 && SUMOP === b01000: unit-stride whole register store
974    // MOP =/= b00                    : strided and indexed store
975    ( 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,
976    // MOP === b00 && LUMOP === b01000: unit-stride whole register load
977    // MOP =/= b00                    : strided and indexed load
978    ( 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,
979  ))
980  io.deq.decodedInst.fuOpType := Mux(isCsrrVlenb, ALUOpType.add, decodedInst.fuOpType)
981  io.deq.decodedInst.imm := Mux(isCsrrVlenb, (VLEN / 8).U, decodedInst.imm)
982  //-------------------------------------------------------------
983  // Debug Info
984//  XSDebug("in:  instr=%x pc=%x excepVec=%b crossPageIPFFix=%d\n",
985//    io.enq.ctrl_flow.instr, io.enq.ctrl_flow.pc, io.enq.ctrl_flow.exceptionVec.asUInt,
986//    io.enq.ctrl_flow.crossPageIPFFix)
987//  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",
988//    io.deq.cf_ctrl.ctrl.srcType(0), io.deq.cf_ctrl.ctrl.srcType(1), io.deq.cf_ctrl.ctrl.srcType(2),
989//    io.deq.cf_ctrl.ctrl.lsrc(0), io.deq.cf_ctrl.ctrl.lsrc(1), io.deq.cf_ctrl.ctrl.lsrc(2),
990//    io.deq.cf_ctrl.ctrl.ldest, io.deq.cf_ctrl.ctrl.fuType, io.deq.cf_ctrl.ctrl.fuOpType)
991//  XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d imm=%x\n",
992//    io.deq.cf_ctrl.ctrl.rfWen, io.deq.cf_ctrl.ctrl.fpWen, io.deq.cf_ctrl.ctrl.isXSTrap,
993//    io.deq.cf_ctrl.ctrl.noSpecExec, io.deq.cf_ctrl.ctrl.blockBackward, io.deq.cf_ctrl.ctrl.flushPipe,
994//    io.deq.cf_ctrl.ctrl.imm)
995//  XSDebug("out: excepVec=%b\n", io.deq.cf_ctrl.cf.exceptionVec.asUInt)
996}
997