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