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._ 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: VPUDataModule 63 64 def connectDataModule = { 65 // def some signal 66 val dataReg = Reg(io.out.bits.data.cloneType) 67 val dataWire = Wire(dataReg.cloneType) 68 val s_idle :: s_compute :: s_finish :: Nil = Enum(3) 69 val state = RegInit(s_idle) 70 71 val outValid = dataModule.io.out.valid 72 val outFire = dataModule.io.out.fire() 73 74 // reg input signal 75 val s0_uopReg = Reg(io.in.bits.uop.cloneType) 76 val inHs = io.in.fire() 77 when(inHs && state === s_idle){ 78 s0_uopReg := io.in.bits.uop 79 } 80 dataReg := Mux(outValid, dataWire, dataReg) 81 82 // fsm 83 switch (state) { 84 is (s_idle) { 85 state := Mux(inHs, s_compute, s_idle) 86 } 87 is (s_compute) { 88 state := Mux(outValid, Mux(outFire, s_idle, s_finish), 89 s_compute) 90 } 91 is (s_finish) { 92 state := Mux(io.out.fire(), s_idle, s_finish) 93 } 94 } 95 96 // connect VIAlu 97 dataWire := dataModule.io.out.bits.data 98 dataModule.io.in.bits <> io.in.bits 99 dataModule.io.redirectIn := DontCare // TODO : 100 dataModule.vxrm := vxrm 101 dataModule.vstart := vstart 102 io.out.bits.data := Mux(state === s_compute && outFire, dataWire, dataReg) 103 io.out.bits.uop := s0_uopReg 104 vxsat := dataModule.vxsat 105 106 dataModule.io.in.valid := io.in.valid && state === s_idle 107 io.out.valid := state === s_compute && outValid || state === s_finish 108 dataModule.io.out.ready := io.out.ready 109 io.in.ready := state === s_idle 110 } 111} 112 113 114object VecImmExtractor { 115 def Imm_OPIVIS(imm: UInt): UInt = { 116 SignExt(imm(4,0), 8) 117 } 118 def Imm_OPIVIU(imm: UInt): UInt = { 119 ZeroExt(imm(4,0), 8) 120 } 121 122 def imm_sew(sew: UInt, imm: UInt): UInt = { 123 val _imm = SignExt(imm(7,0), 64) 124 LookupTree(sew(1,0), List( 125 "b00".U -> VecInit(Seq.fill(8)(_imm(7,0))).asUInt, 126 "b01".U -> VecInit(Seq.fill(4)(_imm(15,0))).asUInt, 127 "b10".U -> VecInit(Seq.fill(2)(_imm(31,0))).asUInt, 128 "b11".U -> _imm(63,0), 129 )) 130 } 131 132 def apply(immType: UInt, sew: UInt, imm: UInt): UInt = { 133 val _imm = Mux(immType === SelImm.IMM_OPIVIS, Imm_OPIVIS(imm), Imm_OPIVIU(imm)) 134 imm_sew(sew, _imm(7,0)) 135 } 136}