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