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.DecodeLogic 23import freechips.rocketchip.rocket.Instructions._ 24import xiangshan.backend.decode.isa.bitfield.XSInstBitFields 25import xiangshan.backend.fu.fpu.FPU 26import xiangshan.backend.fu.vector.Bundles.{VSew, VLmul} 27import xiangshan.backend.Bundles.VPUCtrlSignals 28import xiangshan.{FPUCtrlSignals, XSModule} 29 30class FPToVecDecoder(implicit p: Parameters) extends XSModule { 31 val io = IO(new Bundle() { 32 val instr = Input(UInt(32.W)) 33 val vpuCtrl = Output(new VPUCtrlSignals) 34 }) 35 36 val inst = io.instr.asTypeOf(new XSInstBitFields) 37 val fpToVecInsts = Seq( 38 FADD_S, FSUB_S, FADD_D, FSUB_D, FADD_H, FSUB_H, 39 FEQ_S, FLT_S, FLE_S, FEQ_D, FLT_D, FLE_D, FEQ_H, FLT_H, FLE_H, 40 FMIN_S, FMAX_S, FMIN_D, FMAX_D, FMIN_H, FMAX_H, 41 FMUL_S, FMUL_D, FMUL_H, 42 FDIV_S, FDIV_D, FSQRT_S, FSQRT_D, FDIV_H, FSQRT_H, 43 FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D, FMADD_H, FMSUB_H, FNMADD_H, FNMSUB_H, 44 FCLASS_S, FCLASS_D, FSGNJ_S, FSGNJ_D, FSGNJX_S, FSGNJX_D, FSGNJN_S, FSGNJN_D, 45 FCLASS_H, FSGNJ_H, FSGNJX_H, FSGNJN_H, 46 // scalar cvt inst 47 FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S, 48 FCVT_W_D, FCVT_WU_D, FCVT_L_D, FCVT_LU_D, FCVT_S_D, FCVT_D_S, 49 FCVT_S_H, FCVT_H_S, FCVT_H_D, FCVT_D_H, 50 FMV_X_W, FMV_X_D, FMV_X_H, 51 FCVT_W_H, FCVT_WU_H, FCVT_L_H, FCVT_LU_H, 52 // zfa inst 53 FLEQ_H, FLEQ_S, FLEQ_D, FLTQ_H, FLTQ_S, FLTQ_D, FMINM_H, FMINM_S, FMINM_D, FMAXM_H, FMAXM_S, FMAXM_D, 54 FROUND_H, FROUND_S, FROUND_D, FROUNDNX_H, FROUNDNX_S, FROUNDNX_D, FCVTMOD_W_D, 55 ) 56 val isFpToVecInst = fpToVecInsts.map(io.instr === _).reduce(_ || _) 57 val isFP16Instrs = Seq( 58 // zfh inst 59 FADD_H, FSUB_H, FEQ_H, FLT_H, FLE_H, FMIN_H, FMAX_H, 60 FMUL_H, FDIV_H, FSQRT_H, 61 FMADD_H, FMSUB_H, FNMADD_H, FNMSUB_H, 62 FCLASS_H, FSGNJ_H, FSGNJX_H, FSGNJN_H, 63 // zfa inst 64 FLEQ_H, FLTQ_H, FMINM_H, FMAXM_H, 65 FROUND_H, FROUNDNX_H, 66 ) 67 val isFP16Instr = isFP16Instrs.map(io.instr === _).reduce(_ || _) 68 val isFP32Instrs = Seq( 69 FADD_S, FSUB_S, FEQ_S, FLT_S, FLE_S, FMIN_S, FMAX_S, 70 FMUL_S, FDIV_S, FSQRT_S, 71 FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, 72 FCLASS_S, FSGNJ_S, FSGNJX_S, FSGNJN_S, 73 // zfa inst 74 FLEQ_S, FLTQ_S, FMINM_S, FMAXM_S, 75 FROUND_S, FROUNDNX_S, 76 ) 77 val isFP32Instr = isFP32Instrs.map(io.instr === _).reduce(_ || _) 78 val isFP64Instrs = Seq( 79 FADD_D, FSUB_D, FEQ_D, FLT_D, FLE_D, FMIN_D, FMAX_D, 80 FMUL_D, FDIV_D, FSQRT_D, 81 FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D, 82 FCLASS_D, FSGNJ_D, FSGNJX_D, FSGNJN_D, 83 ) 84 val isFP64Instr = isFP64Instrs.map(io.instr === _).reduce(_ || _) 85 // scalar cvt inst 86 val isSew2Cvts = Seq( 87 FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S, 88 FCVT_W_D, FCVT_WU_D, FCVT_S_D, FCVT_D_S, 89 FMV_X_W, 90 // zfa inst 91 FCVTMOD_W_D, 92 ) 93 /* 94 The optype for FCVT_D_H and FCVT_H_D is the same, 95 so the two instructions are distinguished by sew. 96 FCVT_H_D:VSew.e64 97 FCVT_D_H:VSew.e16 98 */ 99 val isSew2Cvth = Seq( 100 FCVT_S_H, FCVT_H_S, FCVT_D_H, 101 FMV_X_H, 102 FCVT_W_H, FCVT_L_H, FCVT_H_W, 103 FCVT_H_L, FCVT_H_WU, FCVT_H_LU, 104 FCVT_WU_H, FCVT_LU_H, 105 ) 106 val isSew2Cvt32 = isSew2Cvts.map(io.instr === _).reduce(_ || _) 107 val isSew2Cvt16 = isSew2Cvth.map(io.instr === _).reduce(_ || _) 108 val isLmulMf4Cvts = Seq( 109 FCVT_W_S, FCVT_WU_S, 110 FMV_X_W, 111 ) 112 val isLmulMf4Cvt = isLmulMf4Cvts.map(io.instr === _).reduce(_ || _) 113 val needReverseInsts = Seq( 114 FADD_S, FSUB_S, FADD_D, FSUB_D, FADD_H, FSUB_H, 115 FEQ_S, FLT_S, FLE_S, FEQ_D, FLT_D, FLE_D, FEQ_H, FLT_H, FLE_H, 116 FMIN_S, FMAX_S, FMIN_D, FMAX_D, FMIN_H, FMAX_H, 117 FMUL_S, FMUL_D, FMUL_H, 118 FDIV_S, FDIV_D, FSQRT_S, FSQRT_D, FDIV_H, FSQRT_H, 119 FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D, 120 FMADD_H, FMSUB_H, FNMADD_H, FNMSUB_H, 121 FCLASS_S, FCLASS_D, FSGNJ_S, FSGNJ_D, FSGNJX_S, FSGNJX_D, FSGNJN_S, FSGNJN_D, 122 FCLASS_H, FSGNJ_H, FSGNJX_H, FSGNJN_H, 123 // zfa inst 124 FLEQ_H, FLEQ_S, FLEQ_D, FLTQ_H, FLTQ_S, FLTQ_D, FMINM_H, FMINM_S, FMINM_D, FMAXM_H, FMAXM_S, FMAXM_D, 125 ) 126 val needReverseInst = needReverseInsts.map(_ === inst.ALL).reduce(_ || _) 127 io.vpuCtrl := 0.U.asTypeOf(io.vpuCtrl) 128 io.vpuCtrl.fpu.isFpToVecInst := isFpToVecInst 129 io.vpuCtrl.fpu.isFP32Instr := isFP32Instr 130 io.vpuCtrl.fpu.isFP64Instr := isFP64Instr 131 io.vpuCtrl.vill := false.B 132 io.vpuCtrl.vma := true.B 133 io.vpuCtrl.vta := true.B 134 io.vpuCtrl.vsew := Mux(isFP32Instr || isSew2Cvt32, VSew.e32, Mux(isFP16Instr || isSew2Cvt16, VSew.e16, VSew.e64)) 135 io.vpuCtrl.vlmul := Mux(isFP32Instr || isLmulMf4Cvt, VLmul.mf4, VLmul.mf2) 136 io.vpuCtrl.vm := inst.VM 137 io.vpuCtrl.nf := inst.NF 138 io.vpuCtrl.veew := inst.WIDTH 139 io.vpuCtrl.isReverse := needReverseInst 140 io.vpuCtrl.isExt := false.B 141 io.vpuCtrl.isNarrow := false.B 142 io.vpuCtrl.isDstMask := false.B 143 io.vpuCtrl.isOpMask := false.B 144 io.vpuCtrl.isDependOldVd := false.B 145 io.vpuCtrl.isWritePartVd := false.B 146} 147 148 149class FPDecoder(implicit p: Parameters) extends XSModule{ 150 val io = IO(new Bundle() { 151 val instr = Input(UInt(32.W)) 152 val fpCtrl = Output(new FPUCtrlSignals) 153 }) 154 155 private val inst: XSInstBitFields = io.instr.asTypeOf(new XSInstBitFields) 156 157 def X = BitPat("b?") 158 def T = BitPat("b??") //type 159 def N = BitPat("b0") 160 def Y = BitPat("b1") 161 val s = BitPat(FPU.S(1,0)) 162 val d = BitPat(FPU.D(1,0)) 163 val i = BitPat(FPU.D(1,0)) 164 val h = BitPat(FPU.H(1,0)) 165 166 val default = List(X,T,T,N,N,N,X,X,X) 167 168 // isAddSub tagIn tagOut fromInt wflags fpWen div sqrt fcvt 169 val single: Array[(BitPat, List[BitPat])] = Array( 170 // IntToFP 171 FMV_W_X -> List(N,i,s,Y,N,Y,N,N,N), 172 FCVT_S_W -> List(N,i,s,Y,Y,Y,N,N,Y), 173 FCVT_S_WU-> List(N,i,s,Y,Y,Y,N,N,Y), 174 FCVT_S_L -> List(N,i,s,Y,Y,Y,N,N,Y), 175 FCVT_S_LU-> List(N,i,s,Y,Y,Y,N,N,Y), 176 // FPToInt 177 FMV_X_W -> List(N,d,i,N,N,N,N,N,N), // dont box result of fmv.fp.int 178 FCLASS_S -> List(N,s,i,N,N,N,N,N,N), 179 FCVT_W_S -> List(N,s,i,N,Y,N,N,N,Y), 180 FCVT_WU_S-> List(N,s,i,N,Y,N,N,N,Y), 181 FCVT_L_S -> List(N,s,i,N,Y,N,N,N,Y), 182 FCVT_LU_S-> List(N,s,i,N,Y,N,N,N,Y), 183 FEQ_S -> List(N,s,i,N,Y,N,N,N,N), 184 FLT_S -> List(N,s,i,N,Y,N,N,N,N), 185 FLE_S -> List(N,s,i,N,Y,N,N,N,N), 186 // FPToFP 187 FSGNJ_S -> List(N,s,s,N,N,Y,N,N,N), 188 FSGNJN_S -> List(N,s,s,N,N,Y,N,N,N), 189 FSGNJX_S -> List(N,s,s,N,N,Y,N,N,N), 190 FMIN_S -> List(N,s,s,N,Y,Y,N,N,N), 191 FMAX_S -> List(N,s,s,N,Y,Y,N,N,N), 192 FADD_S -> List(Y,s,s,N,Y,Y,N,N,N), 193 FSUB_S -> List(Y,s,s,N,Y,Y,N,N,N), 194 FMUL_S -> List(N,s,s,N,Y,Y,N,N,N), 195 FMADD_S -> List(N,s,s,N,Y,Y,N,N,N), 196 FMSUB_S -> List(N,s,s,N,Y,Y,N,N,N), 197 FNMADD_S -> List(N,s,s,N,Y,Y,N,N,N), 198 FNMSUB_S -> List(N,s,s,N,Y,Y,N,N,N), 199 FDIV_S -> List(N,s,s,N,Y,Y,Y,N,N), 200 FSQRT_S -> List(N,s,s,N,Y,Y,N,Y,N) 201 ) 202 203 204 // isAddSub tagIn tagOut fromInt wflags fpWen div sqrt fcvt 205 val double: Array[(BitPat, List[BitPat])] = Array( 206 FMV_D_X -> List(N,i,d,Y,N,Y,N,N,N), 207 FCVT_D_W -> List(N,i,d,Y,Y,Y,N,N,Y), 208 FCVT_D_WU-> List(N,i,d,Y,Y,Y,N,N,Y), 209 FCVT_D_L -> List(N,i,d,Y,Y,Y,N,N,Y), 210 FCVT_D_LU-> List(N,i,d,Y,Y,Y,N,N,Y), 211 FMV_X_D -> List(N,d,i,N,N,N,N,N,N), 212 FCLASS_D -> List(N,d,i,N,N,N,N,N,N), 213 FCVT_W_D -> List(N,d,i,N,Y,N,N,N,Y), 214 FCVT_WU_D-> List(N,d,i,N,Y,N,N,N,Y), 215 FCVT_L_D -> List(N,d,i,N,Y,N,N,N,Y), 216 FCVT_LU_D-> List(N,d,i,N,Y,N,N,N,Y), 217 FCVT_S_D -> List(N,d,s,N,Y,Y,N,N,Y), 218 FCVT_D_S -> List(N,s,d,N,Y,Y,N,N,Y), 219 FEQ_D -> List(N,d,i,N,Y,N,N,N,N), 220 FLT_D -> List(N,d,i,N,Y,N,N,N,N), 221 FLE_D -> List(N,d,i,N,Y,N,N,N,N), 222 FSGNJ_D -> List(N,d,d,N,N,Y,N,N,N), 223 FSGNJN_D -> List(N,d,d,N,N,Y,N,N,N), 224 FSGNJX_D -> List(N,d,d,N,N,Y,N,N,N), 225 FMIN_D -> List(N,d,d,N,Y,Y,N,N,N), 226 FMAX_D -> List(N,d,d,N,Y,Y,N,N,N), 227 FADD_D -> List(Y,d,d,N,Y,Y,N,N,N), 228 FSUB_D -> List(Y,d,d,N,Y,Y,N,N,N), 229 FMUL_D -> List(N,d,d,N,Y,Y,N,N,N), 230 FMADD_D -> List(N,d,d,N,Y,Y,N,N,N), 231 FMSUB_D -> List(N,d,d,N,Y,Y,N,N,N), 232 FNMADD_D -> List(N,d,d,N,Y,Y,N,N,N), 233 FNMSUB_D -> List(N,d,d,N,Y,Y,N,N,N), 234 FDIV_D -> List(N,d,d,N,Y,Y,Y,N,N), 235 FSQRT_D -> List(N,d,d,N,Y,Y,N,Y,N) 236 ) 237 238 val half : Array[(BitPat, List[BitPat])] = Array( 239 // IntToFP 240 FMV_H_X -> List(N,i,h,Y,N,Y,N,N,N), 241 FCVT_H_W -> List(N,i,h,Y,Y,Y,N,N,Y), 242 FCVT_H_WU-> List(N,i,h,Y,Y,Y,N,N,Y), 243 FCVT_H_L -> List(N,i,h,Y,Y,Y,N,N,Y), 244 FCVT_H_LU-> List(N,i,h,Y,Y,Y,N,N,Y), 245 // FPToInt 246 FMV_X_H -> List(N,h,i,N,N,N,N,N,N), // d or h ?? 247 FCLASS_H -> List(N,h,i,N,N,N,N,N,N), 248 FCVT_W_H -> List(N,h,i,N,Y,N,N,N,Y), 249 FCVT_WU_H-> List(N,h,i,N,Y,N,N,N,Y), 250 FCVT_L_H -> List(N,h,i,N,Y,N,N,N,Y), 251 FCVT_LU_H-> List(N,h,i,N,Y,N,N,N,Y), 252 FEQ_H -> List(N,h,i,N,Y,N,N,N,N), 253 FLT_H -> List(N,h,i,N,Y,N,N,N,N), 254 FLE_H -> List(N,h,i,N,Y,N,N,N,N), 255 // FPToFP 256 FSGNJ_H -> List(N,h,h,N,N,Y,N,N,N), 257 FSGNJN_H -> List(N,h,h,N,N,Y,N,N,N), 258 FSGNJX_H -> List(N,h,h,N,N,Y,N,N,N), 259 FMIN_H -> List(N,h,h,N,Y,Y,N,N,N), 260 FMAX_H -> List(N,h,h,N,Y,Y,N,N,N), 261 FADD_H -> List(Y,h,h,N,Y,Y,N,N,N), 262 FSUB_H -> List(Y,h,h,N,Y,Y,N,N,N), 263 FMUL_H -> List(N,h,h,N,Y,Y,N,N,N), 264 FMADD_H -> List(N,h,h,N,Y,Y,N,N,N), 265 FMSUB_H -> List(N,h,h,N,Y,Y,N,N,N), 266 FNMADD_H -> List(N,h,h,N,Y,Y,N,N,N), 267 FNMSUB_H -> List(N,h,h,N,Y,Y,N,N,N), 268 FDIV_H -> List(N,h,h,N,Y,Y,Y,N,N), 269 FSQRT_H -> List(N,h,h,N,Y,Y,N,Y,N) 270 ) 271 272 val table = single ++ double ++ half 273 274 val decoder = DecodeLogic(io.instr, default, table) 275 276 val ctrl = io.fpCtrl 277 val sigs = Seq(ctrl.typeTagOut, ctrl.wflags) 278 // TODO dirty code 279 sigs(0) := decoder(2) 280 sigs(1) := decoder(4) 281 ctrl.typ := inst.TYP 282 val isFP16Instrs = Seq( 283 // zfh inst 284 FADD_H, FSUB_H, FEQ_H, FLT_H, FLE_H, FMIN_H, FMAX_H, 285 FMUL_H, FDIV_H, FSQRT_H, 286 FMADD_H, FMSUB_H, FNMADD_H, FNMSUB_H, 287 FCLASS_H, FSGNJ_H, FSGNJX_H, FSGNJN_H, 288 // zfa inst 289 FLEQ_H, FLTQ_H, FMINM_H, FMAXM_H, 290 FROUND_H, FROUNDNX_H, 291 ) 292 val isFP16Instr = isFP16Instrs.map(io.instr === _).reduce(_ || _) 293 val isFP32Instrs = Seq( 294 FADD_S, FSUB_S, FEQ_S, FLT_S, FLE_S, FMIN_S, FMAX_S, 295 FMUL_S, FDIV_S, FSQRT_S, 296 FMADD_S, FMSUB_S, FNMADD_S, FNMSUB_S, 297 FCLASS_S, FSGNJ_S, FSGNJX_S, FSGNJN_S, 298 // zfa inst 299 FLEQ_S, FLTQ_S, FMINM_S, FMAXM_S, 300 FROUND_S, FROUNDNX_S, 301 ) 302 val isFP32Instr = isFP32Instrs.map(io.instr === _).reduce(_ || _) 303 val isFP64Instrs = Seq( 304 FADD_D, FSUB_D, FEQ_D, FLT_D, FLE_D, FMIN_D, FMAX_D, 305 FMUL_D, FDIV_D, FSQRT_D, 306 FMADD_D, FMSUB_D, FNMADD_D, FNMSUB_D, 307 FCLASS_D, FSGNJ_D, FSGNJX_D, FSGNJN_D, 308 ) 309 val isFP64Instr = isFP64Instrs.map(io.instr === _).reduce(_ || _) 310 // scalar cvt inst 311 val isSew2Cvts = Seq( 312 FCVT_W_S, FCVT_WU_S, FCVT_L_S, FCVT_LU_S, 313 FCVT_W_D, FCVT_WU_D, FCVT_S_D, FCVT_D_S, 314 FMV_X_W, 315 // zfa inst 316 FCVTMOD_W_D, 317 ) 318 /* 319 The optype for FCVT_D_H and FCVT_H_D is the same, 320 so the two instructions are distinguished by sew. 321 FCVT_H_D:VSew.e64 322 FCVT_D_H:VSew.e16 323 */ 324 val isSew2Cvth = Seq( 325 FCVT_S_H, FCVT_H_S, FCVT_D_H, 326 FMV_X_H, 327 FCVT_W_H, FCVT_L_H, FCVT_H_W, 328 FCVT_H_L, FCVT_H_WU, FCVT_H_LU, 329 FCVT_WU_H, FCVT_LU_H, 330 ) 331 val simpleFmt = Mux1H( 332 // scala format to vsew format, when inst.FMT === "b11".U, ctrl.fmt := "b00".U 333 Seq( 334 (inst.FMT === "b00".U) -> "b10".U, // S 335 (inst.FMT === "b01".U) -> "b11".U, // D 336 (inst.FMT === "b10".U) -> "b01".U, // H 337 ) 338 ) 339 val isSew2Cvt32 = isSew2Cvts.map(io.instr === _).reduce(_ || _) 340 val isSew2Cvt16 = isSew2Cvth.map(io.instr === _).reduce(_ || _) 341 ctrl.fmt := Mux(isFP32Instr || isSew2Cvt32, VSew.e32, Mux(isFP16Instr || isSew2Cvt16, VSew.e16, VSew.e64)) 342 ctrl.rm := inst.RM 343 344 val fmaTable: Array[(BitPat, List[BitPat])] = Array( 345 FADD_S -> List(BitPat("b00"),N), 346 FADD_D -> List(BitPat("b00"),N), 347 FADD_H -> List(BitPat("b00"),N), 348 FSUB_S -> List(BitPat("b01"),N), 349 FSUB_D -> List(BitPat("b01"),N), 350 FSUB_H -> List(BitPat("b01"),N), 351 FMUL_S -> List(BitPat("b00"),N), 352 FMUL_D -> List(BitPat("b00"),N), 353 FMUL_H -> List(BitPat("b00"),N), 354 FMADD_S -> List(BitPat("b00"),Y), 355 FMADD_D -> List(BitPat("b00"),Y), 356 FMADD_H -> List(BitPat("b00"),Y), 357 FMSUB_S -> List(BitPat("b01"),Y), 358 FMSUB_D -> List(BitPat("b01"),Y), 359 FMSUB_H -> List(BitPat("b01"),Y), 360 FNMADD_S-> List(BitPat("b11"),Y), 361 FNMADD_D-> List(BitPat("b11"),Y), 362 FNMADD_H-> List(BitPat("b11"),Y), 363 FNMSUB_S-> List(BitPat("b10"),Y), 364 FNMSUB_D-> List(BitPat("b10"),Y), 365 FNMSUB_H-> List(BitPat("b10"),Y) 366 ) 367 val fmaDefault = List(BitPat("b??"), N) 368} 369