xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Multiplier.scala (revision 3136ee6a0600eb77c23effda5389fe3f858a813c)
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, 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
41//trait HasPipelineReg { this: ArrayMultiplier =>
42//
43//  val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B))
44//  val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready
45//  val ctrlVec = io.in.bits.ctrl +: Array.fill(latency)(Reg(new MulDivCtrl))
46//  val flushVec = ctrlVec.zip(validVec).map(x => x._2 && x._1.uop.needFlush(io.redirect))
47//
48//  for(i <- 0 until latency){
49//    rdyVec(i) := !validVec(i+1) || rdyVec(i+1)
50//  }
51//
52//  for(i <- 1 to latency){
53//    when(flushVec(i-1) || rdyVec(i) && !validVec(i-1)){
54//      validVec(i) := false.B
55//    }.elsewhen(rdyVec(i-1) && validVec(i-1) && !flushVec(i-1)){
56//      validVec(i) := validVec(i-1)
57//      ctrlVec(i) := ctrlVec(i-1)
58//    }
59//  }
60//
61//  io.in.ready := rdyVec(0)
62//  io.out.valid := validVec.last && !flushVec.last
63//  io.out.bits.uop := ctrlVec.last.uop
64//
65//  def PipelineReg[T<:Data](i: Int)(next: T) = RegEnable(
66//    next,
67//    enable = validVec(i-1) && rdyVec(i-1) && !flushVec(i-1)
68//  )
69//
70//  def S1Reg[T<:Data](next: T):T = PipelineReg[T](1)(next)
71//  def S2Reg[T<:Data](next: T):T = PipelineReg[T](2)(next)
72//  def S3Reg[T<:Data](next: T):T = PipelineReg[T](3)(next)
73//  def S4Reg[T<:Data](next: T):T = PipelineReg[T](4)(next)
74//  def S5Reg[T<:Data](next: T):T = PipelineReg[T](5)(next)
75//}
76
77class ArrayMultiplier
78(
79  len: Int,
80  latency: Int = 3,
81  realArray: Boolean = false
82) extends Multiplier(len, latency) {
83
84  val mulRes = src1.asSInt() * src2.asSInt()
85
86  var dataVec = Seq(mulRes.asUInt())
87  var ctrlVec = Seq(io.in.bits.ext.get)
88
89  for(i <- 1 to latency){
90    dataVec = dataVec :+ PipelineReg(i)(dataVec(i-1))
91    ctrlVec = ctrlVec :+ PipelineReg(i)(ctrlVec(i-1))
92  }
93
94  val xlen = io.out.bits.data.getWidth
95  val res = Mux(ctrlVec.last.isHi, dataVec.last(2*xlen-1, xlen), dataVec.last(xlen-1,0))
96  io.out.bits.data := Mux(ctrlVec.last.isW, SignExt(res(31,0),xlen), res)
97
98  XSDebug(p"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n")(this.name)
99
100  //  printf(p"t=${GTimer()} in: v${io.in.valid} r:${io.in.ready}\n")
101  //  printf(p"t=${GTimer()} out: v:${io.out.valid} r:${io.out.ready} vec:${Binary(Cat(validVec))}\n")
102}