xref: /XiangShan/src/main/scala/xiangshan/backend/fu/vector/VPUSubModule.scala (revision 83ba63b34cf09b33c0a9e1b3203138e51af4491b)
13ebdf758SXuan Hu///***************************************************************************************
23ebdf758SXuan Hu//* Copyright (c) 2020-2021 Institute of Computing Technology, Chinese Academy of Sciences
33ebdf758SXuan Hu//* Copyright (c) 2020-2021 Peng Cheng Laboratory
43ebdf758SXuan Hu//*
53ebdf758SXuan Hu//* XiangShan is licensed under Mulan PSL v2.
63ebdf758SXuan Hu//* You can use this software according to the terms and conditions of the Mulan PSL v2.
73ebdf758SXuan Hu//* You may obtain a copy of Mulan PSL v2 at:
83ebdf758SXuan Hu//*          http://license.coscl.org.cn/MulanPSL2
93ebdf758SXuan Hu//*
103ebdf758SXuan Hu//* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
113ebdf758SXuan Hu//* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
123ebdf758SXuan Hu//* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
133ebdf758SXuan Hu//*
143ebdf758SXuan Hu//* See the Mulan PSL v2 for more details.
153ebdf758SXuan Hu//***************************************************************************************/
163ebdf758SXuan Hu//
173ebdf758SXuan Hu//package xiangshan.backend.fu.vector
183ebdf758SXuan Hu//
19*83ba63b3SXuan Hu//import org.chipsalliance.cde.config.Parameters
203ebdf758SXuan Hu//import chisel3._
213ebdf758SXuan Hu//import chisel3.util.{Mux1H, _}
223ebdf758SXuan Hu//import xiangshan.backend.fu.FunctionUnit
233ebdf758SXuan Hu//import xiangshan.{SelImm, SrcType}
243ebdf758SXuan Hu//import utility._
253ebdf758SXuan Hu//
263ebdf758SXuan Hu//abstract class VPUDataModule(len: Int = 128)(implicit p: Parameters) extends FunctionUnit(len: Int)
273ebdf758SXuan Hu//{
283ebdf758SXuan Hu//  val rm = IO(Input(UInt(3.W)))
293ebdf758SXuan Hu//  val fflags = IO(Output(UInt(5.W)))
303ebdf758SXuan Hu//  val vstart = IO(Input(UInt(XLEN.W)))
313ebdf758SXuan Hu//  val vxrm = IO(Input(UInt(2.W)))
323ebdf758SXuan Hu//  val vxsat = IO(Output(UInt(1.W)))
333ebdf758SXuan Hu//  val needReverse = Wire(Bool())
343ebdf758SXuan Hu//  val needClearMask = Wire(Bool())
353ebdf758SXuan Hu//  val src1Sew = Wire(UInt(2.W))
363ebdf758SXuan Hu//  val src1NeedSew = Wire(Bool())
373ebdf758SXuan Hu//
383ebdf758SXuan Hu//  // rename signal
393ebdf758SXuan Hu//  val in = io.in.bits
403ebdf758SXuan Hu//  val ctrl = in.uop.ctrl
413ebdf758SXuan Hu//  val vtype = ctrl.vconfig.vtype
423ebdf758SXuan Hu//
433ebdf758SXuan Hu//  // for generate src1 and src2
443ebdf758SXuan Hu//  src1NeedSew := true.B
453ebdf758SXuan Hu//  src1Sew := vtype.vsew(1,0)
463ebdf758SXuan Hu//  private val immExt = VecInit(Seq.fill(VLEN/XLEN)(VecImmExtractor(ctrl.selImm, src1Sew, ctrl.imm))).asUInt
473ebdf758SXuan Hu//  private val imm = Mux(src1NeedSew, immExt, ctrl.imm(4,0))
483ebdf758SXuan Hu//  private val src1Ext = VecExtractor(src1Sew, in.src(0))
493ebdf758SXuan Hu//  private val src1 = Mux(SrcType.isFp(ctrl.srcType(0))&&src1NeedSew, src1Ext, in.src(0))
503ebdf758SXuan Hu//  private val _vs1 = Mux(SrcType.isImm(ctrl.srcType(0)), imm, src1)
513ebdf758SXuan Hu//  private val _vs2 = in.src(1)
523ebdf758SXuan Hu//
533ebdf758SXuan Hu//  // generate src1 and src2
543ebdf758SXuan Hu//  val vs1 = Mux(needReverse, _vs2, _vs1)
553ebdf758SXuan Hu//  val vs2 = Mux(needReverse, _vs1, _vs2)
563ebdf758SXuan Hu//  val mask = Mux(needClearMask, 0.U, in.src(3))
573ebdf758SXuan Hu//
583ebdf758SXuan Hu//  // connect io
593ebdf758SXuan Hu//  io.out.bits.uop := DontCare
603ebdf758SXuan Hu//  io.in.ready := DontCare
613ebdf758SXuan Hu//  fflags := DontCare
623ebdf758SXuan Hu//  vxsat := DontCare
633ebdf758SXuan Hu//
643ebdf758SXuan Hu//}
653ebdf758SXuan Hu//
663ebdf758SXuan Hu//
673ebdf758SXuan Hu//abstract class VPUSubModule(len: Int = 128)(implicit p: Parameters) extends FunctionUnit(len: Int)
683ebdf758SXuan Hu//{
693ebdf758SXuan Hu//  val rm = IO(Input(UInt(3.W)))
703ebdf758SXuan Hu//  val fflags = IO(Output(UInt(5.W)))
713ebdf758SXuan Hu//  val vstart = IO(Input(UInt(XLEN.W)))
723ebdf758SXuan Hu//  val vxrm = IO(Input(UInt(2.W)))
733ebdf758SXuan Hu//  val vxsat = IO(Output(UInt(1.W)))
743ebdf758SXuan Hu//
753ebdf758SXuan Hu//  val dataModule: Seq[VPUDataModule]
763ebdf758SXuan Hu//  val select : Seq[Bool]
773ebdf758SXuan Hu//
783ebdf758SXuan Hu//  def connectDataModule = {
793ebdf758SXuan Hu//  // def some signal
803ebdf758SXuan Hu//    val dataReg = Reg(io.out.bits.data.cloneType)
813ebdf758SXuan Hu//    val dataWire = Wire(dataReg.cloneType)
823ebdf758SXuan Hu//    val s_idle :: s_compute :: s_finish :: Nil = Enum(3)
833ebdf758SXuan Hu//    val state = RegInit(s_idle)
843ebdf758SXuan Hu//
853ebdf758SXuan Hu//    val outValid = dataModule.map(_.io.out.valid).reduce(_||_)
863ebdf758SXuan Hu//    val outFire = dataModule.map(_.io.out.fire()).reduce(_||_)
873ebdf758SXuan Hu//  // reg input signal
883ebdf758SXuan Hu//    val s0_uopReg = Reg(io.in.bits.uop.cloneType)
89*83ba63b3SXuan Hu//    val s0_selectReg = Reg(VecInit(select).asUInt.cloneType)
903ebdf758SXuan Hu//    val inHs = io.in.fire()
913ebdf758SXuan Hu//    when(inHs && state === s_idle){
923ebdf758SXuan Hu//        s0_uopReg := io.in.bits.uop
93*83ba63b3SXuan Hu//        s0_selectReg := VecInit(select).asUInt
943ebdf758SXuan Hu//      }
953ebdf758SXuan Hu//    dataReg := Mux(outValid, dataWire, dataReg)
963ebdf758SXuan Hu//
973ebdf758SXuan Hu//  // fsm
983ebdf758SXuan Hu//    switch (state) {
993ebdf758SXuan Hu//      is (s_idle) {
1003ebdf758SXuan Hu//        state := Mux(inHs, s_compute, s_idle)
1013ebdf758SXuan Hu//      }
1023ebdf758SXuan Hu//      is (s_compute) {
1033ebdf758SXuan Hu//        state := Mux(outValid, Mux(outFire, s_idle, s_finish),
1043ebdf758SXuan Hu//                              s_compute)
1053ebdf758SXuan Hu//      }
1063ebdf758SXuan Hu//      is (s_finish) {
1073ebdf758SXuan Hu//        state := Mux(io.out.fire(), s_idle, s_finish)
1083ebdf758SXuan Hu//      }
1093ebdf758SXuan Hu//    }
1103ebdf758SXuan Hu//
1113ebdf758SXuan Hu//  // connect
1123ebdf758SXuan Hu//    dataWire := Mux1H(s0_selectReg, dataModule.map(_.io.out.bits.data))
1133ebdf758SXuan Hu//    dataModule.zipWithIndex.foreach{ case(l, i) =>
1143ebdf758SXuan Hu//      l.io.in.bits <> io.in.bits
1153ebdf758SXuan Hu//      l.io.redirectIn := DontCare
1163ebdf758SXuan Hu//      l.rm := rm
1173ebdf758SXuan Hu//      l.vxrm := vxrm
1183ebdf758SXuan Hu//      l.vstart := vstart
1193ebdf758SXuan Hu//      l.io.in.valid := io.in.valid && state === s_idle && select(i)
1203ebdf758SXuan Hu//      l.io.out.ready := io.out.ready
1213ebdf758SXuan Hu//    }
1223ebdf758SXuan Hu//    vxsat := Mux1H(s0_selectReg, dataModule.map(_.vxsat))
1233ebdf758SXuan Hu//    fflags := Mux1H(s0_selectReg, dataModule.map(_.fflags))
1243ebdf758SXuan Hu//
1253ebdf758SXuan Hu//    io.out.bits.data :=  Mux(state === s_compute && outFire, dataWire, dataReg)
1263ebdf758SXuan Hu//    io.out.bits.uop := s0_uopReg
1273ebdf758SXuan Hu//    io.out.valid := state === s_compute && outValid || state === s_finish
1283ebdf758SXuan Hu//    io.in.ready := state === s_idle
1293ebdf758SXuan Hu//  }
1303ebdf758SXuan Hu//}
1313ebdf758SXuan Hu//
1323ebdf758SXuan Hu//
1333ebdf758SXuan Hu//object VecImmExtractor {
1343ebdf758SXuan Hu//  def Imm_OPIVIS(imm: UInt): UInt = {
1353ebdf758SXuan Hu//    SignExt(imm(4,0), 8)
1363ebdf758SXuan Hu//  }
1373ebdf758SXuan Hu//  def Imm_OPIVIU(imm: UInt): UInt = {
1383ebdf758SXuan Hu//    ZeroExt(imm(4,0), 8)
1393ebdf758SXuan Hu//  }
1403ebdf758SXuan Hu//
1413ebdf758SXuan Hu//  def imm_sew(sew: UInt, imm: UInt): UInt = {
1423ebdf758SXuan Hu//    val _imm = SignExt(imm(7,0), 64)
1433ebdf758SXuan Hu//    LookupTree(sew(1,0), List(
1443ebdf758SXuan Hu//      "b00".U -> VecInit(Seq.fill(8)(_imm(7,0))).asUInt,
1453ebdf758SXuan Hu//      "b01".U -> VecInit(Seq.fill(4)(_imm(15,0))).asUInt,
1463ebdf758SXuan Hu//      "b10".U -> VecInit(Seq.fill(2)(_imm(31,0))).asUInt,
1473ebdf758SXuan Hu//      "b11".U -> _imm(63,0),
1483ebdf758SXuan Hu//    ))
1493ebdf758SXuan Hu//  }
1503ebdf758SXuan Hu//
1513ebdf758SXuan Hu//  def apply(immType: UInt, sew: UInt, imm: UInt): UInt = {
1523ebdf758SXuan Hu//    val _imm = Mux(immType === SelImm.IMM_OPIVIS, Imm_OPIVIS(imm), Imm_OPIVIU(imm))
1533ebdf758SXuan Hu//    imm_sew(sew, _imm(7,0))
1543ebdf758SXuan Hu//  }
1553ebdf758SXuan Hu//}
1563ebdf758SXuan Hu//
1573ebdf758SXuan Hu//object VecExtractor{
1583ebdf758SXuan Hu//  def xf2v_sew(sew: UInt, xf:UInt): UInt = {
1593ebdf758SXuan Hu//    LookupTree(sew(1, 0), List(
1603ebdf758SXuan Hu//      "b00".U -> VecInit(Seq.fill(16)(xf(7, 0))).asUInt,
1613ebdf758SXuan Hu//      "b01".U -> VecInit(Seq.fill(8)(xf(15, 0))).asUInt,
1623ebdf758SXuan Hu//      "b10".U -> VecInit(Seq.fill(4)(xf(31, 0))).asUInt,
1633ebdf758SXuan Hu//      "b11".U -> VecInit(Seq.fill(2)(xf(63, 0))).asUInt,
1643ebdf758SXuan Hu//    ))
1653ebdf758SXuan Hu//  }
1663ebdf758SXuan Hu//
1673ebdf758SXuan Hu//  def apply(sew: UInt, xf: UInt): UInt = {
1683ebdf758SXuan Hu//    xf2v_sew(sew, xf)
1693ebdf758SXuan Hu//  }
1703ebdf758SXuan Hu//}