1/*************************************************************************************** 2 * Copyright (c) 2024 Beijing Institute of Open Source Chip (BOSC) 3 * Copyright (c) 2020-2024 Institute of Computing Technology, Chinese Academy of Sciences 4 * Copyright (c) 2020-2021 Peng Cheng Laboratory 5 * 6 * XiangShan is licensed under Mulan PSL v2. 7 * You can use this software according to the terms and conditions of the Mulan PSL v2. 8 * You may obtain a copy of Mulan PSL v2 at: 9 * http://license.coscl.org.cn/MulanPSL2 10 * 11 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 12 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 13 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 14 * 15 * See the Mulan PSL v2 for more details. 16 ***************************************************************************************/ 17 18package xiangshan.backend.decode 19 20import org.chipsalliance.cde.config.Parameters 21import chisel3._ 22import chisel3.util._ 23import freechips.rocketchip.rocket.Instructions 24import freechips.rocketchip.util.uintToBitPat 25import utils._ 26import utility._ 27import xiangshan.ExceptionNO.illegalInstr 28import xiangshan._ 29import xiangshan.backend.fu.fpu.FPU 30import xiangshan.backend.fu.FuType 31import freechips.rocketchip.rocket.Instructions._ 32import xiangshan.backend.Bundles.{DecodedInst, StaticInst} 33import xiangshan.backend.decode.isa.bitfield.XSInstBitFields 34import xiangshan.backend.fu.vector.Bundles.{VSew, VType, VLmul, Vl} 35import yunsuan.VpermType 36import chisel3.util.experimental.decode.{QMCMinimizer, TruthTable, decoder} 37 38class indexedLSUopTable(uopIdx:Int) extends Module { 39 val src = IO(Input(UInt(4.W))) 40 val outOffsetVs2 = IO(Output(UInt(3.W))) 41 val outOffsetVd = IO(Output(UInt(3.W))) 42 def genCsBundle_VEC_INDEXED_LDST(lmul:Int, emul:Int, uopIdx:Int): (Int, Int) ={ 43 // only consider non segment indexed load/store 44 if (lmul < emul) { // lmul < emul, uop num is depend on emul * nf 45 var offset = 1 << (emul - lmul) 46 for (i <- 0 until (1 << emul)) { 47 if (uopIdx == i) { 48 return (i, i / offset) 49 } 50 } 51 } else { // lmul > emul, uop num is depend on lmul * nf 52 var offset = 1 << (lmul - emul) 53 for (i <- 0 until (1 << lmul)) { 54 if (uopIdx == i) { 55 return (i / offset, i) 56 } 57 } 58 } 59 return (0, 0) 60 } 61 // strided load/store 62 var combVemulNf : Seq[(Int, Int, Int, Int)] = Seq() 63 for (emul <- 0 until 4) { 64 for (lmul <- 0 until 4) { 65 var offset = genCsBundle_VEC_INDEXED_LDST(lmul, emul, uopIdx) 66 var offsetVs2 = offset._1 67 var offsetVd = offset._2 68 combVemulNf :+= (emul, lmul, offsetVs2, offsetVd) 69 } 70 } 71 val out = decoder(QMCMinimizer, src, TruthTable(combVemulNf.map { 72 case (emul, lmul, offsetVs2, offsetVd) => 73 (BitPat((emul << 2 | lmul).U(4.W)), BitPat((offsetVs2 << 3 | offsetVd).U(6.W))) 74 }, BitPat.N(6))) 75 outOffsetVs2 := out(5, 3) 76 outOffsetVd := out(2, 0) 77} 78 79trait VectorConstants { 80 val MAX_VLMUL = 8 81 val VECTOR_TMP_REG_LMUL = 32 // 32~46 -> 15 82 val VECTOR_COMPRESS = 1 // in v0 regfile 83 val MAX_INDEXED_LS_UOPNUM = 64 84} 85 86class DecodeUnitCompInput(implicit p: Parameters) extends XSBundle { 87 val simpleDecodedInst = new DecodedInst 88 val uopInfo = new UopInfo 89} 90 91class DecodeUnitCompOutput(implicit p: Parameters) extends XSBundle { 92 val complexDecodedInsts = Vec(RenameWidth, DecoupledIO(new DecodedInst)) 93} 94 95class DecodeUnitCompIO(implicit p: Parameters) extends XSBundle { 96 val redirect = Input(Bool()) 97 val csrCtrl = Input(new CustomCSRCtrlIO) 98 val vtypeBypass = Input(new VType) 99 // When the first inst in decode vector is complex inst, pass it in 100 val in = Flipped(DecoupledIO(new DecodeUnitCompInput)) 101 val out = new DecodeUnitCompOutput 102 val complexNum = Output(UInt(3.W)) 103} 104 105/** 106 * @author zly 107 */ 108class DecodeUnitComp()(implicit p : Parameters) extends XSModule with DecodeUnitConstants with VectorConstants { 109 val io = IO(new DecodeUnitCompIO) 110 111 // alias 112 private val inReady = io.in.ready 113 private val inValid = io.in.valid 114 private val inDecodedInst = WireInit(io.in.bits.simpleDecodedInst) 115 private val inInstFields = io.in.bits.simpleDecodedInst.instr.asTypeOf(new XSInstBitFields) 116 private val inUopInfo = io.in.bits.uopInfo 117 private val outValids = io.out.complexDecodedInsts.map(_.valid) 118 private val outReadys = io.out.complexDecodedInsts.map(_.ready) 119 private val outDecodedInsts = io.out.complexDecodedInsts.map(_.bits) 120 private val outComplexNum = io.complexNum 121 122 val maxUopSize = MaxUopSize 123 when (io.in.fire && io.in.bits.simpleDecodedInst.isVset) { 124 when(inInstFields.RD === 0.U && inInstFields.RS1 === 0.U) { 125 inDecodedInst.fuOpType := VSETOpType.keepVl(io.in.bits.simpleDecodedInst.fuOpType) 126 }.elsewhen(inInstFields.RS1 === 0.U) { 127 inDecodedInst.fuOpType := VSETOpType.setVlmax(io.in.bits.simpleDecodedInst.fuOpType) 128 } 129 } 130 131 val latchedInst = RegEnable(inDecodedInst, inValid && inReady) 132 val latchedUopInfo = RegEnable(inUopInfo, inValid && inReady) 133 //input bits 134 private val instFields: XSInstBitFields = latchedInst.instr.asTypeOf(new XSInstBitFields) 135 136 val src1 = Cat(0.U(1.W), instFields.RS1) 137 val src2 = Cat(0.U(1.W), instFields.RS2) 138 val dest = Cat(0.U(1.W), instFields.RD) 139 140 val nf = instFields.NF 141 val width = instFields.WIDTH(1, 0) 142 143 //output of DecodeUnit 144 val numOfUop = Wire(UInt(log2Up(maxUopSize).W)) 145 val numOfWB = Wire(UInt(log2Up(maxUopSize).W)) 146 val lmul = Wire(UInt(4.W)) 147 val isVsetSimple = Wire(Bool()) 148 149 val indexedLSRegOffset = Seq.tabulate(MAX_VLMUL)(i => Module(new indexedLSUopTable(i))) 150 indexedLSRegOffset.map(_.src := 0.U) 151 152 //pre decode 153 lmul := latchedUopInfo.lmul 154 isVsetSimple := latchedInst.isVset 155 val vlmulReg = latchedInst.vpu.vlmul 156 val vsewReg = latchedInst.vpu.vsew 157 val vstartReg = latchedInst.vpu.vstart 158 159 //Type of uop Div 160 val typeOfSplit = latchedInst.uopSplitType 161 val src1Type = latchedInst.srcType(0) 162 val src1IsImm = src1Type === SrcType.imm 163 val src1IsFp = src1Type === SrcType.fp 164 165 val isVstore = FuType.isVStore(latchedInst.fuType) 166 167 // exception generator 168 val vecException = Module(new VecExceptionGen) 169 vecException.io.inst := latchedInst.instr 170 vecException.io.decodedInst := latchedInst 171 vecException.io.vtype := latchedInst.vpu.vtype 172 vecException.io.vstart := latchedInst.vpu.vstart 173 val illegalInst = vecException.io.illegalInst 174 175 numOfUop := latchedUopInfo.numOfUop 176 numOfWB := latchedUopInfo.numOfWB 177 178 //uops dispatch 179 val s_idle :: s_active :: Nil = Enum(2) 180 val state = RegInit(s_idle) 181 val stateNext = WireDefault(state) 182 val numDecodedUop = RegInit(0.U(log2Up(maxUopSize).W)) 183 val uopRes = RegInit(0.U(log2Up(maxUopSize).W)) 184 val uopResNext = WireInit(uopRes) 185 val e64 = 3.U(2.W) 186 val isUsSegment = instFields.MOP === 0.U && ((nf =/= 0.U && instFields.LUMOP === 0.U) || instFields.LUMOP === "b10000".U) 187 val isIxSegment = instFields.MOP(0) === 1.U && nf =/= 0.U 188 val isSdSegment = instFields.MOP === "b10".U && nf =/= 0.U 189 190 //uop div up to maxUopSize 191 val csBundle = Wire(Vec(maxUopSize, new DecodedInst)) 192 val fixedDecodedInst = Wire(Vec(maxUopSize, new DecodedInst)) 193 194 csBundle.foreach { case dst => 195 dst := latchedInst 196 dst.numUops := latchedUopInfo.numOfUop 197 dst.numWB := latchedUopInfo.numOfWB 198 dst.exceptionVec(ExceptionNO.EX_II) := latchedInst.exceptionVec(ExceptionNO.EX_II) || illegalInst 199 dst.firstUop := false.B 200 dst.lastUop := false.B 201 dst.vlsInstr := false.B 202 } 203 204 csBundle(0).firstUop := true.B 205 csBundle(numOfUop - 1.U).lastUop := true.B 206 207 // when vstart is not zero, the last uop will modify vstart to zero 208 // therefore, blockback and flush pipe 209 csBundle(numOfUop - 1.U).blockBackward := vstartReg =/= 0.U 210 csBundle(0.U).flushPipe := vstartReg =/= 0.U 211 212 switch(typeOfSplit) { 213 is(UopSplitType.AMO_CAS_W) { 214 csBundle(0).uopIdx := 0.U 215 csBundle(0).fuOpType := Cat(1.U(3.W), LSUOpType.amocas_w) 216 csBundle(0).lsrc(0) := 0.U 217 csBundle(0).lsrc(1) := src2 218 csBundle(0).rfWen := false.B 219 csBundle(0).waitForward := true.B 220 csBundle(0).blockBackward := false.B 221 222 csBundle(1).uopIdx := 1.U 223 csBundle(1).fuOpType := Cat(0.U(3.W), LSUOpType.amocas_w) 224 csBundle(1).lsrc(0) := src1 225 csBundle(1).lsrc(1) := dest 226 csBundle(1).waitForward := false.B 227 csBundle(1).blockBackward := true.B 228 } 229 is(UopSplitType.AMO_CAS_D) { 230 csBundle(0).uopIdx := 0.U 231 csBundle(0).fuOpType := Cat(1.U(3.W), LSUOpType.amocas_d) 232 csBundle(0).lsrc(0) := 0.U 233 csBundle(0).lsrc(1) := src2 234 csBundle(0).rfWen := false.B 235 csBundle(0).waitForward := true.B 236 csBundle(0).blockBackward := false.B 237 238 csBundle(1).uopIdx := 1.U 239 csBundle(1).fuOpType := Cat(0.U(3.W), LSUOpType.amocas_d) 240 csBundle(1).lsrc(0) := src1 241 csBundle(1).lsrc(1) := dest 242 csBundle(1).waitForward := false.B 243 csBundle(1).blockBackward := true.B 244 } 245 is(UopSplitType.AMO_CAS_Q) { 246 csBundle(0).uopIdx := 0.U 247 csBundle(0).fuOpType := Cat(1.U(3.W), LSUOpType.amocas_q) 248 csBundle(0).lsrc(0) := 0.U 249 csBundle(0).lsrc(1) := src2 250 csBundle(0).rfWen := false.B 251 csBundle(0).waitForward := true.B 252 csBundle(0).blockBackward := false.B 253 254 csBundle(1).uopIdx := 1.U 255 csBundle(1).fuOpType := Cat(0.U(3.W), LSUOpType.amocas_q) 256 csBundle(1).lsrc(0) := src1 257 csBundle(1).lsrc(1) := dest 258 csBundle(1).waitForward := false.B 259 csBundle(1).blockBackward := false.B 260 261 csBundle(2).uopIdx := 2.U 262 csBundle(2).fuOpType := Cat(3.U(3.W), LSUOpType.amocas_q) 263 csBundle(2).lsrc(0) := 0.U 264 csBundle(2).lsrc(1) := Mux(src2 === 0.U, 0.U, src2 + 1.U) 265 csBundle(2).rfWen := false.B 266 csBundle(2).waitForward := false.B 267 csBundle(2).blockBackward := false.B 268 269 csBundle(3).uopIdx := 3.U 270 csBundle(3).fuOpType := Cat(2.U(3.W), LSUOpType.amocas_q) 271 csBundle(3).lsrc(0) := 0.U 272 csBundle(3).lsrc(1) := Mux(dest === 0.U, 0.U, dest + 1.U) 273 csBundle(3).ldest := Mux(dest === 0.U, 0.U, dest + 1.U) 274 csBundle(3).waitForward := false.B 275 csBundle(3).blockBackward := true.B 276 } 277 is(UopSplitType.VSET) { 278 // In simple decoder, rfWen and vecWen are not set 279 when(isVsetSimple) { 280 // Default 281 // uop0 set rd, never flushPipe 282 csBundle(0).fuType := FuType.vsetiwi.U 283 csBundle(0).flushPipe := Mux(VSETOpType.isVsetvl(latchedInst.fuOpType), true.B, vstartReg =/= 0.U) 284 csBundle(0).blockBackward := false.B 285 csBundle(0).rfWen := true.B 286 // uop1 set vl, vsetvl will flushPipe 287 csBundle(1).ldest := Vl_IDX.U 288 csBundle(1).vecWen := false.B 289 csBundle(1).vlWen := true.B 290 csBundle(1).flushPipe := false.B 291 csBundle(1).blockBackward := Mux(VSETOpType.isVsetvl(latchedInst.fuOpType), true.B, vstartReg =/= 0.U) 292 when(VSETOpType.isVsetvli(latchedInst.fuOpType) && dest === 0.U && src1 === 0.U) { 293 // write nothing, uop0 is a nop instruction 294 csBundle(0).rfWen := false.B 295 csBundle(0).fpWen := false.B 296 csBundle(0).vecWen := false.B 297 csBundle(0).vlWen := false.B 298 csBundle(1).fuType := FuType.vsetfwf.U 299 csBundle(1).srcType(0) := SrcType.no 300 csBundle(1).srcType(2) := SrcType.no 301 csBundle(1).srcType(3) := SrcType.no 302 csBundle(1).srcType(4) := SrcType.vp 303 csBundle(1).lsrc(4) := Vl_IDX.U 304 }.elsewhen(VSETOpType.isVsetvl(latchedInst.fuOpType) && dest === 0.U && src1 === 0.U) { 305 // uop0: mv vtype gpr to vector region 306 csBundle(0).srcType(0) := SrcType.xp 307 csBundle(0).srcType(1) := SrcType.no 308 csBundle(0).lsrc(0) := src2 309 csBundle(0).lsrc(1) := 0.U 310 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 311 csBundle(0).fuType := FuType.i2v.U 312 csBundle(0).fuOpType := Cat(IF2VectorType.i2Vec(2, 0), e64) 313 csBundle(0).rfWen := false.B 314 csBundle(0).fpWen := false.B 315 csBundle(0).vecWen := true.B 316 csBundle(0).vlWen := false.B 317 // uop1: uvsetvcfg_vv 318 csBundle(1).fuType := FuType.vsetfwf.U 319 // vl 320 csBundle(1).srcType(0) := SrcType.no 321 csBundle(1).srcType(2) := SrcType.no 322 csBundle(1).srcType(3) := SrcType.no 323 csBundle(1).srcType(4) := SrcType.vp 324 csBundle(1).lsrc(4) := Vl_IDX.U 325 // vtype 326 csBundle(1).srcType(1) := SrcType.vp 327 csBundle(1).lsrc(1) := VECTOR_TMP_REG_LMUL.U 328 csBundle(1).vecWen := false.B 329 csBundle(1).vlWen := true.B 330 csBundle(1).ldest := Vl_IDX.U 331 }.elsewhen(dest === 0.U) { 332 // write nothing, uop0 is a nop instruction 333 csBundle(0).rfWen := false.B 334 csBundle(0).fpWen := false.B 335 csBundle(0).vecWen := false.B 336 csBundle(0).vlWen := false.B 337 }.elsewhen(VSETOpType.isVsetvl(latchedInst.fuOpType)) { 338 // because vsetvl may modified src2 when src2 == rd, 339 // we need to modify vd in second uop to avoid dependency 340 // uop0 set vl 341 csBundle(0).fuType := FuType.vsetiwf.U 342 csBundle(0).ldest := Vl_IDX.U 343 csBundle(0).rfWen := false.B 344 csBundle(0).vlWen := true.B 345 // uop1 set rd 346 csBundle(1).fuType := FuType.vsetiwi.U 347 csBundle(1).ldest := dest 348 csBundle(1).rfWen := true.B 349 csBundle(1).vlWen := false.B 350 } 351 // use bypass vtype from vtypeGen 352 csBundle(0).vpu.connectVType(io.vtypeBypass) 353 csBundle(1).vpu.connectVType(io.vtypeBypass) 354 } 355 } 356 is(UopSplitType.VEC_VVV) { 357 for (i <- 0 until MAX_VLMUL) { 358 csBundle(i).lsrc(0) := src1 + i.U 359 csBundle(i).lsrc(1) := src2 + i.U 360 csBundle(i).lsrc(2) := dest + i.U 361 csBundle(i).ldest := dest + i.U 362 csBundle(i).uopIdx := i.U 363 } 364 } 365 is(UopSplitType.VEC_VFV) { 366 /* 367 f to vector move 368 */ 369 csBundle(0).srcType(0) := SrcType.fp 370 csBundle(0).srcType(1) := SrcType.imm 371 csBundle(0).srcType(2) := SrcType.imm 372 csBundle(0).lsrc(1) := 0.U 373 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 374 csBundle(0).fuType := FuType.f2v.U 375 csBundle(0).fuOpType := Cat(IF2VectorType.fDup2Vec(2, 0), vsewReg) 376 csBundle(0).vecWen := true.B 377 csBundle(0).vpu.isReverse := false.B 378 /* 379 LMUL 380 */ 381 for (i <- 0 until MAX_VLMUL) { 382 csBundle(i + 1).srcType(0) := SrcType.vp 383 csBundle(i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 384 csBundle(i + 1).lsrc(1) := src2 + i.U 385 csBundle(i + 1).lsrc(2) := dest + i.U 386 csBundle(i + 1).ldest := dest + i.U 387 csBundle(i + 1).uopIdx := i.U 388 } 389 } 390 is(UopSplitType.VEC_EXT2) { 391 for (i <- 0 until MAX_VLMUL / 2) { 392 csBundle(2 * i).lsrc(1) := src2 + i.U 393 csBundle(2 * i).lsrc(2) := dest + (2 * i).U 394 csBundle(2 * i).ldest := dest + (2 * i).U 395 csBundle(2 * i).uopIdx := (2 * i).U 396 csBundle(2 * i + 1).lsrc(1) := src2 + i.U 397 csBundle(2 * i + 1).lsrc(2) := dest + (2 * i + 1).U 398 csBundle(2 * i + 1).ldest := dest + (2 * i + 1).U 399 csBundle(2 * i + 1).uopIdx := (2 * i + 1).U 400 } 401 } 402 is(UopSplitType.VEC_EXT4) { 403 for (i <- 0 until MAX_VLMUL / 4) { 404 csBundle(4 * i).lsrc(1) := src2 + i.U 405 csBundle(4 * i).lsrc(2) := dest + (4 * i).U 406 csBundle(4 * i).ldest := dest + (4 * i).U 407 csBundle(4 * i).uopIdx := (4 * i).U 408 csBundle(4 * i + 1).lsrc(1) := src2 + i.U 409 csBundle(4 * i + 1).lsrc(2) := dest + (4 * i + 1).U 410 csBundle(4 * i + 1).ldest := dest + (4 * i + 1).U 411 csBundle(4 * i + 1).uopIdx := (4 * i + 1).U 412 csBundle(4 * i + 2).lsrc(1) := src2 + i.U 413 csBundle(4 * i + 2).lsrc(2) := dest + (4 * i + 2).U 414 csBundle(4 * i + 2).ldest := dest + (4 * i + 2).U 415 csBundle(4 * i + 2).uopIdx := (4 * i + 2).U 416 csBundle(4 * i + 3).lsrc(1) := src2 + i.U 417 csBundle(4 * i + 3).lsrc(2) := dest + (4 * i + 3).U 418 csBundle(4 * i + 3).ldest := dest + (4 * i + 3).U 419 csBundle(4 * i + 3).uopIdx := (4 * i + 3).U 420 } 421 } 422 is(UopSplitType.VEC_EXT8) { 423 for (i <- 0 until MAX_VLMUL) { 424 csBundle(i).lsrc(1) := src2 425 csBundle(i).lsrc(2) := dest + i.U 426 csBundle(i).ldest := dest + i.U 427 csBundle(i).uopIdx := i.U 428 } 429 } 430 is(UopSplitType.VEC_0XV) { 431 /* 432 i/f to vector move 433 */ 434 csBundle(0).srcType(0) := Mux(src1IsFp, SrcType.fp, SrcType.reg) 435 csBundle(0).srcType(1) := SrcType.imm 436 csBundle(0).srcType(2) := SrcType.imm 437 csBundle(0).lsrc(1) := 0.U 438 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 439 csBundle(0).fuType := Mux(src1IsFp, FuType.f2v.U, FuType.i2v.U) 440 csBundle(0).fuOpType := Cat(Mux(src1IsFp, IF2VectorType.fDup2Vec(2, 0), IF2VectorType.i2Vec(2, 0)), vsewReg) 441 csBundle(0).rfWen := false.B 442 csBundle(0).fpWen := false.B 443 csBundle(0).vecWen := true.B 444 /* 445 vmv.s.x 446 */ 447 csBundle(1).srcType(0) := SrcType.vp 448 csBundle(1).srcType(1) := SrcType.imm 449 csBundle(1).srcType(2) := SrcType.vp 450 csBundle(1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 451 csBundle(1).lsrc(1) := 0.U 452 csBundle(1).lsrc(2) := dest 453 csBundle(1).ldest := dest 454 csBundle(1).rfWen := false.B 455 csBundle(1).fpWen := false.B 456 csBundle(1).vecWen := true.B 457 csBundle(1).uopIdx := 0.U 458 } 459 is(UopSplitType.VEC_VXV) { 460 /* 461 i to vector move 462 */ 463 csBundle(0).srcType(0) := Mux(src1IsImm, SrcType.imm, SrcType.reg) 464 csBundle(0).srcType(1) := SrcType.imm 465 csBundle(0).srcType(2) := SrcType.imm 466 csBundle(0).lsrc(1) := 0.U 467 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 468 csBundle(0).fuType := FuType.i2v.U 469 csBundle(0).fuOpType := Cat(Mux(src1IsImm, IF2VectorType.immDup2Vec(2, 0), IF2VectorType.iDup2Vec(2, 0)), vsewReg) 470 csBundle(0).vecWen := true.B 471 csBundle(0).vpu.isReverse := false.B 472 /* 473 LMUL 474 */ 475 for (i <- 0 until MAX_VLMUL) { 476 csBundle(i + 1).srcType(0) := SrcType.vp 477 csBundle(i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 478 csBundle(i + 1).lsrc(1) := src2 + i.U 479 csBundle(i + 1).lsrc(2) := dest + i.U 480 csBundle(i + 1).ldest := dest + i.U 481 csBundle(i + 1).uopIdx := i.U 482 } 483 } 484 is(UopSplitType.VEC_VVW) { 485 for (i <- 0 until MAX_VLMUL / 2) { 486 csBundle(2 * i).lsrc(0) := src1 + i.U 487 csBundle(2 * i).lsrc(1) := src2 + i.U 488 csBundle(2 * i).lsrc(2) := dest + (2 * i).U 489 csBundle(2 * i).ldest := dest + (2 * i).U 490 csBundle(2 * i).uopIdx := (2 * i).U 491 csBundle(2 * i + 1).lsrc(0) := src1 + i.U 492 csBundle(2 * i + 1).lsrc(1) := src2 + i.U 493 csBundle(2 * i + 1).lsrc(2) := dest + (2 * i + 1).U 494 csBundle(2 * i + 1).ldest := dest + (2 * i + 1).U 495 csBundle(2 * i + 1).uopIdx := (2 * i + 1).U 496 } 497 } 498 is(UopSplitType.VEC_VFW) { 499 /* 500 f to vector move 501 */ 502 csBundle(0).srcType(0) := SrcType.fp 503 csBundle(0).srcType(1) := SrcType.imm 504 csBundle(0).srcType(2) := SrcType.imm 505 csBundle(0).lsrc(1) := 0.U 506 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 507 csBundle(0).fuType := FuType.f2v.U 508 csBundle(0).fuOpType := Cat(IF2VectorType.fDup2Vec(2, 0), vsewReg) 509 csBundle(0).rfWen := false.B 510 csBundle(0).fpWen := false.B 511 csBundle(0).vecWen := true.B 512 513 for (i <- 0 until MAX_VLMUL / 2) { 514 csBundle(2 * i + 1).srcType(0) := SrcType.vp 515 csBundle(2 * i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 516 csBundle(2 * i + 1).lsrc(1) := src2 + i.U 517 csBundle(2 * i + 1).lsrc(2) := dest + (2 * i).U 518 csBundle(2 * i + 1).ldest := dest + (2 * i).U 519 csBundle(2 * i + 1).uopIdx := (2 * i).U 520 csBundle(2 * i + 2).srcType(0) := SrcType.vp 521 csBundle(2 * i + 2).lsrc(0) := VECTOR_TMP_REG_LMUL.U 522 csBundle(2 * i + 2).lsrc(1) := src2 + i.U 523 csBundle(2 * i + 2).lsrc(2) := dest + (2 * i + 1).U 524 csBundle(2 * i + 2).ldest := dest + (2 * i + 1).U 525 csBundle(2 * i + 2).uopIdx := (2 * i + 1).U 526 } 527 } 528 is(UopSplitType.VEC_WVW) { 529 for (i <- 0 until MAX_VLMUL / 2) { 530 csBundle(2 * i).lsrc(0) := src1 + i.U 531 csBundle(2 * i).lsrc(1) := src2 + (2 * i).U 532 csBundle(2 * i).lsrc(2) := dest + (2 * i).U 533 csBundle(2 * i).ldest := dest + (2 * i).U 534 csBundle(2 * i).uopIdx := (2 * i).U 535 csBundle(2 * i + 1).lsrc(0) := src1 + i.U 536 csBundle(2 * i + 1).lsrc(1) := src2 + (2 * i + 1).U 537 csBundle(2 * i + 1).lsrc(2) := dest + (2 * i + 1).U 538 csBundle(2 * i + 1).ldest := dest + (2 * i + 1).U 539 csBundle(2 * i + 1).uopIdx := (2 * i + 1).U 540 } 541 } 542 is(UopSplitType.VEC_VXW) { 543 /* 544 i to vector move 545 */ 546 csBundle(0).srcType(0) := Mux(src1IsImm, SrcType.imm, SrcType.reg) 547 csBundle(0).srcType(1) := SrcType.imm 548 csBundle(0).srcType(2) := SrcType.imm 549 csBundle(0).lsrc(1) := 0.U 550 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 551 csBundle(0).fuType := FuType.i2v.U 552 csBundle(0).fuOpType := Cat(Mux(src1IsImm, IF2VectorType.immDup2Vec(2, 0), IF2VectorType.iDup2Vec(2, 0)), vsewReg) 553 csBundle(0).vecWen := true.B 554 555 for (i <- 0 until MAX_VLMUL / 2) { 556 csBundle(2 * i + 1).srcType(0) := SrcType.vp 557 csBundle(2 * i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 558 csBundle(2 * i + 1).lsrc(1) := src2 + i.U 559 csBundle(2 * i + 1).lsrc(2) := dest + (2 * i).U 560 csBundle(2 * i + 1).ldest := dest + (2 * i).U 561 csBundle(2 * i + 1).uopIdx := (2 * i).U 562 csBundle(2 * i + 2).srcType(0) := SrcType.vp 563 csBundle(2 * i + 2).lsrc(0) := VECTOR_TMP_REG_LMUL.U 564 csBundle(2 * i + 2).lsrc(1) := src2 + i.U 565 csBundle(2 * i + 2).lsrc(2) := dest + (2 * i + 1).U 566 csBundle(2 * i + 2).ldest := dest + (2 * i + 1).U 567 csBundle(2 * i + 2).uopIdx := (2 * i + 1).U 568 } 569 } 570 is(UopSplitType.VEC_WXW) { 571 /* 572 i to vector move 573 */ 574 csBundle(0).srcType(0) := SrcType.reg 575 csBundle(0).srcType(1) := SrcType.imm 576 csBundle(0).srcType(2) := SrcType.imm 577 csBundle(0).lsrc(1) := 0.U 578 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 579 csBundle(0).fuType := FuType.i2v.U 580 csBundle(0).fuOpType := Cat(IF2VectorType.iDup2Vec(2, 0), vsewReg) 581 csBundle(0).vecWen := true.B 582 583 for (i <- 0 until MAX_VLMUL / 2) { 584 csBundle(2 * i + 1).srcType(0) := SrcType.vp 585 csBundle(2 * i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 586 csBundle(2 * i + 1).lsrc(1) := src2 + (2 * i).U 587 csBundle(2 * i + 1).lsrc(2) := dest + (2 * i).U 588 csBundle(2 * i + 1).ldest := dest + (2 * i).U 589 csBundle(2 * i + 1).uopIdx := (2 * i).U 590 csBundle(2 * i + 2).srcType(0) := SrcType.vp 591 csBundle(2 * i + 2).lsrc(0) := VECTOR_TMP_REG_LMUL.U 592 csBundle(2 * i + 2).lsrc(1) := src2 + (2 * i + 1).U 593 csBundle(2 * i + 2).lsrc(2) := dest + (2 * i + 1).U 594 csBundle(2 * i + 2).ldest := dest + (2 * i + 1).U 595 csBundle(2 * i + 2).uopIdx := (2 * i + 1).U 596 } 597 } 598 is(UopSplitType.VEC_WVV) { 599 for (i <- 0 until MAX_VLMUL / 2) { 600 601 csBundle(2 * i).lsrc(0) := src1 + i.U 602 csBundle(2 * i).lsrc(1) := src2 + (2 * i).U 603 csBundle(2 * i).lsrc(2) := dest + i.U 604 csBundle(2 * i).ldest := dest + i.U 605 csBundle(2 * i).uopIdx := (2 * i).U 606 csBundle(2 * i + 1).lsrc(0) := src1 + i.U 607 csBundle(2 * i + 1).lsrc(1) := src2 + (2 * i + 1).U 608 csBundle(2 * i + 1).lsrc(2) := dest + i.U 609 csBundle(2 * i + 1).ldest := dest + i.U 610 csBundle(2 * i + 1).uopIdx := (2 * i + 1).U 611 } 612 } 613 is(UopSplitType.VEC_WFW) { 614 /* 615 f to vector move 616 */ 617 csBundle(0).srcType(0) := SrcType.fp 618 csBundle(0).srcType(1) := SrcType.imm 619 csBundle(0).srcType(2) := SrcType.imm 620 csBundle(0).lsrc(1) := 0.U 621 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 622 csBundle(0).fuType := FuType.f2v.U 623 csBundle(0).fuOpType := Cat(IF2VectorType.fDup2Vec(2, 0), vsewReg) 624 csBundle(0).rfWen := false.B 625 csBundle(0).fpWen := false.B 626 csBundle(0).vecWen := true.B 627 628 for (i <- 0 until MAX_VLMUL / 2) { 629 csBundle(2 * i + 1).srcType(0) := SrcType.vp 630 csBundle(2 * i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 631 csBundle(2 * i + 1).lsrc(1) := src2 + (2 * i).U 632 csBundle(2 * i + 1).lsrc(2) := dest + (2 * i).U 633 csBundle(2 * i + 1).ldest := dest + (2 * i).U 634 csBundle(2 * i + 1).uopIdx := (2 * i).U 635 csBundle(2 * i + 2).srcType(0) := SrcType.vp 636 csBundle(2 * i + 2).lsrc(0) := VECTOR_TMP_REG_LMUL.U 637 csBundle(2 * i + 2).lsrc(1) := src2 + (2 * i + 1).U 638 csBundle(2 * i + 2).lsrc(2) := dest + (2 * i + 1).U 639 csBundle(2 * i + 2).ldest := dest + (2 * i + 1).U 640 csBundle(2 * i + 2).uopIdx := (2 * i + 1).U 641 } 642 } 643 is(UopSplitType.VEC_WXV) { 644 /* 645 i to vector move 646 */ 647 csBundle(0).srcType(0) := Mux(src1IsImm, SrcType.imm, SrcType.reg) 648 csBundle(0).srcType(1) := SrcType.imm 649 csBundle(0).srcType(2) := SrcType.imm 650 csBundle(0).lsrc(1) := 0.U 651 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 652 csBundle(0).fuType := FuType.i2v.U 653 csBundle(0).fuOpType := Cat(Mux(src1IsImm, IF2VectorType.immDup2Vec(2, 0), IF2VectorType.iDup2Vec(2, 0)), vsewReg) 654 csBundle(0).vecWen := true.B 655 656 for (i <- 0 until MAX_VLMUL / 2) { 657 csBundle(2 * i + 1).srcType(0) := SrcType.vp 658 csBundle(2 * i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 659 csBundle(2 * i + 1).lsrc(1) := src2 + (2 * i).U 660 csBundle(2 * i + 1).lsrc(2) := dest + i.U 661 csBundle(2 * i + 1).ldest := dest + i.U 662 csBundle(2 * i + 1).uopIdx := (2 * i).U 663 csBundle(2 * i + 2).srcType(0) := SrcType.vp 664 csBundle(2 * i + 2).lsrc(0) := VECTOR_TMP_REG_LMUL.U 665 csBundle(2 * i + 2).lsrc(1) := src2 + (2 * i + 1).U 666 csBundle(2 * i + 2).lsrc(2) := dest + i.U 667 csBundle(2 * i + 2).ldest := dest + i.U 668 csBundle(2 * i + 2).uopIdx := (2 * i + 1).U 669 } 670 } 671 is(UopSplitType.VEC_VVM) { 672 csBundle(0).lsrc(2) := dest 673 csBundle(0).ldest := dest 674 csBundle(0).uopIdx := 0.U 675 for (i <- 1 until MAX_VLMUL) { 676 csBundle(i).lsrc(0) := src1 + i.U 677 csBundle(i).lsrc(1) := src2 + i.U 678 csBundle(i).lsrc(2) := dest 679 csBundle(i).ldest := dest 680 csBundle(i).uopIdx := i.U 681 } 682 } 683 is(UopSplitType.VEC_VFM) { 684 /* 685 f to vector move 686 */ 687 csBundle(0).srcType(0) := SrcType.fp 688 csBundle(0).srcType(1) := SrcType.imm 689 csBundle(0).srcType(2) := SrcType.imm 690 csBundle(0).lsrc(1) := 0.U 691 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 692 csBundle(0).fuType := FuType.f2v.U 693 csBundle(0).fuOpType := Cat(IF2VectorType.fDup2Vec(2, 0), vsewReg) 694 csBundle(0).rfWen := false.B 695 csBundle(0).fpWen := false.B 696 csBundle(0).vecWen := true.B 697 //LMUL 698 csBundle(1).srcType(0) := SrcType.vp 699 csBundle(1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 700 csBundle(1).lsrc(2) := dest 701 csBundle(1).ldest := dest 702 csBundle(1).uopIdx := 0.U 703 for (i <- 1 until MAX_VLMUL) { 704 csBundle(i + 1).srcType(0) := SrcType.vp 705 csBundle(i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 706 csBundle(i + 1).lsrc(1) := src2 + i.U 707 csBundle(i + 1).lsrc(2) := dest 708 csBundle(i + 1).ldest := dest 709 csBundle(i + 1).uopIdx := i.U 710 } 711 csBundle(numOfUop - 1.U).ldest := dest 712 } 713 is(UopSplitType.VEC_VXM) { 714 /* 715 i to vector move 716 */ 717 csBundle(0).srcType(0) := Mux(src1IsImm, SrcType.imm, SrcType.reg) 718 csBundle(0).srcType(1) := SrcType.imm 719 csBundle(0).srcType(2) := SrcType.imm 720 csBundle(0).lsrc(1) := 0.U 721 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 722 csBundle(0).fuType := FuType.i2v.U 723 csBundle(0).fuOpType := Cat(Mux(src1IsImm, IF2VectorType.immDup2Vec(2, 0), IF2VectorType.iDup2Vec(2, 0)), vsewReg) 724 csBundle(0).vecWen := true.B 725 //LMUL 726 csBundle(1).srcType(0) := SrcType.vp 727 csBundle(1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 728 csBundle(1).lsrc(2) := dest 729 csBundle(1).ldest := dest 730 csBundle(1).uopIdx := 0.U 731 for (i <- 1 until MAX_VLMUL) { 732 csBundle(i + 1).srcType(0) := SrcType.vp 733 csBundle(i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 734 csBundle(i + 1).lsrc(1) := src2 + i.U 735 csBundle(i + 1).lsrc(2) := dest 736 csBundle(i + 1).ldest := dest 737 csBundle(i + 1).uopIdx := i.U 738 } 739 csBundle(numOfUop - 1.U).ldest := dest 740 } 741 is(UopSplitType.VEC_SLIDE1UP) { 742 /* 743 i to vector move 744 */ 745 csBundle(0).srcType(0) := SrcType.reg 746 csBundle(0).srcType(1) := SrcType.imm 747 csBundle(0).srcType(2) := SrcType.imm 748 csBundle(0).lsrc(1) := 0.U 749 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 750 csBundle(0).fuType := FuType.i2v.U 751 csBundle(0).fuOpType := Cat(IF2VectorType.iDup2Vec(2, 0), vsewReg) 752 csBundle(0).vecWen := true.B 753 //LMUL 754 csBundle(1).srcType(0) := SrcType.vp 755 csBundle(1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 756 csBundle(1).lsrc(2) := dest 757 csBundle(1).ldest := dest 758 csBundle(1).uopIdx := 0.U 759 for (i <- 1 until MAX_VLMUL) { 760 csBundle(i + 1).srcType(0) := SrcType.vp 761 csBundle(i + 1).lsrc(0) := src2 + (i - 1).U 762 csBundle(i + 1).lsrc(1) := src2 + i.U 763 csBundle(i + 1).lsrc(2) := dest + i.U 764 csBundle(i + 1).ldest := dest + i.U 765 csBundle(i + 1).uopIdx := i.U 766 } 767 } 768 is(UopSplitType.VEC_FSLIDE1UP) { 769 /* 770 f to vector move 771 */ 772 csBundle(0).srcType(0) := SrcType.fp 773 csBundle(0).srcType(1) := SrcType.imm 774 csBundle(0).srcType(2) := SrcType.imm 775 csBundle(0).lsrc(1) := 0.U 776 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 777 csBundle(0).fuType := FuType.f2v.U 778 csBundle(0).fuOpType := Cat(IF2VectorType.fDup2Vec(2, 0), vsewReg) 779 csBundle(0).rfWen := false.B 780 csBundle(0).fpWen := false.B 781 csBundle(0).vecWen := true.B 782 //LMUL 783 csBundle(1).srcType(0) := SrcType.vp 784 csBundle(1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 785 csBundle(1).lsrc(1) := src2 786 csBundle(1).lsrc(2) := dest 787 csBundle(1).ldest := dest 788 csBundle(1).uopIdx := 0.U 789 for (i <- 1 until MAX_VLMUL) { 790 csBundle(i + 1).srcType(0) := SrcType.vp 791 csBundle(i + 1).lsrc(0) := src2 + (i - 1).U 792 csBundle(i + 1).lsrc(1) := src2 + i.U 793 csBundle(i + 1).lsrc(2) := dest + i.U 794 csBundle(i + 1).ldest := dest + i.U 795 csBundle(i + 1).uopIdx := i.U 796 } 797 } 798 is(UopSplitType.VEC_SLIDE1DOWN) { // lmul+lmul = 16 799 /* 800 i to vector move 801 */ 802 csBundle(0).srcType(0) := SrcType.reg 803 csBundle(0).srcType(1) := SrcType.imm 804 csBundle(0).srcType(2) := SrcType.imm 805 csBundle(0).lsrc(1) := 0.U 806 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 807 csBundle(0).fuType := FuType.i2v.U 808 csBundle(0).fuOpType := Cat(IF2VectorType.iDup2Vec(2, 0), vsewReg) 809 csBundle(0).vecWen := true.B 810 //LMUL 811 for (i <- 0 until MAX_VLMUL) { 812 csBundle(2 * i + 1).srcType(0) := SrcType.vp 813 csBundle(2 * i + 1).srcType(1) := SrcType.vp 814 csBundle(2 * i + 1).lsrc(0) := src2 + (i + 1).U 815 csBundle(2 * i + 1).lsrc(1) := src2 + i.U 816 csBundle(2 * i + 1).lsrc(2) := dest + i.U 817 csBundle(2 * i + 1).ldest := VECTOR_TMP_REG_LMUL.U + 1.U 818 csBundle(2 * i + 1).uopIdx := (2 * i).U 819 if (2 * i + 2 < MAX_VLMUL * 2) { 820 csBundle(2 * i + 2).srcType(0) := SrcType.vp 821 csBundle(2 * i + 2).lsrc(0) := VECTOR_TMP_REG_LMUL.U 822 // csBundle(2 * i + 2).lsrc(1) := src2 + i.U // DontCare 823 csBundle(2 * i + 2).lsrc(2) := VECTOR_TMP_REG_LMUL.U + 1.U 824 csBundle(2 * i + 2).ldest := dest + i.U 825 csBundle(2 * i + 2).uopIdx := (2 * i + 1).U 826 } 827 } 828 csBundle(numOfUop - 1.U).srcType(0) := SrcType.vp 829 csBundle(numOfUop - 1.U).lsrc(0) := VECTOR_TMP_REG_LMUL.U 830 csBundle(numOfUop - 1.U).ldest := dest + lmul - 1.U 831 } 832 is(UopSplitType.VEC_FSLIDE1DOWN) { 833 /* 834 f to vector move 835 */ 836 csBundle(0).srcType(0) := SrcType.fp 837 csBundle(0).srcType(1) := SrcType.imm 838 csBundle(0).srcType(2) := SrcType.imm 839 csBundle(0).lsrc(1) := 0.U 840 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 841 csBundle(0).fuType := FuType.f2v.U 842 csBundle(0).fuOpType := Cat(IF2VectorType.fDup2Vec(2, 0), vsewReg) 843 csBundle(0).rfWen := false.B 844 csBundle(0).fpWen := false.B 845 csBundle(0).vecWen := true.B 846 //LMUL 847 for (i <- 0 until MAX_VLMUL) { 848 csBundle(2 * i + 1).srcType(0) := SrcType.vp 849 csBundle(2 * i + 1).srcType(1) := SrcType.vp 850 csBundle(2 * i + 1).lsrc(0) := src2 + (i + 1).U 851 csBundle(2 * i + 1).lsrc(1) := src2 + i.U 852 csBundle(2 * i + 1).lsrc(2) := dest + i.U 853 csBundle(2 * i + 1).ldest := VECTOR_TMP_REG_LMUL.U + 1.U 854 csBundle(2 * i + 1).uopIdx := (2 * i).U 855 if (2 * i + 2 < MAX_VLMUL * 2) { 856 csBundle(2 * i + 2).srcType(0) := SrcType.vp 857 csBundle(2 * i + 2).lsrc(0) := VECTOR_TMP_REG_LMUL.U 858 // csBundle(2 * i + 2).lsrc(1) := src2 + i.U // DontCare 859 csBundle(2 * i + 2).lsrc(2) := VECTOR_TMP_REG_LMUL.U + 1.U 860 csBundle(2 * i + 2).ldest := dest + i.U 861 csBundle(2 * i + 2).uopIdx := (2 * i + 1).U 862 } 863 } 864 csBundle(numOfUop - 1.U).srcType(0) := SrcType.vp 865 csBundle(numOfUop - 1.U).lsrc(0) := VECTOR_TMP_REG_LMUL.U 866 csBundle(numOfUop - 1.U).ldest := dest + lmul - 1.U 867 } 868 is(UopSplitType.VEC_VRED) { 869 when(vlmulReg === "b001".U) { 870 csBundle(0).srcType(2) := SrcType.DC 871 csBundle(0).lsrc(0) := src2 + 1.U 872 csBundle(0).lsrc(1) := src2 873 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 874 csBundle(0).uopIdx := 0.U 875 } 876 when(vlmulReg === "b010".U) { 877 csBundle(0).srcType(2) := SrcType.DC 878 csBundle(0).lsrc(0) := src2 + 1.U 879 csBundle(0).lsrc(1) := src2 880 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 881 csBundle(0).uopIdx := 0.U 882 883 csBundle(1).srcType(2) := SrcType.DC 884 csBundle(1).lsrc(0) := src2 + 3.U 885 csBundle(1).lsrc(1) := src2 + 2.U 886 csBundle(1).ldest := (VECTOR_TMP_REG_LMUL + 1).U 887 csBundle(1).uopIdx := 1.U 888 889 csBundle(2).srcType(2) := SrcType.DC 890 csBundle(2).lsrc(0) := (VECTOR_TMP_REG_LMUL + 1).U 891 csBundle(2).lsrc(1) := VECTOR_TMP_REG_LMUL.U 892 csBundle(2).ldest := (VECTOR_TMP_REG_LMUL + 2).U 893 csBundle(2).uopIdx := 2.U 894 } 895 when(vlmulReg === "b011".U) { 896 for (i <- 0 until MAX_VLMUL) { 897 if (i < MAX_VLMUL - MAX_VLMUL / 2) { 898 csBundle(i).lsrc(0) := src2 + (i * 2 + 1).U 899 csBundle(i).lsrc(1) := src2 + (i * 2).U 900 csBundle(i).ldest := (VECTOR_TMP_REG_LMUL + i).U 901 } else if (i < MAX_VLMUL - MAX_VLMUL / 4) { 902 csBundle(i).lsrc(0) := (VECTOR_TMP_REG_LMUL + (i - MAX_VLMUL / 2) * 2 + 1).U 903 csBundle(i).lsrc(1) := (VECTOR_TMP_REG_LMUL + (i - MAX_VLMUL / 2) * 2).U 904 csBundle(i).ldest := (VECTOR_TMP_REG_LMUL + i).U 905 } else if (i < MAX_VLMUL - MAX_VLMUL / 8) { 906 csBundle(6).lsrc(0) := (VECTOR_TMP_REG_LMUL + 5).U 907 csBundle(6).lsrc(1) := (VECTOR_TMP_REG_LMUL + 4).U 908 csBundle(6).ldest := (VECTOR_TMP_REG_LMUL + 6).U 909 } 910 csBundle(i).srcType(2) := SrcType.DC 911 csBundle(i).uopIdx := i.U 912 } 913 } 914 when(vlmulReg(2) === 0.U && vlmulReg(1, 0).orR) { 915 /* 916 * 2 <= vlmul <= 8 917 */ 918 csBundle(numOfUop - 1.U).srcType(2) := SrcType.vp 919 csBundle(numOfUop - 1.U).lsrc(0) := src1 920 csBundle(numOfUop - 1.U).lsrc(1) := VECTOR_TMP_REG_LMUL.U + numOfUop - 2.U 921 csBundle(numOfUop - 1.U).lsrc(2) := dest 922 csBundle(numOfUop - 1.U).ldest := dest 923 csBundle(numOfUop - 1.U).uopIdx := numOfUop - 1.U 924 } 925 } 926 is(UopSplitType.VEC_VFRED) { 927 val vlmul = vlmulReg 928 val vsew = vsewReg 929 when(vlmul === VLmul.m8){ 930 for (i <- 0 until 4) { 931 csBundle(i).lsrc(0) := src2 + (i * 2 + 1).U 932 csBundle(i).lsrc(1) := src2 + (i * 2).U 933 csBundle(i).ldest := (VECTOR_TMP_REG_LMUL + i).U 934 csBundle(i).uopIdx := i.U 935 } 936 for (i <- 4 until 6) { 937 csBundle(i).lsrc(0) := (VECTOR_TMP_REG_LMUL + (i - 4) * 2 + 1).U 938 csBundle(i).lsrc(1) := (VECTOR_TMP_REG_LMUL + (i - 4) * 2).U 939 csBundle(i).ldest := (VECTOR_TMP_REG_LMUL + i).U 940 csBundle(i).uopIdx := i.U 941 } 942 csBundle(6).lsrc(0) := (VECTOR_TMP_REG_LMUL + 5).U 943 csBundle(6).lsrc(1) := (VECTOR_TMP_REG_LMUL + 4).U 944 csBundle(6).ldest := (VECTOR_TMP_REG_LMUL + 6).U 945 csBundle(6).uopIdx := 6.U 946 when(vsew === VSew.e64) { 947 csBundle(7).lsrc(0) := (VECTOR_TMP_REG_LMUL + 6).U 948 csBundle(7).lsrc(1) := (VECTOR_TMP_REG_LMUL + 6).U 949 csBundle(7).ldest := (VECTOR_TMP_REG_LMUL + 7).U 950 csBundle(7).vpu.fpu.isFoldTo1_2 := true.B 951 csBundle(7).uopIdx := 7.U 952 csBundle(8).lsrc(0) := src1 953 csBundle(8).lsrc(1) := (VECTOR_TMP_REG_LMUL + 7).U 954 csBundle(8).ldest := dest 955 csBundle(8).uopIdx := 8.U 956 } 957 when(vsew === VSew.e32) { 958 csBundle(7).lsrc(0) := (VECTOR_TMP_REG_LMUL + 6).U 959 csBundle(7).lsrc(1) := (VECTOR_TMP_REG_LMUL + 6).U 960 csBundle(7).ldest := (VECTOR_TMP_REG_LMUL + 7).U 961 csBundle(7).vpu.fpu.isFoldTo1_2 := true.B 962 csBundle(7).uopIdx := 7.U 963 csBundle(8).lsrc(0) := (VECTOR_TMP_REG_LMUL + 7).U 964 csBundle(8).lsrc(1) := (VECTOR_TMP_REG_LMUL + 7).U 965 csBundle(8).ldest := (VECTOR_TMP_REG_LMUL + 8).U 966 csBundle(8).vpu.fpu.isFoldTo1_4 := true.B 967 csBundle(8).uopIdx := 8.U 968 csBundle(9).lsrc(0) := src1 969 csBundle(9).lsrc(1) := (VECTOR_TMP_REG_LMUL + 8).U 970 csBundle(9).ldest := dest 971 csBundle(9).uopIdx := 9.U 972 } 973 when(vsew === VSew.e16) { 974 csBundle(7).lsrc(0) := (VECTOR_TMP_REG_LMUL + 6).U 975 csBundle(7).lsrc(1) := (VECTOR_TMP_REG_LMUL + 6).U 976 csBundle(7).ldest := (VECTOR_TMP_REG_LMUL + 7).U 977 csBundle(7).vpu.fpu.isFoldTo1_2 := true.B 978 csBundle(7).uopIdx := 7.U 979 csBundle(8).lsrc(0) := (VECTOR_TMP_REG_LMUL + 7).U 980 csBundle(8).lsrc(1) := (VECTOR_TMP_REG_LMUL + 7).U 981 csBundle(8).ldest := (VECTOR_TMP_REG_LMUL + 8).U 982 csBundle(8).vpu.fpu.isFoldTo1_4 := true.B 983 csBundle(8).uopIdx := 8.U 984 csBundle(9).lsrc(0) := (VECTOR_TMP_REG_LMUL + 8).U 985 csBundle(9).lsrc(1) := (VECTOR_TMP_REG_LMUL + 8).U 986 csBundle(9).ldest := (VECTOR_TMP_REG_LMUL + 9).U 987 csBundle(9).vpu.fpu.isFoldTo1_8 := true.B 988 csBundle(9).uopIdx := 9.U 989 csBundle(10).lsrc(0) := src1 990 csBundle(10).lsrc(1) := (VECTOR_TMP_REG_LMUL + 9).U 991 csBundle(10).ldest := dest 992 csBundle(10).uopIdx := 10.U 993 } 994 } 995 when(vlmul === VLmul.m4) { 996 for (i <- 0 until 2) { 997 csBundle(i).lsrc(0) := src2 + (i * 2 + 1).U 998 csBundle(i).lsrc(1) := src2 + (i * 2).U 999 csBundle(i).ldest := (VECTOR_TMP_REG_LMUL + i).U 1000 csBundle(i).uopIdx := i.U 1001 } 1002 csBundle(2).lsrc(0) := (VECTOR_TMP_REG_LMUL + 1).U 1003 csBundle(2).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1004 csBundle(2).ldest := (VECTOR_TMP_REG_LMUL + 2).U 1005 csBundle(2).uopIdx := 2.U 1006 when(vsew === VSew.e64) { 1007 csBundle(3).lsrc(0) := (VECTOR_TMP_REG_LMUL + 2).U 1008 csBundle(3).lsrc(1) := (VECTOR_TMP_REG_LMUL + 2).U 1009 csBundle(3).ldest := (VECTOR_TMP_REG_LMUL + 3).U 1010 csBundle(3).vpu.fpu.isFoldTo1_2 := true.B 1011 csBundle(3).uopIdx := 3.U 1012 csBundle(4).lsrc(0) := src1 1013 csBundle(4).lsrc(1) := (VECTOR_TMP_REG_LMUL + 3).U 1014 csBundle(4).ldest := dest 1015 csBundle(4).uopIdx := 4.U 1016 } 1017 when(vsew === VSew.e32) { 1018 csBundle(3).lsrc(0) := (VECTOR_TMP_REG_LMUL + 2).U 1019 csBundle(3).lsrc(1) := (VECTOR_TMP_REG_LMUL + 2).U 1020 csBundle(3).ldest := (VECTOR_TMP_REG_LMUL + 3).U 1021 csBundle(3).vpu.fpu.isFoldTo1_2 := true.B 1022 csBundle(3).uopIdx := 3.U 1023 csBundle(4).lsrc(0) := (VECTOR_TMP_REG_LMUL + 3).U 1024 csBundle(4).lsrc(1) := (VECTOR_TMP_REG_LMUL + 3).U 1025 csBundle(4).ldest := (VECTOR_TMP_REG_LMUL + 4).U 1026 csBundle(4).vpu.fpu.isFoldTo1_4 := true.B 1027 csBundle(4).uopIdx := 4.U 1028 csBundle(5).lsrc(0) := src1 1029 csBundle(5).lsrc(1) := (VECTOR_TMP_REG_LMUL + 4).U 1030 csBundle(5).ldest := dest 1031 csBundle(5).uopIdx := 5.U 1032 } 1033 when(vsew === VSew.e16) { 1034 csBundle(3).lsrc(0) := (VECTOR_TMP_REG_LMUL + 2).U 1035 csBundle(3).lsrc(1) := (VECTOR_TMP_REG_LMUL + 2).U 1036 csBundle(3).ldest := (VECTOR_TMP_REG_LMUL + 3).U 1037 csBundle(3).vpu.fpu.isFoldTo1_2 := true.B 1038 csBundle(3).uopIdx := 3.U 1039 csBundle(4).lsrc(0) := (VECTOR_TMP_REG_LMUL + 3).U 1040 csBundle(4).lsrc(1) := (VECTOR_TMP_REG_LMUL + 3).U 1041 csBundle(4).ldest := (VECTOR_TMP_REG_LMUL + 4).U 1042 csBundle(4).vpu.fpu.isFoldTo1_4 := true.B 1043 csBundle(4).uopIdx := 4.U 1044 csBundle(5).lsrc(0) := (VECTOR_TMP_REG_LMUL + 4).U 1045 csBundle(5).lsrc(1) := (VECTOR_TMP_REG_LMUL + 4).U 1046 csBundle(5).ldest := (VECTOR_TMP_REG_LMUL + 5).U 1047 csBundle(5).vpu.fpu.isFoldTo1_8 := true.B 1048 csBundle(5).uopIdx := 5.U 1049 csBundle(6).lsrc(0) := src1 1050 csBundle(6).lsrc(1) := (VECTOR_TMP_REG_LMUL + 5).U 1051 csBundle(6).ldest := dest 1052 csBundle(6).uopIdx := 6.U 1053 } 1054 } 1055 when(vlmul === VLmul.m2) { 1056 csBundle(0).lsrc(0) := src2 + 1.U 1057 csBundle(0).lsrc(1) := src2 + 0.U 1058 csBundle(0).ldest := (VECTOR_TMP_REG_LMUL + 0).U 1059 csBundle(0).uopIdx := 0.U 1060 when(vsew === VSew.e64) { 1061 csBundle(1).lsrc(0) := (VECTOR_TMP_REG_LMUL + 0).U 1062 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1063 csBundle(1).ldest := (VECTOR_TMP_REG_LMUL + 1).U 1064 csBundle(1).vpu.fpu.isFoldTo1_2 := true.B 1065 csBundle(1).uopIdx := 1.U 1066 csBundle(2).lsrc(0) := src1 1067 csBundle(2).lsrc(1) := (VECTOR_TMP_REG_LMUL + 1).U 1068 csBundle(2).ldest := dest 1069 csBundle(2).uopIdx := 2.U 1070 } 1071 when(vsew === VSew.e32) { 1072 csBundle(1).lsrc(0) := (VECTOR_TMP_REG_LMUL + 0).U 1073 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1074 csBundle(1).ldest := (VECTOR_TMP_REG_LMUL + 1).U 1075 csBundle(1).vpu.fpu.isFoldTo1_2 := true.B 1076 csBundle(1).uopIdx := 1.U 1077 csBundle(2).lsrc(0) := (VECTOR_TMP_REG_LMUL + 1).U 1078 csBundle(2).lsrc(1) := (VECTOR_TMP_REG_LMUL + 1).U 1079 csBundle(2).ldest := (VECTOR_TMP_REG_LMUL + 2).U 1080 csBundle(2).vpu.fpu.isFoldTo1_4 := true.B 1081 csBundle(2).uopIdx := 2.U 1082 csBundle(3).lsrc(0) := src1 1083 csBundle(3).lsrc(1) := (VECTOR_TMP_REG_LMUL + 2).U 1084 csBundle(3).ldest := dest 1085 csBundle(3).uopIdx := 3.U 1086 } 1087 when(vsew === VSew.e16) { 1088 csBundle(1).lsrc(0) := (VECTOR_TMP_REG_LMUL + 0).U 1089 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1090 csBundle(1).ldest := (VECTOR_TMP_REG_LMUL + 1).U 1091 csBundle(1).vpu.fpu.isFoldTo1_2 := true.B 1092 csBundle(1).uopIdx := 1.U 1093 csBundle(2).lsrc(0) := (VECTOR_TMP_REG_LMUL + 1).U 1094 csBundle(2).lsrc(1) := (VECTOR_TMP_REG_LMUL + 1).U 1095 csBundle(2).ldest := (VECTOR_TMP_REG_LMUL + 2).U 1096 csBundle(2).vpu.fpu.isFoldTo1_4 := true.B 1097 csBundle(2).uopIdx := 2.U 1098 csBundle(3).lsrc(0) := (VECTOR_TMP_REG_LMUL + 2).U 1099 csBundle(3).lsrc(1) := (VECTOR_TMP_REG_LMUL + 2).U 1100 csBundle(3).ldest := (VECTOR_TMP_REG_LMUL + 3).U 1101 csBundle(3).vpu.fpu.isFoldTo1_8 := true.B 1102 csBundle(3).uopIdx := 3.U 1103 csBundle(4).lsrc(0) := src1 1104 csBundle(4).lsrc(1) := (VECTOR_TMP_REG_LMUL + 3).U 1105 csBundle(4).ldest := dest 1106 csBundle(4).uopIdx := 4.U 1107 } 1108 } 1109 when(vlmul === VLmul.m1) { 1110 when(vsew === VSew.e64) { 1111 csBundle(0).lsrc(0) := src2 1112 csBundle(0).lsrc(1) := src2 1113 csBundle(0).ldest := (VECTOR_TMP_REG_LMUL + 0).U 1114 csBundle(0).vpu.fpu.isFoldTo1_2 := true.B 1115 csBundle(0).uopIdx := 0.U 1116 csBundle(1).lsrc(0) := src1 1117 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1118 csBundle(1).ldest := dest 1119 csBundle(1).uopIdx := 1.U 1120 } 1121 when(vsew === VSew.e32) { 1122 csBundle(0).lsrc(0) := src2 1123 csBundle(0).lsrc(1) := src2 1124 csBundle(0).ldest := (VECTOR_TMP_REG_LMUL + 0).U 1125 csBundle(0).vpu.fpu.isFoldTo1_2 := true.B 1126 csBundle(0).uopIdx := 0.U 1127 csBundle(1).lsrc(0) := (VECTOR_TMP_REG_LMUL + 0).U 1128 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1129 csBundle(1).ldest := (VECTOR_TMP_REG_LMUL + 1).U 1130 csBundle(1).vpu.fpu.isFoldTo1_4 := true.B 1131 csBundle(1).uopIdx := 1.U 1132 csBundle(2).lsrc(0) := src1 1133 csBundle(2).lsrc(1) := (VECTOR_TMP_REG_LMUL + 1).U 1134 csBundle(2).ldest := dest 1135 csBundle(2).uopIdx := 2.U 1136 } 1137 when(vsew === VSew.e16) { 1138 csBundle(0).lsrc(0) := src2 1139 csBundle(0).lsrc(1) := src2 1140 csBundle(0).ldest := (VECTOR_TMP_REG_LMUL + 0).U 1141 csBundle(0).vpu.fpu.isFoldTo1_2 := true.B 1142 csBundle(0).uopIdx := 0.U 1143 csBundle(1).lsrc(0) := (VECTOR_TMP_REG_LMUL + 0).U 1144 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1145 csBundle(1).ldest := (VECTOR_TMP_REG_LMUL + 1).U 1146 csBundle(1).vpu.fpu.isFoldTo1_4 := true.B 1147 csBundle(1).uopIdx := 1.U 1148 csBundle(2).lsrc(0) := (VECTOR_TMP_REG_LMUL + 1).U 1149 csBundle(2).lsrc(1) := (VECTOR_TMP_REG_LMUL + 1).U 1150 csBundle(2).ldest := (VECTOR_TMP_REG_LMUL + 2).U 1151 csBundle(2).vpu.fpu.isFoldTo1_8 := true.B 1152 csBundle(2).uopIdx := 2.U 1153 csBundle(3).lsrc(0) := src1 1154 csBundle(3).lsrc(1) := (VECTOR_TMP_REG_LMUL + 2).U 1155 csBundle(3).ldest := dest 1156 csBundle(3).uopIdx := 3.U 1157 } 1158 } 1159 when(vlmul === VLmul.mf2) { 1160 when(vsew === VSew.e32) { 1161 csBundle(0).lsrc(0) := src2 1162 csBundle(0).lsrc(1) := src2 1163 csBundle(0).ldest := (VECTOR_TMP_REG_LMUL + 0).U 1164 csBundle(0).vpu.fpu.isFoldTo1_4 := true.B 1165 csBundle(0).uopIdx := 0.U 1166 csBundle(1).lsrc(0) := src1 1167 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1168 csBundle(1).ldest := dest 1169 csBundle(1).uopIdx := 1.U 1170 } 1171 when(vsew === VSew.e16) { 1172 csBundle(0).lsrc(0) := src2 1173 csBundle(0).lsrc(1) := src2 1174 csBundle(0).ldest := (VECTOR_TMP_REG_LMUL + 0).U 1175 csBundle(0).vpu.fpu.isFoldTo1_4 := true.B 1176 csBundle(0).uopIdx := 0.U 1177 csBundle(1).lsrc(0) := (VECTOR_TMP_REG_LMUL + 0).U 1178 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1179 csBundle(1).ldest := (VECTOR_TMP_REG_LMUL + 1).U 1180 csBundle(1).vpu.fpu.isFoldTo1_8 := true.B 1181 csBundle(1).uopIdx := 1.U 1182 csBundle(2).lsrc(0) := src1 1183 csBundle(2).lsrc(1) := (VECTOR_TMP_REG_LMUL + 1).U 1184 csBundle(2).ldest := dest 1185 csBundle(2).uopIdx := 2.U 1186 } 1187 } 1188 when(vlmul === VLmul.mf4) { 1189 when(vsew === VSew.e16) { 1190 csBundle(0).lsrc(0) := src2 1191 csBundle(0).lsrc(1) := src2 1192 csBundle(0).ldest := (VECTOR_TMP_REG_LMUL + 0).U 1193 csBundle(0).vpu.fpu.isFoldTo1_8 := true.B 1194 csBundle(0).uopIdx := 0.U 1195 csBundle(1).lsrc(0) := src1 1196 csBundle(1).lsrc(1) := (VECTOR_TMP_REG_LMUL + 0).U 1197 csBundle(1).ldest := dest 1198 csBundle(1).uopIdx := 1.U 1199 } 1200 } 1201 } 1202 1203 is(UopSplitType.VEC_VFREDOSUM) { 1204 import yunsuan.VfaluType 1205 val vlmul = vlmulReg 1206 val vsew = vsewReg 1207 val isWiden = latchedInst.fuOpType === VfaluType.vfwredosum 1208 when(vlmul === VLmul.m8) { 1209 when(vsew === VSew.e64) { 1210 val vlmax = 16 1211 for (i <- 0 until vlmax) { 1212 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1213 csBundle(i).lsrc(1) := (if (i % 2 == 0) src2 + (i/2).U else VECTOR_TMP_REG_LMUL.U) 1214 csBundle(i).lsrc(2) := (if (i % 2 == 0) src2 + (i/2).U else if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1215 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1216 csBundle(i).vpu.fpu.isFoldTo1_2 := (if (i % 2 == 0) false.B else true.B) 1217 csBundle(i).uopIdx := i.U 1218 } 1219 } 1220 when(vsew === VSew.e32) { 1221 val vlmax = 32 1222 for (i <- 0 until vlmax) { 1223 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1224 csBundle(i).lsrc(1) := (if (i % 4 == 0) src2 + (i/4).U else VECTOR_TMP_REG_LMUL.U) 1225 csBundle(i).lsrc(2) := (if (i % 4 == 0) src2 + (i/4).U else if (i == vlmax - 1) dest else if (i % 4 == 1) Mux(isWiden, src2 + (i/4).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1226 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1227 csBundle(i).vpu.fpu.isFoldTo1_2 := isWiden && (if (i % 4 == 0) false.B else true.B) 1228 csBundle(i).vpu.fpu.isFoldTo1_4 := !isWiden && (if (i % 4 == 0) false.B else true.B) 1229 csBundle(i).uopIdx := i.U 1230 } 1231 } 1232 when(vsew === VSew.e16) { 1233 val vlmax = 64 1234 for (i <- 0 until vlmax) { 1235 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1236 csBundle(i).lsrc(1) := (if (i % 8 == 0) src2 + (i/8).U else VECTOR_TMP_REG_LMUL.U) 1237 csBundle(i).lsrc(2) := (if (i % 8 == 0) src2 + (i/8).U else if (i == vlmax - 1) dest else if (i % 8 == 1) Mux(isWiden, src2 + (i/8).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1238 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1239 csBundle(i).vpu.fpu.isFoldTo1_4 := isWiden && (if (i % 8 == 0) false.B else true.B) 1240 csBundle(i).vpu.fpu.isFoldTo1_8 := !isWiden && (if (i % 8 == 0) false.B else true.B) 1241 csBundle(i).uopIdx := i.U 1242 } 1243 } 1244 } 1245 when(vlmul === VLmul.m4) { 1246 when(vsew === VSew.e64) { 1247 val vlmax = 8 1248 for (i <- 0 until vlmax) { 1249 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1250 csBundle(i).lsrc(1) := (if (i % 2 == 0) src2 + (i/2).U else VECTOR_TMP_REG_LMUL.U) 1251 csBundle(i).lsrc(2) := (if (i % 2 == 0) src2 + (i/2).U else if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1252 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1253 csBundle(i).vpu.fpu.isFoldTo1_2 := (if (i % 2 == 0) false.B else true.B) 1254 csBundle(i).uopIdx := i.U 1255 } 1256 } 1257 when(vsew === VSew.e32) { 1258 val vlmax = 16 1259 for (i <- 0 until vlmax) { 1260 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1261 csBundle(i).lsrc(1) := (if (i % 4 == 0) src2 + (i/4).U else VECTOR_TMP_REG_LMUL.U) 1262 csBundle(i).lsrc(2) := (if (i % 4 == 0) src2 + (i/4).U else if (i == vlmax - 1) dest else if (i % 4 == 1) Mux(isWiden, src2 + (i/4).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1263 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1264 csBundle(i).vpu.fpu.isFoldTo1_2 := isWiden && (if (i % 4 == 0) false.B else true.B) 1265 csBundle(i).vpu.fpu.isFoldTo1_4 := !isWiden && (if (i % 4 == 0) false.B else true.B) 1266 csBundle(i).uopIdx := i.U 1267 } 1268 } 1269 when(vsew === VSew.e16) { 1270 val vlmax = 32 1271 for (i <- 0 until vlmax) { 1272 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1273 csBundle(i).lsrc(1) := (if (i % 8 == 0) src2 + (i/8).U else VECTOR_TMP_REG_LMUL.U) 1274 csBundle(i).lsrc(2) := (if (i % 8 == 0) src2 + (i/8).U else if (i == vlmax - 1) dest else if (i % 8 == 1) Mux(isWiden, src2 + (i/8).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1275 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1276 csBundle(i).vpu.fpu.isFoldTo1_4 := isWiden && (if (i % 8 == 0) false.B else true.B) 1277 csBundle(i).vpu.fpu.isFoldTo1_8 := !isWiden && (if (i % 8 == 0) false.B else true.B) 1278 csBundle(i).uopIdx := i.U 1279 } 1280 } 1281 } 1282 when(vlmul === VLmul.m2) { 1283 when(vsew === VSew.e64) { 1284 val vlmax = 4 1285 for (i <- 0 until vlmax) { 1286 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1287 csBundle(i).lsrc(1) := (if (i % 2 == 0) src2 + (i/2).U else VECTOR_TMP_REG_LMUL.U) 1288 csBundle(i).lsrc(2) := (if (i % 2 == 0) src2 + (i/2).U else if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1289 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1290 csBundle(i).vpu.fpu.isFoldTo1_2 := (if (i % 2 == 0) false.B else true.B) 1291 csBundle(i).uopIdx := i.U 1292 } 1293 } 1294 when(vsew === VSew.e32) { 1295 val vlmax = 8 1296 for (i <- 0 until vlmax) { 1297 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1298 csBundle(i).lsrc(1) := (if (i % 4 == 0) src2 + (i/4).U else VECTOR_TMP_REG_LMUL.U) 1299 csBundle(i).lsrc(2) := (if (i % 4 == 0) src2 + (i/4).U else if (i == vlmax - 1) dest else if (i % 4 == 1) Mux(isWiden, src2 + (i/4).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1300 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1301 csBundle(i).vpu.fpu.isFoldTo1_2 := isWiden && (if (i % 4 == 0) false.B else true.B) 1302 csBundle(i).vpu.fpu.isFoldTo1_4 := !isWiden && (if (i % 4 == 0) false.B else true.B) 1303 csBundle(i).uopIdx := i.U 1304 } 1305 } 1306 when(vsew === VSew.e16) { 1307 val vlmax = 16 1308 for (i <- 0 until vlmax) { 1309 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1310 csBundle(i).lsrc(1) := (if (i % 8 == 0) src2 + (i/8).U else VECTOR_TMP_REG_LMUL.U) 1311 csBundle(i).lsrc(2) := (if (i % 8 == 0) src2 + (i/8).U else if (i == vlmax - 1) dest else if (i % 8 == 1) Mux(isWiden, src2 + (i/8).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1312 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1313 csBundle(i).vpu.fpu.isFoldTo1_4 := isWiden && (if (i % 8 == 0) false.B else true.B) 1314 csBundle(i).vpu.fpu.isFoldTo1_8 := !isWiden && (if (i % 8 == 0) false.B else true.B) 1315 csBundle(i).uopIdx := i.U 1316 } 1317 } 1318 } 1319 when(vlmul === VLmul.m1) { 1320 when(vsew === VSew.e64) { 1321 val vlmax = 2 1322 for (i <- 0 until vlmax) { 1323 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1324 csBundle(i).lsrc(1) := (if (i % 2 == 0) src2 + (i/2).U else VECTOR_TMP_REG_LMUL.U) 1325 csBundle(i).lsrc(2) := (if (i % 2 == 0) src2 + (i/2).U else if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1326 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1327 csBundle(i).vpu.fpu.isFoldTo1_2 := (if (i % 2 == 0) false.B else true.B) 1328 csBundle(i).uopIdx := i.U 1329 } 1330 } 1331 when(vsew === VSew.e32) { 1332 val vlmax = 4 1333 for (i <- 0 until vlmax) { 1334 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1335 csBundle(i).lsrc(1) := (if (i % 4 == 0) src2 + (i/4).U else VECTOR_TMP_REG_LMUL.U) 1336 csBundle(i).lsrc(2) := (if (i % 4 == 0) src2 + (i/4).U else if (i == vlmax - 1) dest else if (i % 4 == 1) Mux(isWiden, src2 + (i/4).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1337 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1338 csBundle(i).vpu.fpu.isFoldTo1_2 := isWiden && (if (i % 4 == 0) false.B else true.B) 1339 csBundle(i).vpu.fpu.isFoldTo1_4 := !isWiden && (if (i % 4 == 0) false.B else true.B) 1340 csBundle(i).uopIdx := i.U 1341 } 1342 } 1343 when(vsew === VSew.e16) { 1344 val vlmax = 8 1345 for (i <- 0 until vlmax) { 1346 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1347 csBundle(i).lsrc(1) := (if (i % 8 == 0) src2 + (i/8).U else VECTOR_TMP_REG_LMUL.U) 1348 csBundle(i).lsrc(2) := (if (i % 8 == 0) src2 + (i/8).U else if (i == vlmax - 1) dest else if (i % 8 == 1) Mux(isWiden, src2 + (i/8).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1349 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1350 csBundle(i).vpu.fpu.isFoldTo1_4 := isWiden && (if (i % 8 == 0) false.B else true.B) 1351 csBundle(i).vpu.fpu.isFoldTo1_8 := !isWiden && (if (i % 8 == 0) false.B else true.B) 1352 csBundle(i).uopIdx := i.U 1353 } 1354 } 1355 } 1356 when(vlmul === VLmul.mf2) { 1357 when(vsew === VSew.e32) { 1358 val vlmax = 2 1359 for (i <- 0 until vlmax) { 1360 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1361 csBundle(i).lsrc(1) := (if (i % 4 == 0) src2 + (i/4).U else VECTOR_TMP_REG_LMUL.U) 1362 csBundle(i).lsrc(2) := (if (i % 4 == 0) src2 + (i/4).U else if (i == vlmax - 1) dest else if (i % 4 == 1) Mux(isWiden, src2 + (i/4).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1363 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1364 csBundle(i).vpu.fpu.isFoldTo1_2 := isWiden && (if (i % 4 == 0) false.B else true.B) 1365 csBundle(i).vpu.fpu.isFoldTo1_4 := !isWiden && (if (i % 4 == 0) false.B else true.B) 1366 csBundle(i).uopIdx := i.U 1367 } 1368 } 1369 when(vsew === VSew.e16) { 1370 val vlmax = 4 1371 for (i <- 0 until vlmax) { 1372 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1373 csBundle(i).lsrc(1) := (if (i % 8 == 0) src2 + (i/8).U else VECTOR_TMP_REG_LMUL.U) 1374 csBundle(i).lsrc(2) := (if (i % 8 == 0) src2 + (i/8).U else if (i == vlmax - 1) dest else if (i % 8 == 1) Mux(isWiden, src2 + (i/8).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1375 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1376 csBundle(i).vpu.fpu.isFoldTo1_4 := isWiden && (if (i % 8 == 0) false.B else true.B) 1377 csBundle(i).vpu.fpu.isFoldTo1_8 := !isWiden && (if (i % 8 == 0) false.B else true.B) 1378 csBundle(i).uopIdx := i.U 1379 } 1380 } 1381 } 1382 when(vlmul === VLmul.mf4) { 1383 when(vsew === VSew.e16) { 1384 val vlmax = 2 1385 for (i <- 0 until vlmax) { 1386 csBundle(i).lsrc(0) := (if (i == 0) src1 else VECTOR_TMP_REG_LMUL.U) 1387 csBundle(i).lsrc(1) := (if (i % 8 == 0) src2 + (i/8).U else VECTOR_TMP_REG_LMUL.U) 1388 csBundle(i).lsrc(2) := (if (i % 8 == 0) src2 + (i/8).U else if (i == vlmax - 1) dest else if (i % 8 == 1) Mux(isWiden, src2 + (i/8).U, VECTOR_TMP_REG_LMUL.U) else VECTOR_TMP_REG_LMUL.U) 1389 csBundle(i).ldest := (if (i == vlmax - 1) dest else VECTOR_TMP_REG_LMUL.U) 1390 csBundle(i).vpu.fpu.isFoldTo1_4 := isWiden && (if (i % 8 == 0) false.B else true.B) 1391 csBundle(i).vpu.fpu.isFoldTo1_8 := !isWiden && (if (i % 8 == 0) false.B else true.B) 1392 csBundle(i).uopIdx := i.U 1393 } 1394 } 1395 } 1396 } 1397 1398 is(UopSplitType.VEC_SLIDEUP) { 1399 // i to vector move 1400 csBundle(0).srcType(0) := Mux(src1IsImm, SrcType.imm, SrcType.reg) 1401 csBundle(0).srcType(1) := SrcType.imm 1402 csBundle(0).srcType(2) := SrcType.imm 1403 csBundle(0).lsrc(1) := 0.U 1404 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 1405 csBundle(0).fuType := FuType.i2v.U 1406 csBundle(0).fuOpType := Cat(Mux(src1IsImm, IF2VectorType.imm2Vec(2, 0), IF2VectorType.i2Vec(2, 0)), vsewReg) 1407 csBundle(0).vecWen := true.B 1408 // LMUL 1409 for (i <- 0 until MAX_VLMUL) 1410 for (j <- 0 to i) { 1411 val old_vd = if (j == 0) { 1412 dest + i.U 1413 } else (VECTOR_TMP_REG_LMUL + j).U 1414 val vd = if (j == i) { 1415 dest + i.U 1416 } else (VECTOR_TMP_REG_LMUL + j + 1).U 1417 csBundle(i * (i + 1) / 2 + j + 1).srcType(0) := SrcType.vp 1418 csBundle(i * (i + 1) / 2 + j + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1419 csBundle(i * (i + 1) / 2 + j + 1).lsrc(1) := src2 + j.U 1420 csBundle(i * (i + 1) / 2 + j + 1).lsrc(2) := old_vd 1421 csBundle(i * (i + 1) / 2 + j + 1).ldest := vd 1422 csBundle(i * (i + 1) / 2 + j + 1).uopIdx := (i * (i + 1) / 2 + j).U 1423 } 1424 } 1425 1426 is(UopSplitType.VEC_SLIDEDOWN) { 1427 // i to vector move 1428 csBundle(0).srcType(0) := Mux(src1IsImm, SrcType.imm, SrcType.reg) 1429 csBundle(0).srcType(1) := SrcType.imm 1430 csBundle(0).srcType(2) := SrcType.imm 1431 csBundle(0).lsrc(1) := 0.U 1432 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 1433 csBundle(0).fuType := FuType.i2v.U 1434 csBundle(0).fuOpType := Cat(Mux(src1IsImm, IF2VectorType.imm2Vec(2, 0), IF2VectorType.i2Vec(2, 0)), vsewReg) 1435 csBundle(0).vecWen := true.B 1436 // LMUL 1437 for (i <- 0 until MAX_VLMUL) 1438 for (j <- (0 to i).reverse) { 1439 when(i.U < lmul) { 1440 val old_vd = if (j == 0) { 1441 dest + lmul - 1.U - i.U 1442 } else (VECTOR_TMP_REG_LMUL + j).U 1443 val vd = if (j == i) { 1444 dest + lmul - 1.U - i.U 1445 } else (VECTOR_TMP_REG_LMUL + j + 1).U 1446 csBundle(numOfUop - (i * (i + 1) / 2 + i - j + 1).U).srcType(0) := SrcType.vp 1447 csBundle(numOfUop - (i * (i + 1) / 2 + i - j + 1).U).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1448 csBundle(numOfUop - (i * (i + 1) / 2 + i - j + 1).U).lsrc(1) := src2 + lmul - 1.U - j.U 1449 csBundle(numOfUop - (i * (i + 1) / 2 + i - j + 1).U).lsrc(2) := old_vd 1450 csBundle(numOfUop - (i * (i + 1) / 2 + i - j + 1).U).ldest := vd 1451 csBundle(numOfUop - (i * (i + 1) / 2 + i - j + 1).U).uopIdx := numOfUop - (i * (i + 1) / 2 + i - j + 2).U 1452 } 1453 } 1454 } 1455 1456 is(UopSplitType.VEC_M0X) { 1457 // LMUL 1458 for (i <- 0 until MAX_VLMUL) { 1459 val srcType0 = if (i == 0) SrcType.DC else SrcType.vp 1460 val ldest = (VECTOR_TMP_REG_LMUL + i).U 1461 csBundle(i).srcType(0) := srcType0 1462 csBundle(i).srcType(1) := SrcType.vp 1463 csBundle(i).rfWen := false.B 1464 csBundle(i).fpWen := false.B 1465 csBundle(i).vecWen := true.B 1466 csBundle(i).lsrc(0) := (VECTOR_TMP_REG_LMUL + i - 1).U 1467 csBundle(i).lsrc(1) := src2 1468 // csBundle(i).lsrc(2) := dest + i.U DontCare 1469 csBundle(i).ldest := ldest 1470 csBundle(i).uopIdx := i.U 1471 } 1472 csBundle(numOfUop - 1.U).rfWen := Mux(dest === 0.U, false.B, true.B) 1473 csBundle(numOfUop - 1.U).fpWen := false.B 1474 csBundle(numOfUop - 1.U).vecWen := false.B 1475 csBundle(numOfUop - 1.U).ldest := dest 1476 } 1477 1478 is(UopSplitType.VEC_MVV) { 1479 // LMUL 1480 for (i <- 0 until MAX_VLMUL) { 1481 val srcType0 = if (i == 0) SrcType.DC else SrcType.vp 1482 csBundle(i * 2 + 0).srcType(0) := srcType0 1483 csBundle(i * 2 + 0).srcType(1) := SrcType.vp 1484 csBundle(i * 2 + 0).lsrc(0) := (VECTOR_TMP_REG_LMUL + i - 1).U 1485 csBundle(i * 2 + 0).lsrc(1) := src2 1486 csBundle(i * 2 + 0).lsrc(2) := dest + i.U 1487 csBundle(i * 2 + 0).ldest := dest + i.U 1488 csBundle(i * 2 + 0).uopIdx := (i * 2 + 0).U 1489 1490 csBundle(i * 2 + 1).srcType(0) := srcType0 1491 csBundle(i * 2 + 1).srcType(1) := SrcType.vp 1492 csBundle(i * 2 + 1).lsrc(0) := (VECTOR_TMP_REG_LMUL + i - 1).U 1493 csBundle(i * 2 + 1).lsrc(1) := src2 1494 // csBundle(i).lsrc(2) := dest + i.U DontCare 1495 csBundle(i * 2 + 1).ldest := (VECTOR_TMP_REG_LMUL + i).U 1496 csBundle(i * 2 + 1).uopIdx := (i * 2 + 1).U 1497 } 1498 } 1499 is(UopSplitType.VEC_VWW) { 1500 for (i <- 0 until MAX_VLMUL*2) { 1501 when(i.U < lmul){ 1502 csBundle(i).srcType(2) := SrcType.DC 1503 csBundle(i).lsrc(0) := src2 + i.U 1504 csBundle(i).lsrc(1) := src2 + i.U 1505 // csBundle(i).lsrc(2) := dest + (2 * i).U 1506 csBundle(i).ldest := (VECTOR_TMP_REG_LMUL + i).U 1507 csBundle(i).uopIdx := i.U 1508 } otherwise { 1509 csBundle(i).srcType(2) := SrcType.DC 1510 csBundle(i).lsrc(0) := VECTOR_TMP_REG_LMUL.U + Cat((i.U-lmul),0.U(1.W)) + 1.U 1511 csBundle(i).lsrc(1) := VECTOR_TMP_REG_LMUL.U + Cat((i.U-lmul),0.U(1.W)) 1512 // csBundle(i).lsrc(2) := dest + (2 * i).U 1513 csBundle(i).ldest := (VECTOR_TMP_REG_LMUL + i).U 1514 csBundle(i).uopIdx := i.U 1515 } 1516 csBundle(numOfUop-1.U).srcType(2) := SrcType.vp 1517 csBundle(numOfUop-1.U).lsrc(0) := src1 1518 csBundle(numOfUop-1.U).lsrc(2) := dest 1519 csBundle(numOfUop-1.U).ldest := dest 1520 } 1521 } 1522 is(UopSplitType.VEC_RGATHER) { 1523 def genCsBundle_VEC_RGATHER(len:Int): Unit ={ 1524 for (i <- 0 until len) 1525 for (j <- 0 until len) { 1526 // csBundle(i * len + j).srcType(0) := SrcType.vp // SrcType.imm 1527 // csBundle(i * len + j).srcType(1) := SrcType.vp 1528 // csBundle(i * len + j).srcType(2) := SrcType.vp 1529 csBundle(i * len + j).lsrc(0) := src1 + i.U 1530 csBundle(i * len + j).lsrc(1) := src2 + j.U 1531 val vd_old = if(j==0) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j - 1).U 1532 csBundle(i * len + j).lsrc(2) := vd_old 1533 val vd = if(j==len-1) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j).U 1534 csBundle(i * len + j).ldest := vd 1535 csBundle(i * len + j).uopIdx := (i * len + j).U 1536 } 1537 } 1538 switch(vlmulReg) { 1539 is("b001".U ){ 1540 genCsBundle_VEC_RGATHER(2) 1541 } 1542 is("b010".U ){ 1543 genCsBundle_VEC_RGATHER(4) 1544 } 1545 is("b011".U ){ 1546 genCsBundle_VEC_RGATHER(8) 1547 } 1548 } 1549 } 1550 is(UopSplitType.VEC_RGATHER_VX) { 1551 def genCsBundle_RGATHER_VX(len:Int): Unit ={ 1552 for (i <- 0 until len) 1553 for (j <- 0 until len) { 1554 csBundle(i * len + j + 1).srcType(0) := SrcType.vp 1555 // csBundle(i * len + j + 1).srcType(1) := SrcType.vp 1556 // csBundle(i * len + j + 1).srcType(2) := SrcType.vp 1557 csBundle(i * len + j + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1558 csBundle(i * len + j + 1).lsrc(1) := src2 + j.U 1559 val vd_old = if(j==0) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j).U 1560 csBundle(i * len + j + 1).lsrc(2) := vd_old 1561 val vd = if(j==len-1) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j + 1).U 1562 csBundle(i * len + j + 1).ldest := vd 1563 csBundle(i * len + j + 1).uopIdx := (i * len + j).U 1564 } 1565 } 1566 // i to vector move 1567 csBundle(0).srcType(0) := Mux(src1IsImm, SrcType.imm, SrcType.reg) 1568 csBundle(0).srcType(1) := SrcType.imm 1569 csBundle(0).srcType(2) := SrcType.imm 1570 csBundle(0).lsrc(1) := 0.U 1571 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 1572 csBundle(0).fuType := FuType.i2v.U 1573 csBundle(0).fuOpType := Cat(Mux(src1IsImm, IF2VectorType.imm2Vec(2, 0), IF2VectorType.i2Vec(2, 0)), vsewReg) 1574 csBundle(0).rfWen := false.B 1575 csBundle(0).fpWen := false.B 1576 csBundle(0).vecWen := true.B 1577 genCsBundle_RGATHER_VX(1) 1578 switch(vlmulReg) { 1579 is("b001".U ){ 1580 genCsBundle_RGATHER_VX(2) 1581 } 1582 is("b010".U ){ 1583 genCsBundle_RGATHER_VX(4) 1584 } 1585 is("b011".U ){ 1586 genCsBundle_RGATHER_VX(8) 1587 } 1588 } 1589 } 1590 is(UopSplitType.VEC_RGATHEREI16) { 1591 def genCsBundle_VEC_RGATHEREI16_SEW8(len:Int): Unit ={ 1592 for (i <- 0 until len) 1593 for (j <- 0 until len) { 1594 val vd_old0 = if(j==0) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j*2-1).U 1595 val vd0 = (VECTOR_TMP_REG_LMUL + j*2 ).U 1596 csBundle((i * len + j)*2+0).lsrc(0) := src1 + (i*2+0).U 1597 csBundle((i * len + j)*2+0).lsrc(1) := src2 + j.U 1598 csBundle((i * len + j)*2+0).lsrc(2) := vd_old0 1599 csBundle((i * len + j)*2+0).ldest := vd0 1600 csBundle((i * len + j)*2+0).uopIdx := ((i * len + j)*2+0).U 1601 val vd_old1 = (VECTOR_TMP_REG_LMUL + j*2).U 1602 val vd1 = if(j==len-1) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j*2+1 ).U 1603 csBundle((i * len + j)*2+1).lsrc(0) := src1 + (i*2+1).U 1604 csBundle((i * len + j)*2+1).lsrc(1) := src2 + j.U 1605 csBundle((i * len + j)*2+1).lsrc(2) := vd_old1 1606 csBundle((i * len + j)*2+1).ldest := vd1 1607 csBundle((i * len + j)*2+1).uopIdx := ((i * len + j)*2+1).U 1608 } 1609 } 1610 def genCsBundle_VEC_RGATHEREI16(len:Int): Unit ={ 1611 for (i <- 0 until len) 1612 for (j <- 0 until len) { 1613 val vd_old = if(j==0) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j-1).U 1614 val vd = if(j==len-1) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j).U 1615 csBundle(i * len + j).lsrc(0) := src1 + i.U 1616 csBundle(i * len + j).lsrc(1) := src2 + j.U 1617 csBundle(i * len + j).lsrc(2) := vd_old 1618 csBundle(i * len + j).ldest := vd 1619 csBundle(i * len + j).uopIdx := (i * len + j).U 1620 } 1621 } 1622 def genCsBundle_VEC_RGATHEREI16_SEW32(len:Int): Unit ={ 1623 for (i <- 0 until len) 1624 for (j <- 0 until len) { 1625 val vd_old = if(j==0) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j-1).U 1626 val vd = if(j==len-1) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j).U 1627 csBundle(i * len + j).lsrc(0) := src1 + (i / 2).U 1628 csBundle(i * len + j).lsrc(1) := src2 + j.U 1629 csBundle(i * len + j).lsrc(2) := vd_old 1630 csBundle(i * len + j).ldest := vd 1631 csBundle(i * len + j).uopIdx := (i * len + j).U 1632 } 1633 } 1634 def genCsBundle_VEC_RGATHEREI16_SEW64(len:Int): Unit ={ 1635 for (i <- 0 until len) 1636 for (j <- 0 until len) { 1637 val vd_old = if(j==0) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j-1).U 1638 val vd = if(j==len-1) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j).U 1639 csBundle(i * len + j).lsrc(0) := src1 + (i / 4).U 1640 csBundle(i * len + j).lsrc(1) := src2 + j.U 1641 csBundle(i * len + j).lsrc(2) := vd_old 1642 csBundle(i * len + j).ldest := vd 1643 csBundle(i * len + j).uopIdx := (i * len + j).U 1644 } 1645 } 1646 when(!vsewReg.orR){ 1647 genCsBundle_VEC_RGATHEREI16_SEW8(1) 1648 }.elsewhen(vsewReg === VSew.e32){ 1649 genCsBundle_VEC_RGATHEREI16_SEW32(1) 1650 }.elsewhen(vsewReg === VSew.e64){ 1651 genCsBundle_VEC_RGATHEREI16_SEW64(1) 1652 }.otherwise{ 1653 genCsBundle_VEC_RGATHEREI16(1) 1654 } 1655 switch(vlmulReg) { 1656 is("b001".U) { 1657 when(!vsewReg.orR) { 1658 genCsBundle_VEC_RGATHEREI16_SEW8(2) 1659 }.elsewhen(vsewReg === VSew.e32){ 1660 genCsBundle_VEC_RGATHEREI16_SEW32(2) 1661 }.elsewhen(vsewReg === VSew.e64){ 1662 genCsBundle_VEC_RGATHEREI16_SEW64(2) 1663 }.otherwise{ 1664 genCsBundle_VEC_RGATHEREI16(2) 1665 } 1666 } 1667 is("b010".U) { 1668 when(!vsewReg.orR) { 1669 genCsBundle_VEC_RGATHEREI16_SEW8(4) 1670 }.elsewhen(vsewReg === VSew.e32){ 1671 genCsBundle_VEC_RGATHEREI16_SEW32(4) 1672 }.elsewhen(vsewReg === VSew.e64){ 1673 genCsBundle_VEC_RGATHEREI16_SEW64(4) 1674 }.otherwise{ 1675 genCsBundle_VEC_RGATHEREI16(4) 1676 } 1677 } 1678 is("b011".U) { 1679 when(vsewReg === VSew.e32){ 1680 genCsBundle_VEC_RGATHEREI16_SEW32(8) 1681 }.elsewhen(vsewReg === VSew.e64){ 1682 genCsBundle_VEC_RGATHEREI16_SEW64(8) 1683 }.otherwise{ 1684 genCsBundle_VEC_RGATHEREI16(8) 1685 } 1686 } 1687 } 1688 } 1689 is(UopSplitType.VEC_COMPRESS) { 1690 def genCsBundle_VEC_COMPRESS(len:Int): Unit = { 1691 for (i <- 0 until len) { 1692 val jlen = if (i == len-1) i+1 else i+2 1693 for (j <- 0 until jlen) { 1694 val vd_old = if(i==j) (dest + i.U) else (VECTOR_TMP_REG_LMUL + j + 1).U 1695 val vd = if(i==len-1) (dest + j.U) else { 1696 if (j == i+1) VECTOR_TMP_REG_LMUL.U else (VECTOR_TMP_REG_LMUL + j + 1).U 1697 } 1698 csBundle(i*(i+3)/2 + j).vecWen := true.B 1699 csBundle(i*(i+3)/2 + j).v0Wen := false.B 1700 val src13Type = if (j == i+1) DontCare else SrcType.vp 1701 csBundle(i*(i+3)/2 + j).srcType(0) := src13Type 1702 csBundle(i*(i+3)/2 + j).srcType(1) := SrcType.vp 1703 csBundle(i*(i+3)/2 + j).srcType(2) := src13Type 1704 if (i == 0) { 1705 csBundle(i*(i+3)/2 + j).lsrc(0) := src1 1706 } else { 1707 csBundle(i*(i+3)/2 + j).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1708 } 1709 csBundle(i*(i+3)/2 + j).lsrc(1) := src2 + i.U 1710 csBundle(i*(i+3)/2 + j).lsrc(2) := vd_old 1711 csBundle(i*(i+3)/2 + j).ldest := vd 1712 csBundle(i*(i+3)/2 + j).uopIdx := (i*(i+3)/2 + j).U 1713 } 1714 } 1715 } 1716 switch(vlmulReg) { 1717 is("b001".U ){ 1718 genCsBundle_VEC_COMPRESS(2) 1719 } 1720 is("b010".U ){ 1721 genCsBundle_VEC_COMPRESS(4) 1722 } 1723 is("b011".U ){ 1724 genCsBundle_VEC_COMPRESS(8) 1725 } 1726 } 1727 } 1728 is(UopSplitType.VEC_MVNR) { 1729 for (i <- 0 until MAX_VLMUL) { 1730 csBundle(i).lsrc(0) := src1 + i.U 1731 csBundle(i).lsrc(1) := src2 + i.U 1732 csBundle(i).lsrc(2) := dest + i.U 1733 csBundle(i).ldest := dest + i.U 1734 csBundle(i).uopIdx := i.U 1735 } 1736 } 1737 is(UopSplitType.VEC_US_LDST) { 1738 /* 1739 FMV.D.X 1740 */ 1741 csBundle(0).srcType(0) := SrcType.reg 1742 csBundle(0).srcType(1) := SrcType.imm 1743 csBundle(0).lsrc(1) := 0.U 1744 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 1745 csBundle(0).fuType := FuType.i2v.U 1746 csBundle(0).fuOpType := Cat(IF2VectorType.i2Vec(2, 0), e64) 1747 csBundle(0).rfWen := false.B 1748 csBundle(0).fpWen := false.B 1749 csBundle(0).vecWen := true.B 1750 csBundle(0).vlsInstr := true.B 1751 //LMUL 1752 for (i <- 0 until MAX_VLMUL) { 1753 csBundle(i + 1).srcType(0) := SrcType.vp 1754 csBundle(i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1755 csBundle(i + 1).lsrc(2) := dest + i.U // old vd 1756 csBundle(i + 1).ldest := dest + i.U 1757 csBundle(i + 1).uopIdx := i.U 1758 csBundle(i + 1).vlsInstr := true.B 1759 } 1760 csBundle.head.waitForward := isUsSegment 1761 csBundle(numOfUop - 1.U).blockBackward := isUsSegment 1762 } 1763 is(UopSplitType.VEC_US_FF_LD) { 1764 csBundle(0).srcType(0) := SrcType.reg 1765 csBundle(0).srcType(1) := SrcType.imm 1766 csBundle(0).lsrc(1) := 0.U 1767 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 1768 csBundle(0).fuType := FuType.i2v.U 1769 csBundle(0).fuOpType := Cat(IF2VectorType.i2Vec(2, 0), e64) 1770 csBundle(0).rfWen := false.B 1771 csBundle(0).fpWen := false.B 1772 csBundle(0).vecWen := true.B 1773 csBundle(0).vlsInstr := true.B 1774 //LMUL 1775 for (i <- 0 until MAX_VLMUL) { 1776 csBundle(i + 1).srcType(0) := SrcType.vp 1777 csBundle(i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1778 csBundle(i + 1).lsrc(2) := dest + i.U // old vd 1779 csBundle(i + 1).ldest := dest + i.U 1780 csBundle(i + 1).uopIdx := i.U 1781 csBundle(i + 1).vlsInstr := true.B 1782 } 1783 csBundle.head.waitForward := isUsSegment 1784 csBundle(numOfUop - 1.U).blockBackward := isUsSegment 1785 // last uop read vl and write vl 1786 csBundle(numOfUop - 1.U).srcType(0) := SrcType.no 1787 csBundle(numOfUop - 1.U).srcType(1) := SrcType.no 1788 csBundle(numOfUop - 1.U).srcType(2) := SrcType.no 1789 csBundle(numOfUop - 1.U).srcType(3) := SrcType.no 1790 csBundle(numOfUop - 1.U).srcType(4) := SrcType.vp 1791 csBundle(numOfUop - 1.U).lsrc(4) := Vl_IDX.U 1792 // vtype 1793 csBundle(numOfUop - 1.U).vecWen := false.B 1794 csBundle(numOfUop - 1.U).vlWen := true.B 1795 csBundle(numOfUop - 1.U).ldest := Vl_IDX.U 1796 } 1797 is(UopSplitType.VEC_S_LDST) { 1798 /* 1799 FMV.D.X 1800 */ 1801 csBundle(0).srcType(0) := SrcType.reg 1802 csBundle(0).srcType(1) := SrcType.imm 1803 csBundle(0).lsrc(1) := 0.U 1804 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 1805 csBundle(0).fuType := FuType.i2v.U 1806 csBundle(0).fuOpType := Cat(IF2VectorType.i2Vec(2, 0), e64) 1807 csBundle(0).rfWen := false.B 1808 csBundle(0).fpWen := false.B 1809 csBundle(0).vecWen := true.B 1810 csBundle(0).vlsInstr := true.B 1811 1812 csBundle(1).srcType(0) := SrcType.reg 1813 csBundle(1).srcType(1) := SrcType.imm 1814 csBundle(1).lsrc(0) := latchedInst.lsrc(1) 1815 csBundle(1).lsrc(1) := 0.U 1816 csBundle(1).ldest := (VECTOR_TMP_REG_LMUL + 1).U 1817 csBundle(1).fuType := FuType.i2v.U 1818 csBundle(1).fuOpType := Cat(IF2VectorType.i2Vec(2, 0), e64) 1819 csBundle(1).rfWen := false.B 1820 csBundle(1).fpWen := false.B 1821 csBundle(1).vecWen := true.B 1822 csBundle(1).vlsInstr := true.B 1823 1824 //LMUL 1825 for (i <- 0 until MAX_VLMUL) { 1826 csBundle(i + 2).srcType(0) := SrcType.vp 1827 csBundle(i + 2).srcType(1) := SrcType.vp 1828 csBundle(i + 2).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1829 csBundle(i + 2).lsrc(1) := (VECTOR_TMP_REG_LMUL + 1).U 1830 csBundle(i + 2).lsrc(2) := dest + i.U // old vd 1831 csBundle(i + 2).ldest := dest + i.U 1832 csBundle(i + 2).uopIdx := i.U 1833 csBundle(i + 2).vlsInstr := true.B 1834 } 1835 csBundle.head.waitForward := isSdSegment 1836 csBundle(numOfUop - 1.U).blockBackward := isSdSegment 1837 } 1838 is(UopSplitType.VEC_I_LDST) { 1839 def genCsBundle_SEGMENT_INDEXED_LOADSTORE(lmul:Int, nf:Int): Unit ={ 1840 for (i <- 0 until MAX_VLMUL) { 1841 val vecWen = if (i < lmul * nf) true.B else false.B 1842 val src2Type = if (i < lmul * nf) SrcType.vp else SrcType.no 1843 csBundle(i + 1).srcType(0) := SrcType.vp 1844 csBundle(i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1845 csBundle(i + 1).srcType(1) := SrcType.no 1846 csBundle(i + 1).lsrc(1) := src2 + i.U 1847 csBundle(i + 1).srcType(2) := src2Type 1848 csBundle(i + 1).lsrc(2) := dest + i.U 1849 csBundle(i + 1).ldest := dest + i.U 1850 csBundle(i + 1).rfWen := false.B 1851 csBundle(i + 1).fpWen := false.B 1852 csBundle(i + 1).vecWen := vecWen 1853 csBundle(i + 1).uopIdx := i.U 1854 csBundle(i + 1).vlsInstr := true.B 1855 } 1856 } 1857 def genCsBundle_SEGMENT_INDEXED_LOADSTORE_SRC1(emul:Int): Unit ={ 1858 for (i <- 0 until MAX_VLMUL) { 1859 val src1Type = if (i < emul) SrcType.vp else SrcType.no 1860 csBundle(i + 1).srcType(1) := src1Type 1861 csBundle(i + 1).lsrc(1) := src2 + i.U 1862 } 1863 } 1864 1865 val vlmul = vlmulReg 1866 val vsew = Cat(0.U(1.W), vsewReg) 1867 val veew = Cat(0.U(1.W), width) 1868 val vemul: UInt = veew.asUInt + 1.U + vlmul.asUInt + ~vsew.asUInt 1869 val simple_lmul = MuxLookup(vlmul, 0.U(2.W))(Seq( 1870 "b001".U -> 1.U, 1871 "b010".U -> 2.U, 1872 "b011".U -> 3.U 1873 )) 1874 val simple_emul = MuxLookup(vemul, 0.U(2.W))(Seq( 1875 "b001".U -> 1.U, 1876 "b010".U -> 2.U, 1877 "b011".U -> 3.U 1878 )) 1879 csBundle(0).srcType(0) := SrcType.reg 1880 csBundle(0).srcType(1) := SrcType.imm 1881 csBundle(0).lsrc(1) := 0.U 1882 csBundle(0).ldest := VECTOR_TMP_REG_LMUL.U 1883 csBundle(0).fuType := FuType.i2v.U 1884 csBundle(0).fuOpType := Cat(IF2VectorType.i2Vec(2, 0), e64) 1885 csBundle(0).rfWen := false.B 1886 csBundle(0).fpWen := false.B 1887 csBundle(0).vecWen := true.B 1888 csBundle(0).vlsInstr := true.B 1889 1890 //LMUL 1891 when(nf === 0.U) { 1892 for (i <- 0 until MAX_VLMUL) { 1893 indexedLSRegOffset(i).src := Cat(simple_emul, simple_lmul) 1894 val offsetVs2 = indexedLSRegOffset(i).outOffsetVs2 1895 val offsetVd = indexedLSRegOffset(i).outOffsetVd 1896 csBundle(i + 1).srcType(0) := SrcType.vp 1897 csBundle(i + 1).lsrc(0) := VECTOR_TMP_REG_LMUL.U 1898 csBundle(i + 1).lsrc(1) := Mux1H(UIntToOH(offsetVs2, MAX_VLMUL), (0 until MAX_VLMUL).map(j => src2 + j.U)) 1899 csBundle(i + 1).srcType(2) := SrcType.vp 1900 // lsrc2 is old vd 1901 csBundle(i + 1).lsrc(2) := Mux1H(UIntToOH(offsetVd, MAX_VLMUL), (0 until MAX_VLMUL).map(j => dest + j.U)) 1902 csBundle(i + 1).ldest := Mux1H(UIntToOH(offsetVd, MAX_VLMUL), (0 until MAX_VLMUL).map(j => dest + j.U)) 1903 csBundle(i + 1).uopIdx := i.U 1904 csBundle(i + 1).vlsInstr := true.B 1905 } 1906 }.otherwise{ 1907 // nf > 1, is segment indexed load/store 1908 // gen src0, vd 1909 switch(simple_lmul) { 1910 is(0.U) { 1911 switch(nf) { 1912 is(1.U) { 1913 genCsBundle_SEGMENT_INDEXED_LOADSTORE(1, 2) 1914 } 1915 is(2.U) { 1916 genCsBundle_SEGMENT_INDEXED_LOADSTORE(1, 3) 1917 } 1918 is(3.U) { 1919 genCsBundle_SEGMENT_INDEXED_LOADSTORE(1, 4) 1920 } 1921 is(4.U) { 1922 genCsBundle_SEGMENT_INDEXED_LOADSTORE(1, 5) 1923 } 1924 is(5.U) { 1925 genCsBundle_SEGMENT_INDEXED_LOADSTORE(1, 6) 1926 } 1927 is(6.U) { 1928 genCsBundle_SEGMENT_INDEXED_LOADSTORE(1, 7) 1929 } 1930 is(7.U) { 1931 genCsBundle_SEGMENT_INDEXED_LOADSTORE(1, 8) 1932 } 1933 } 1934 } 1935 is(1.U) { 1936 switch(nf) { 1937 is(1.U) { 1938 genCsBundle_SEGMENT_INDEXED_LOADSTORE(2, 2) 1939 } 1940 is(2.U) { 1941 genCsBundle_SEGMENT_INDEXED_LOADSTORE(2, 3) 1942 } 1943 is(3.U) { 1944 genCsBundle_SEGMENT_INDEXED_LOADSTORE(2, 4) 1945 } 1946 } 1947 } 1948 is(2.U) { 1949 switch(nf) { 1950 is(1.U) { 1951 genCsBundle_SEGMENT_INDEXED_LOADSTORE(4, 2) 1952 } 1953 } 1954 } 1955 } 1956 1957 // gen src1 1958 switch(simple_emul) { 1959 is(0.U) { 1960 genCsBundle_SEGMENT_INDEXED_LOADSTORE_SRC1(1) 1961 } 1962 is(1.U) { 1963 genCsBundle_SEGMENT_INDEXED_LOADSTORE_SRC1(2) 1964 } 1965 is(2.U) { 1966 genCsBundle_SEGMENT_INDEXED_LOADSTORE_SRC1(4) 1967 } 1968 is(3.U) { 1969 genCsBundle_SEGMENT_INDEXED_LOADSTORE_SRC1(8) 1970 } 1971 } 1972 1973 // when is vstore instructions, not set vecwen 1974 when(isVstore) { 1975 for (i <- 0 until MAX_VLMUL) { 1976 csBundle(i + 1).vecWen := false.B 1977 } 1978 } 1979 } 1980 csBundle.head.waitForward := isIxSegment 1981 csBundle(numOfUop - 1.U).blockBackward := isIxSegment 1982 } 1983 } 1984 1985 //readyFromRename Counter 1986 val readyCounter = Mux(outReadys.head, RenameWidth.U, 0.U) 1987 1988 // The left uops of the complex inst in ComplexDecoder can be send out this cycle 1989 val thisAllOut = uopRes <= readyCounter 1990 1991 val count = RegInit(0.U(log2Up(maxUopSize/RenameWidth + 1).W)) 1992 val countNext = WireInit(count) 1993 1994 switch(state) { 1995 is(s_idle) { 1996 when (inValid) { 1997 stateNext := s_active 1998 uopResNext := inUopInfo.numOfUop 1999 countNext := 0.U 2000 } 2001 } 2002 is(s_active) { 2003 when (thisAllOut) { 2004 when (inValid) { 2005 stateNext := s_active 2006 uopResNext := inUopInfo.numOfUop 2007 }.otherwise { 2008 stateNext := s_idle 2009 uopResNext := 0.U 2010 } 2011 countNext := 0.U 2012 }.otherwise { 2013 stateNext := s_active 2014 uopResNext := uopRes - readyCounter 2015 countNext := count + outReadys.head.asUInt 2016 } 2017 } 2018 } 2019 2020 state := Mux(io.redirect, s_idle, stateNext) 2021 uopRes := Mux(io.redirect, 0.U, uopResNext) 2022 count := Mux(io.redirect, 0.U, countNext) 2023 2024 val complexNum = Mux(uopRes > readyCounter, readyCounter, uopRes) 2025 2026 fixedDecodedInst := csBundle 2027 2028 // when vstart is not zero, the last uop will modify vstart to zero 2029 // therefore, blockback and flush pipe 2030 fixedDecodedInst(numOfUop - 1.U).flushPipe := (vstartReg =/= 0.U) || latchedInst.flushPipe 2031 val uopsSeq = (0 until RenameWidth).map(i => VecInit(fixedDecodedInst.zipWithIndex.filter(_._2 % RenameWidth == i).map(_._1))) 2032 2033 /** Generate output insts and valid signals */ 2034 for(i <- 0 until RenameWidth) { 2035 outValids(i) := complexNum > i.U 2036 outDecodedInsts(i) := uopsSeq(i)(count) 2037 } 2038 2039 /** Generate number of valid output insts */ 2040 outComplexNum := Mux(state === s_active, complexNum, 0.U) 2041 inReady := state === s_idle || state === s_active && thisAllOut 2042 2043 2044 XSError(inValid && inUopInfo.numOfUop === 0.U, 2045 p"uop number ${inUopInfo.numOfUop} is illegal, cannot be zero") 2046// val validSimple = Wire(Vec(DecodeWidth, Bool())) 2047// validSimple.zip(io.validFromIBuf.zip(io.isComplex)).map{ case (dst, (src1, src2)) => dst := src1 && !src2 } 2048// val notInf = Wire(Vec(DecodeWidth, Bool())) 2049// notInf.drop(1).zip(io.validFromIBuf.drop(1).zip(validSimple.drop(1))).map{ case (dst, (src1, src2)) => dst := !src1 || src2 } 2050// notInf(0) := !io.validFromIBuf(0) || validSimple(0) || (io.isComplex(0) && io.in0pc === io.simple.decodedInst.pc) 2051// val notInfVec = Wire(Vec(DecodeWidth, Bool())) 2052// notInfVec.zipWithIndex.map{ case (dst, i) => dst := Cat(notInf.take(i + 1)).andR} 2053// 2054// complexNum := Mux(io.validFromIBuf(0) && readyCounter.orR , 2055// Mux(uopRes0 > readyCounter, readyCounter, uopRes0), 2056// 0.U) 2057// validToRename.zipWithIndex.foreach{ 2058// case(dst, i) => 2059// val validFix = Mux(complexNum.orR, validSimple((i+1).U - complexNum), validSimple(i)) 2060// dst := MuxCase(false.B, Seq( 2061// (io.validFromIBuf(0) && readyCounter.orR && uopRes0 > readyCounter) -> Mux(readyCounter > i.U, true.B, false.B), 2062// (io.validFromIBuf(0) && readyCounter.orR && !(uopRes0 > readyCounter)) -> Mux(complexNum > i.U, true.B, validFix && notInfVec(i.U - complexNum) && io.readyFromRename(i)), 2063// ).toSeq) 2064// } 2065// 2066// readyToIBuf.zipWithIndex.foreach { 2067// case (dst, i) => 2068// val readyToIBuf0 = Mux(io.isComplex(0), io.in0pc === io.simple.decodedInst.pc, true.B) 2069// dst := MuxCase(true.B, Seq( 2070// (io.validFromIBuf(0) && uopRes0 > readyCounter || !readyCounter.orR) -> false.B, 2071// (io.validFromIBuf(0) && !(uopRes0 > readyCounter) && readyCounter.orR) -> (if (i==0) readyToIBuf0 else Mux(RenameWidth.U - complexNum >= i.U, notInfVec(i) && validSimple(i) && io.readyFromRename(i), false.B)) 2072// ).toSeq) 2073// } 2074// 2075// io.deq.decodedInsts := decodedInsts 2076// io.deq.complexNum := complexNum 2077// io.deq.validToRename := validToRename 2078// io.deq.readyToIBuf := readyToIBuf 2079} 2080