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 */ 17 18 19package xiangshan.backend.fu.vector 20 21import chipsalliance.rocketchip.config.Parameters 22import chisel3._ 23import chisel3.util._ 24import utils._ 25import utility._ 26import yunsuan.vector.VectorIntAdder 27import yunsuan.{VipuType, VectorElementFormat} 28import xiangshan.{SrcType, SelImm} 29import xiangshan.backend.fu.FunctionUnit 30import xiangshan.XSCoreParamsKey 31 32class VIPU(implicit p: Parameters) extends FunctionUnit(p(XSCoreParamsKey).VLEN) { 33 XSError(io.in.valid && io.in.bits.uop.ctrl.fuOpType === VipuType.dummy, "VIPU OpType not supported") 34 35 val uop = io.in.bits.uop 36 val ctrl = uop.ctrl 37 val vtype = ctrl.vconfig.vtype 38 val v0 = ~0.U(8.W) // TODO 39 40 // TODO: mv VecImmExtractor from exe stage to read rf stage(or forward stage). 41 val imm = VecInit(Seq.fill(VLEN/XLEN)(VecImmExtractor(ctrl.selImm, vtype.vsew, ctrl.imm))).asUInt 42 43 val _src1 = Mux(SrcType.isImm(ctrl.srcType(0)), imm, io.in.bits.src(0)) 44 val _src2 = io.in.bits.src(1) 45 val src1 = Mux(VipuType.needReverse(ctrl.fuOpType), _src2, _src1) 46 val src2 = Mux(VipuType.needReverse(ctrl.fuOpType), _src1, _src2) 47 val carryIn = Mux(ctrl.fuOpType === VipuType.madc0, 0.U(8.W), v0) 48 49 val AdderWidth = XLEN 50 val NumAdder = VLEN / XLEN 51 val adder = Seq.fill(NumAdder)(Module(new VectorIntAdder())) 52 for(i <- 0 until NumAdder) { 53 adder(i).io.in_0 := src1(AdderWidth*(i+1)-1, AdderWidth*i) 54 adder(i).io.in_1 := src2(AdderWidth*(i+1)-1, AdderWidth*i) 55 adder(i).io.int_format := vtype.vsew // TODO 56 adder(i).io.op_code := ctrl.fuOpType 57 adder(i).io.carry_or_borrow_in := carryIn // TODO 58 adder(i).io.uop_index := DontCare // TODO 59 } 60 val adder_result = VecInit(adder.map(_.io.out)).asUInt 61 val adder_carry = LookupTree(vtype.vsew(1,0), List( 62 "b00".U -> Cat(~0.U((VLEN-16).W), VecInit(adder.map(_.io.carry_or_borrow_or_compare_out(7,0))).asUInt), 63 "b01".U -> Cat(~0.U((VLEN-8).W), VecInit(adder.map(_.io.carry_or_borrow_or_compare_out(3,0))).asUInt), 64 "b10".U -> Cat(~0.U((VLEN-4).W), VecInit(adder.map(_.io.carry_or_borrow_or_compare_out(1,0))).asUInt), 65 "b11".U -> Cat(~0.U((VLEN-2).W), VecInit(adder.map(_.io.carry_or_borrow_or_compare_out(0))).asUInt), 66 )) 67 68 io.out.bits.data := Mux(VipuType.outIsCarry(ctrl.fuOpType), adder_carry, adder_result) 69 io.out.bits.uop := io.in.bits.uop 70 io.out.valid := io.in.valid 71 io.in.ready := io.out.ready 72} 73 74object VecImmExtractor { 75 def Imm_OPIVIS(imm: UInt): UInt = { 76 SignExt(imm(4,0), 8) 77 } 78 def Imm_OPIVIU(imm: UInt): UInt = { 79 ZeroExt(imm(4,0), 8) 80 } 81 82 def imm_sew(sew: UInt, imm: UInt): UInt = { 83 val _imm = SignExt(imm(7,0), 64) 84 LookupTree(sew(1,0), List( 85 "b00".U -> VecInit(Seq.fill(8)(_imm(7,0))).asUInt, 86 "b01".U -> VecInit(Seq.fill(4)(_imm(15,0))).asUInt, 87 "b10".U -> VecInit(Seq.fill(2)(_imm(31,0))).asUInt, 88 "b11".U -> _imm(63,0), 89 )) 90 } 91 92 def apply(immType: UInt, sew: UInt, imm: UInt): UInt = { 93 val _imm = Mux(immType === SelImm.IMM_OPIVIS, Imm_OPIVIS(imm), Imm_OPIVIU(imm)) 94 imm_sew(sew, _imm(7,0)) 95 } 96} 97