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