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