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