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