xref: /XiangShan/src/main/scala/xiangshan/backend/fu/wrapper/VIAluFix.scala (revision 39c388b5d08cc17a9f298e3f70fb444be19f51b0)
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.MMM) -> Cat(Vs2IntType.mask,     Vs1IntType.mask,    VdType.mask),
99  )).asTypeOf(new Vs2Vs1VdType)
100
101  private val vs2Type = Mux1H(Seq(
102    isDstMask               -> maskTypes.vs2,
103    isExt                   -> Cat(intType, vextSews.vs2),
104    (!isExt && !isDstMask)  -> Cat(intType, addSubSews.vs2),
105  ))
106  private val vs1Type = Mux1H(Seq(
107    isDstMask               -> maskTypes.vs1,
108    isExt                   -> Cat(intType, vextSews.vs1),
109    (!isExt && !isDstMask)  -> Cat(intType, addSubSews.vs1),
110  ))
111  private val vdType = Mux1H(Seq(
112    isDstMask               -> maskTypes.vd,
113    isExt                   -> Cat(intType, vextSews.vd),
114    (!isExt && !isDstMask)  -> Cat(intType, addSubSews.vd),
115  ))
116
117  io.out.vs2Type := vs2Type
118  io.out.vs1Type := vs1Type
119  io.out.vdType := vdType
120  io.out.illegal := illegal
121}
122
123class VIAluFix(cfg: FuConfig)(implicit p: Parameters) extends VecPipedFuncUnit(cfg) {
124  XSError(io.in.valid && io.in.bits.ctrl.fuOpType === VialuFixType.dummy, "VialuF OpType not supported")
125
126  // modules
127
128  private val typeModule = Module(new VIAluSrcTypeModule)
129  private val vIntFixpAlu = Module(new VIntFixpAlu)
130
131  val maskDataVec: Vec[UInt] = VecDataToMaskDataVec(srcMask, vsew)
132  val maskIdx = Mux(isNarrow, (vuopIdx >> 1.U).asUInt, vuopIdx)
133  val maskUsed = maskDataVec(maskIdx)
134
135  val vconfig = srcVConfig
136  val vl = vconfig.vl
137
138
139  /**
140    * [[typeModule]]'s io connection
141    */
142  typeModule.io.in.fuOpType := fuOpType
143  typeModule.io.in.vsew := vsew
144  typeModule.io.in.isReverse := isReverse
145  typeModule.io.in.isExt := isExt
146  typeModule.io.in.isDstMask := vecCtrl.isDstMask
147  typeModule.io.in.isMove := isMove
148
149  /**
150    * [[vIntFixpAlu]]'s io connection
151    */
152  vIntFixpAlu.io match {
153    case subIO =>
154      subIO.in.opcode       := VialuFixType.getOpcode(inCtrl.fuOpType).asTypeOf(subIO.in.opcode)
155      subIO.in.info.vm      := vm
156      subIO.in.info.ma      := vma
157      subIO.in.info.ta      := vta
158      subIO.in.info.vlmul   := vlmul
159      subIO.in.info.vl      := srcVConfig.vl
160      subIO.in.info.vstart  := vstart
161      subIO.in.info.uopIdx  := vuopIdx
162      subIO.in.info.vxrm    := vxrm
163      subIO.in.srcType(0)   := typeModule.io.out.vs2Type
164      subIO.in.srcType(1)   := typeModule.io.out.vs1Type
165      subIO.in.vdType       := typeModule.io.out.vdType
166      subIO.in.vs2          := vs2
167      subIO.in.vs1          := vs1
168      subIO.in.old_vd       := old_vd
169      subIO.in.mask16b      := maskUsed // Todo: make mask16b more flexiable
170      subIO.ctrl.narrow     := isNarrow
171      subIO.ctrl.vstart_gte_vl := vstart >= vl
172  }
173
174  io.out.bits.res.data := vIntFixpAlu.io.out.vd
175  io.out.bits.res.vxsat.foreach(_ := vIntFixpAlu.io.out.vxsat)
176}
177