xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Multiplier.scala (revision a9ecfa67572f9dc8d32a66b8924cfc8e21bbda0c)
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 MulDivOutput extends XSBundle {
17  val data = UInt(XLEN.W)
18  val uop = new MicroOp
19}
20
21class MulDivIO(val len: Int) extends XSBundle {
22  val in = Flipped(DecoupledIO(new Bundle() {
23    val src1, src2 = UInt(len.W)
24    val ctrl = new MulDivCtrl
25  }))
26  val out = DecoupledIO(new MulDivOutput)
27  val redirect = Flipped(ValidIO(new Redirect))
28}
29
30abstract class Multiplier
31(
32  val len: Int,
33  latency: Int = 3
34) extends FunctionUnit(cfg = mulCfg, len, extIn = new MulDivCtrl, latency = latency)
35  with HasPipelineReg[MulDivCtrl, Null]
36{
37
38  val (src1, src2) = (io.in.bits.src(0), io.in.bits.src(1))
39}
40
41class ArrayMultiplier
42(
43  len: Int,
44  latency: Int = 3,
45  realArray: Boolean = false
46) extends Multiplier(len, latency) {
47
48  val mulRes = src1.asSInt() * src2.asSInt()
49
50  var dataVec = Seq(mulRes.asUInt())
51  var ctrlVec = Seq(io.in.bits.ext.get)
52
53  for(i <- 1 to latency){
54    dataVec = dataVec :+ PipelineReg(i)(dataVec(i-1))
55    ctrlVec = ctrlVec :+ PipelineReg(i)(ctrlVec(i-1))
56  }
57
58  val xlen = io.out.bits.data.getWidth
59  val res = Mux(ctrlVec.last.isHi, dataVec.last(2*xlen-1, xlen), dataVec.last(xlen-1,0))
60  io.out.bits.data := Mux(ctrlVec.last.isW, SignExt(res(31,0),xlen), res)
61
62  XSDebug(p"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n")(this.name)
63
64  //  printf(p"t=${GTimer()} in: v${io.in.valid} r:${io.in.ready}\n")
65  //  printf(p"t=${GTimer()} out: v:${io.out.valid} r:${io.out.ready} vec:${Binary(Cat(validVec))}\n")
66}