xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Multiplier.scala (revision e18c367f538130ef8e8c577e982d5e20161011b1)
1package xiangshan.backend.fu
2
3import chisel3._
4import chisel3.util._
5import xiangshan._
6import utils._
7import xiangshan.backend._
8import xiangshan.backend.fu.FunctionUnit._
9
10class MulDivCtrl extends Bundle{
11  val sign = Bool()
12  val isW = Bool()
13  val isHi = Bool() // return hi bits of result ?
14}
15
16class ArrayMultiplier(len: Int, latency: Int = 3)
17  extends FunctionUnit(
18    FuConfig(FuType.mul, 2, 0, writeIntRf = true, writeFpRf = false, hasRedirect = false, CertainLatency(latency)),
19    len
20  )
21  with HasPipelineReg
22{
23  val ctrl = IO(Input(new MulDivCtrl))
24
25  val (src1, src2) = (io.in.bits.src(0), io.in.bits.src(1))
26
27  val mulRes = src1.asSInt() * src2.asSInt()
28
29  var dataVec = Seq(mulRes.asUInt())
30  var ctrlVec = Seq(ctrl)
31
32  for(i <- 1 to latency){
33    dataVec = dataVec :+ PipelineReg(i)(dataVec(i-1))
34    ctrlVec = ctrlVec :+ PipelineReg(i)(ctrlVec(i-1))
35  }
36
37  val xlen = io.out.bits.data.getWidth
38  val res = Mux(ctrlVec.last.isHi, dataVec.last(2*xlen-1, xlen), dataVec.last(xlen-1,0))
39  io.out.bits.data := Mux(ctrlVec.last.isW, SignExt(res(31,0),xlen), res)
40
41  XSDebug(p"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n")
42}