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