xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/VIAluFix.scala (revision 9eaaa75dcad8a8d34b2382c2c1fc06046f339895)
1package xiangshan.backend.fu.wrapper
2
3import chipsalliance.rocketchip.config.Parameters
4import chisel3._
5import chisel3.util._
6import utils.XSError
7import xiangshan.XSCoreParamsKey
8import xiangshan.backend.fu.vector.Bundles.{VConfig, VSew}
9import xiangshan.backend.fu.vector.{VecPipedFuncUnit}
10import xiangshan.backend.fu.vector.Utils.VecDataToMaskDataVec
11import xiangshan.backend.fu.{FuConfig, FuType}
12import yunsuan.{OpType, VialuFixType}
13import yunsuan.vector.alu.VIntFixpAlu
14import yunsuan.encoding.{VdType, Vs1IntType, Vs2IntType}
15import yunsuan.encoding.Opcode.VialuOpcode
16
17class VIAluSrcTypeIO extends Bundle {
18  val in = Input(new Bundle {
19    val fuOpType  : UInt = OpType()
20    val vsew      : UInt = VSew()
21    val isReverse : Bool = Bool() // vrsub, vrdiv
22    val isExt     : Bool = Bool()
23    val isDstMask : Bool = Bool() // vvm, vvvm, mmm
24    val isMove    : Bool = Bool() // vmv.s.x, vmv.v.v, vmv.v.x, vmv.v.i
25  })
26  val out = Output(new Bundle {
27    val vs1Type : UInt = Vs1IntType()
28    val vs2Type : UInt = Vs2IntType()
29    val vdType  : UInt = VdType()
30    val illegal : Bool = Bool()
31  })
32}
33
34class VIAluSrcTypeModule extends Module {
35  val io: VIAluSrcTypeIO = IO(new VIAluSrcTypeIO)
36
37  private val vsew = io.in.vsew
38  private val isExt = io.in.isExt
39  private val isDstMask = io.in.isDstMask
40
41  private val opcode = VialuFixType.getOpcode(io.in.fuOpType)
42  private val isSign = VialuFixType.isSigned(io.in.fuOpType)
43  private val format = VialuFixType.getFormat(io.in.fuOpType)
44
45  private val vsewX2 = vsew + 1.U
46  private val vsewF2 = vsew - 1.U
47  private val vsewF4 = vsew - 2.U
48  private val vsewF8 = vsew - 3.U
49
50  private val isAddSub = opcode === VialuOpcode.vadd || opcode === VialuOpcode.vsub
51  private val isShiftRight = Seq(VialuOpcode.vsrl, VialuOpcode.vsra, VialuOpcode.vssrl, VialuOpcode.vssra).map(fmt => fmt === format).reduce(_ || _)
52  private val isVext = opcode === VialuOpcode.vext
53
54  private val isWiden = isAddSub && Seq(VialuFixType.FMT.VVW, VialuFixType.FMT.WVW).map(fmt => fmt === format).reduce(_ || _)
55  private val isNarrow = isShiftRight && format === VialuFixType.FMT.WVV
56  private val isVextF2 = isVext && format === VialuFixType.FMT.VF2
57  private val isVextF4 = isVext && format === VialuFixType.FMT.VF4
58  private val isVextF8 = isVext && format === VialuFixType.FMT.VF8
59
60  // check illegal
61  private val widenIllegal  = isWiden   && vsewX2 === VSew.e8
62  private val narrowIllegal = isNarrow  && vsewF2 === VSew.e64
63  private val vextIllegal   = (isVextF2 && (vsewF2 === VSew.e64)) ||
64    (isVextF4 && (vsewF4 === VSew.e64)) ||
65    (isVextF8 && (vsewF8 === VSew.e64))
66  // Todo: use it
67  private val illegal = widenIllegal || narrowIllegal || vextIllegal
68
69  private val intType = Cat(0.U(1.W), isSign)
70
71  private class Vs2Vs1VdSew extends Bundle {
72    val vs2 = VSew()
73    val vs1 = VSew()
74    val vd = VSew()
75  }
76
77  private class Vs2Vs1VdType extends Bundle {
78    val vs2 = Vs2IntType()
79    val vs1 = Vs1IntType()
80    val vd  = VdType()
81  }
82
83  private val addSubSews = Mux1H(Seq(
84    (format === VialuFixType.FMT.VVV) -> Cat(vsew  ,  vsew, vsew  ),
85    (format === VialuFixType.FMT.VVW) -> Cat(vsew  ,  vsew, vsewX2),
86    (format === VialuFixType.FMT.WVW) -> Cat(vsewX2,  vsew, vsewX2),
87    (format === VialuFixType.FMT.WVV) -> Cat(vsewX2,  vsew, vsew  ),
88  )).asTypeOf(new Vs2Vs1VdSew)
89
90  private val vextSews = Mux1H(Seq(
91    (format === VialuFixType.FMT.VF2) -> Cat(vsewF2, vsewF2, vsew),
92    (format === VialuFixType.FMT.VF4) -> Cat(vsewF4, vsewF4, vsew),
93    (format === VialuFixType.FMT.VF8) -> Cat(vsewF8, vsewF8, vsew),
94  )).asTypeOf(new Vs2Vs1VdSew)
95
96  private val maskTypes = Mux1H(Seq(
97    (format === VialuFixType.FMT.VVM) -> Cat(Cat(intType, vsew),  Cat(intType, vsew), VdType.mask),
98    (format === VialuFixType.FMT.VVMM)-> Cat(Cat(intType, vsew),  Cat(intType, vsew), VdType.mask),
99    (format === VialuFixType.FMT.MMM) -> Cat(Vs2IntType.mask,     Vs1IntType.mask,    VdType.mask),
100  )).asTypeOf(new Vs2Vs1VdType)
101
102  private val vs2Type = Mux1H(Seq(
103    isDstMask               -> maskTypes.vs2,
104    isExt                   -> Cat(intType, vextSews.vs2),
105    (!isExt && !isDstMask)  -> Cat(intType, addSubSews.vs2),
106  ))
107  private val vs1Type = Mux1H(Seq(
108    isDstMask               -> maskTypes.vs1,
109    isExt                   -> Cat(intType, vextSews.vs1),
110    (!isExt && !isDstMask)  -> Cat(intType, addSubSews.vs1),
111  ))
112  private val vdType = Mux1H(Seq(
113    isDstMask               -> maskTypes.vd,
114    isExt                   -> Cat(intType, vextSews.vd),
115    (!isExt && !isDstMask)  -> Cat(intType, addSubSews.vd),
116  ))
117
118  io.out.vs2Type := vs2Type
119  io.out.vs1Type := vs1Type
120  io.out.vdType := vdType
121  io.out.illegal := illegal
122}
123
124class VIAluFix(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) {
125  XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VialuFixType.dummy, "VialuF OpType not supported")
126
127  // modules
128
129  private val typeModule = Module(new VIAluSrcTypeModule)
130  private val vIntFixpAlu = Module(new VIntFixpAlu)
131
132  val maskDataVec: Vec[UInt] = VecDataToMaskDataVec(srcMask, vsew)
133  val maskIdx = Mux(isNarrow, (vuopIdx >> 1.U).asUInt, vuopIdx)
134  val maskUsed = maskDataVec(maskIdx)
135
136  val vconfig = srcVConfig
137  val vl = vconfig.vl
138
139
140  /**
141    * [[typeModule]]'s io connection
142    */
143  typeModule.io.in.fuOpType := fuOpType
144  typeModule.io.in.vsew := vsew
145  typeModule.io.in.isReverse := isReverse
146  typeModule.io.in.isExt := isExt
147  typeModule.io.in.isDstMask := vecCtrl.isDstMask
148  typeModule.io.in.isMove := isMove
149
150  /**
151    * [[vIntFixpAlu]]'s io connection
152    */
153  vIntFixpAlu.io match {
154    case subIO =>
155      subIO.in.opcode       := VialuFixType.getOpcode(inCtrl.fuOpType).asTypeOf(subIO.in.opcode)
156      subIO.in.info.vm      := vm
157      subIO.in.info.ma      := vma
158      subIO.in.info.ta      := vta
159      subIO.in.info.vlmul   := vlmul
160      subIO.in.info.vl      := srcVConfig.vl
161      subIO.in.info.vstart  := vstart
162      subIO.in.info.uopIdx  := vuopIdx
163      subIO.in.info.vxrm    := vxrm
164      subIO.in.srcType(0)   := typeModule.io.out.vs2Type
165      subIO.in.srcType(1)   := typeModule.io.out.vs1Type
166      subIO.in.vdType       := typeModule.io.out.vdType
167      subIO.in.vs2          := vs2
168      subIO.in.vs1          := vs1
169      subIO.in.old_vd       := old_vd
170      subIO.in.mask16b      := maskUsed // Todo: make mask16b more flexiable
171      subIO.ctrl.narrow     := isNarrow
172      subIO.ctrl.vstart_gte_vl := vstart >= vl
173  }
174
175  io.out.bits.res.data := vIntFixpAlu.io.out.vd
176  io.out.bits.res.vxsat.foreach(_ := vIntFixpAlu.io.out.vxsat)
177}
178