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.fu.vector 18 19import chipsalliance.rocketchip.config.Parameters 20import chisel3._ 21import chisel3.util.{Mux1H, _} 22import xiangshan.backend.fu.FunctionUnit 23import xiangshan.{SelImm, SrcType} 24import utility._ 25 26abstract class VPUDataModule(len: Int = 128)(implicit p: Parameters) extends FunctionUnit(len: Int) 27{ 28 val rm = IO(Input(UInt(3.W))) 29 val fflags = IO(Output(UInt(5.W))) 30 val vstart = IO(Input(UInt(XLEN.W))) 31 val vxrm = IO(Input(UInt(2.W))) 32 val vxsat = IO(Output(UInt(1.W))) 33 val needReverse = Wire(Bool()) 34 val needClearMask = Wire(Bool()) 35 val src1Sew = Wire(UInt(2.W)) 36 val src1NeedSew = Wire(Bool()) 37 38 // rename signal 39 val in = io.in.bits 40 val ctrl = in.uop.ctrl 41 val vtype = ctrl.vconfig.vtype 42 43 // for generate src1 and src2 44 src1NeedSew := true.B 45 src1Sew := vtype.vsew(1,0) 46 private val immExt = VecInit(Seq.fill(VLEN/XLEN)(VecImmExtractor(ctrl.selImm, src1Sew, ctrl.imm))).asUInt 47 private val imm = Mux(src1NeedSew, immExt, ctrl.imm(4,0)) 48 private val src1Ext = VecExtractor(src1Sew, in.src(0)) 49 private val src1 = Mux(SrcType.isFp(ctrl.srcType(0))&&src1NeedSew, src1Ext, in.src(0)) 50 private val _vs1 = Mux(SrcType.isImm(ctrl.srcType(0)), imm, src1) 51 private val _vs2 = in.src(1) 52 53 // generate src1 and src2 54 val vs1 = Mux(needReverse, _vs2, _vs1) 55 val vs2 = Mux(needReverse, _vs1, _vs2) 56 val mask = Mux(needClearMask, 0.U, in.src(3)) 57 58 // connect io 59 io.out.bits.uop := DontCare 60 io.in.ready := DontCare 61 fflags := DontCare 62 vxsat := DontCare 63 64} 65 66 67abstract class VPUSubModule(len: Int = 128)(implicit p: Parameters) extends FunctionUnit(len: Int) 68{ 69 val rm = IO(Input(UInt(3.W))) 70 val fflags = IO(Output(UInt(5.W))) 71 val vstart = IO(Input(UInt(XLEN.W))) 72 val vxrm = IO(Input(UInt(2.W))) 73 val vxsat = IO(Output(UInt(1.W))) 74 75 val dataModule: Seq[VPUDataModule] 76 val select : Seq[Bool] 77 78 def connectDataModule = { 79 // def some signal 80 val dataReg = Reg(io.out.bits.data.cloneType) 81 val dataWire = Wire(dataReg.cloneType) 82 val s_idle :: s_compute :: s_finish :: Nil = Enum(3) 83 val state = RegInit(s_idle) 84 85 val outValid = dataModule.map(_.io.out.valid).reduce(_||_) 86 val outFire = dataModule.map(_.io.out.fire()).reduce(_||_) 87 // reg input signal 88 val s0_uopReg = Reg(io.in.bits.uop.cloneType) 89 val s0_selectReg = Reg(VecInit(select).asUInt().cloneType) 90 val inHs = io.in.fire() 91 when(inHs && state === s_idle){ 92 s0_uopReg := io.in.bits.uop 93 s0_selectReg := VecInit(select).asUInt() 94 } 95 dataReg := Mux(outValid, dataWire, dataReg) 96 97 // fsm 98 switch (state) { 99 is (s_idle) { 100 state := Mux(inHs, s_compute, s_idle) 101 } 102 is (s_compute) { 103 state := Mux(outValid, Mux(outFire, s_idle, s_finish), 104 s_compute) 105 } 106 is (s_finish) { 107 state := Mux(io.out.fire(), s_idle, s_finish) 108 } 109 } 110 111 // connect 112 dataWire := Mux1H(s0_selectReg, dataModule.map(_.io.out.bits.data)) 113 dataModule.zipWithIndex.foreach{ case(l, i) => 114 l.io.in.bits <> io.in.bits 115 l.io.redirectIn := DontCare 116 l.rm := rm 117 l.vxrm := vxrm 118 l.vstart := vstart 119 l.io.in.valid := io.in.valid && state === s_idle && select(i) 120 l.io.out.ready := io.out.ready 121 } 122 vxsat := Mux1H(s0_selectReg, dataModule.map(_.vxsat)) 123 fflags := Mux1H(s0_selectReg, dataModule.map(_.fflags)) 124 125 io.out.bits.data := Mux(state === s_compute && outFire, dataWire, dataReg) 126 io.out.bits.uop := s0_uopReg 127 io.out.valid := state === s_compute && outValid || state === s_finish 128 io.in.ready := state === s_idle 129 } 130} 131 132 133object VecImmExtractor { 134 def Imm_OPIVIS(imm: UInt): UInt = { 135 SignExt(imm(4,0), 8) 136 } 137 def Imm_OPIVIU(imm: UInt): UInt = { 138 ZeroExt(imm(4,0), 8) 139 } 140 141 def imm_sew(sew: UInt, imm: UInt): UInt = { 142 val _imm = SignExt(imm(7,0), 64) 143 LookupTree(sew(1,0), List( 144 "b00".U -> VecInit(Seq.fill(8)(_imm(7,0))).asUInt, 145 "b01".U -> VecInit(Seq.fill(4)(_imm(15,0))).asUInt, 146 "b10".U -> VecInit(Seq.fill(2)(_imm(31,0))).asUInt, 147 "b11".U -> _imm(63,0), 148 )) 149 } 150 151 def apply(immType: UInt, sew: UInt, imm: UInt): UInt = { 152 val _imm = Mux(immType === SelImm.IMM_OPIVIS, Imm_OPIVIS(imm), Imm_OPIVIU(imm)) 153 imm_sew(sew, _imm(7,0)) 154 } 155} 156 157object VecExtractor{ 158 def xf2v_sew(sew: UInt, xf:UInt): UInt = { 159 LookupTree(sew(1, 0), List( 160 "b00".U -> VecInit(Seq.fill(16)(xf(7, 0))).asUInt, 161 "b01".U -> VecInit(Seq.fill(8)(xf(15, 0))).asUInt, 162 "b10".U -> VecInit(Seq.fill(4)(xf(31, 0))).asUInt, 163 "b11".U -> VecInit(Seq.fill(2)(xf(63, 0))).asUInt, 164 )) 165 } 166 167 def apply(sew: UInt, xf: UInt): UInt = { 168 xf2v_sew(sew, xf) 169 } 170}