xref: /XiangShan/src/main/scala/xiangshan/backend/fu/Multiplier.scala (revision b9fd18920ff32da90dcdccd2b29c490bab87f0eb)
1cafb3558SLinJiaweipackage xiangshan.backend.fu
2cafb3558SLinJiawei
3cafb3558SLinJiaweiimport chisel3._
4cafb3558SLinJiaweiimport chisel3.util._
5cafb3558SLinJiaweiimport xiangshan._
6*b9fd1892SLinJiaweiimport utils._
7cafb3558SLinJiaweiimport xiangshan.backend._
8cafb3558SLinJiaweiimport xiangshan.backend.fu.FunctionUnit._
9cafb3558SLinJiawei
10cafb3558SLinJiaweiclass MulDivCtrl extends Bundle{
11cafb3558SLinJiawei  val uop = new MicroOp
12cafb3558SLinJiawei  val sign = Bool()
13cafb3558SLinJiawei  val isW = Bool()
14cafb3558SLinJiawei  val isHi = Bool() // return hi bits of result ?
15cafb3558SLinJiawei}
16cafb3558SLinJiawei
17cafb3558SLinJiaweiclass MulDivOutput extends XSBundle {
18cafb3558SLinJiawei  val data = UInt(XLEN.W)
19cafb3558SLinJiawei  val uop = new MicroOp
20cafb3558SLinJiawei}
21cafb3558SLinJiawei
22cafb3558SLinJiaweiclass MulDivIO(val len: Int) extends XSBundle {
23cafb3558SLinJiawei  val in = Flipped(DecoupledIO(new Bundle() {
24cafb3558SLinJiawei    val src1, src2 = UInt(len.W)
25cafb3558SLinJiawei    val ctrl = new MulDivCtrl
26cafb3558SLinJiawei  }))
27cafb3558SLinJiawei  val out = DecoupledIO(new MulDivOutput)
28cafb3558SLinJiawei  val redirect = Flipped(ValidIO(new Redirect))
29cafb3558SLinJiawei}
30cafb3558SLinJiawei
31cafb3558SLinJiaweiabstract class Multiplier
32cafb3558SLinJiawei(
33cafb3558SLinJiawei  val len: Int,
34cafb3558SLinJiawei  val latency: Int = 3
35cafb3558SLinJiawei) extends FunctionUnit(mulCfg) {
36cafb3558SLinJiawei  val io = IO(new MulDivIO(len))
37cafb3558SLinJiawei}
38cafb3558SLinJiawei
39cafb3558SLinJiaweitrait HasPipelineReg { this: ArrayMultiplier =>
40cafb3558SLinJiawei
41cafb3558SLinJiawei  val validVec = io.in.valid +: Array.fill(latency)(RegInit(false.B))
42cafb3558SLinJiawei  val rdyVec = Array.fill(latency)(Wire(Bool())) :+ io.out.ready
43cafb3558SLinJiawei  val ctrlVec = io.in.bits.ctrl +: Array.fill(latency)(Reg(new MulDivCtrl))
44cafb3558SLinJiawei  val flushVec = ctrlVec.zip(validVec).map(x => x._2 && x._1.uop.brTag.needFlush(io.redirect))
45cafb3558SLinJiawei
46cafb3558SLinJiawei  for(i <- 0 until latency){
47cafb3558SLinJiawei    rdyVec(i) := !validVec(i+1) || rdyVec(i+1)
48cafb3558SLinJiawei  }
49cafb3558SLinJiawei
50cafb3558SLinJiawei  for(i <- 1 to latency){
51cafb3558SLinJiawei    when(flushVec(i) || rdyVec(i) && !validVec(i-1)){
52cafb3558SLinJiawei      validVec(i) := false.B
53cafb3558SLinJiawei    }.elsewhen(rdyVec(i-1) && validVec(i-1) && !flushVec(i-1)){
54cafb3558SLinJiawei      validVec(i) := validVec(i-1)
55cafb3558SLinJiawei      ctrlVec(i) := ctrlVec(i-1)
56cafb3558SLinJiawei    }
57cafb3558SLinJiawei  }
58cafb3558SLinJiawei
59cafb3558SLinJiawei  io.in.ready := rdyVec(0)
60cafb3558SLinJiawei  io.out.valid := validVec.last && !flushVec.last
61cafb3558SLinJiawei  io.out.bits.uop := ctrlVec.last.uop
62cafb3558SLinJiawei
63cafb3558SLinJiawei  def PipelineReg[T<:Data](i: Int)(next: T) = RegEnable(
64cafb3558SLinJiawei    next,
65cafb3558SLinJiawei    enable = validVec(i-1) && rdyVec(i-1) && !flushVec(i-1)
66cafb3558SLinJiawei  )
67cafb3558SLinJiawei
68cafb3558SLinJiawei  def S1Reg[T<:Data](next: T):T = PipelineReg[T](1)(next)
69cafb3558SLinJiawei  def S2Reg[T<:Data](next: T):T = PipelineReg[T](2)(next)
70cafb3558SLinJiawei  def S3Reg[T<:Data](next: T):T = PipelineReg[T](3)(next)
71cafb3558SLinJiawei  def S4Reg[T<:Data](next: T):T = PipelineReg[T](4)(next)
72cafb3558SLinJiawei  def S5Reg[T<:Data](next: T):T = PipelineReg[T](5)(next)
73cafb3558SLinJiawei}
74cafb3558SLinJiawei
75cafb3558SLinJiaweiclass ArrayMultiplier
76cafb3558SLinJiawei(
77cafb3558SLinJiawei  len: Int,
78cafb3558SLinJiawei  latency: Int = 3,
79cafb3558SLinJiawei  realArray: Boolean = false
80cafb3558SLinJiawei) extends Multiplier(len, latency) with HasPipelineReg {
81cafb3558SLinJiawei
82cafb3558SLinJiawei  val mulRes = io.in.bits.src1.asSInt() * io.in.bits.src2.asSInt()
83cafb3558SLinJiawei
84cafb3558SLinJiawei  var dataVec = Seq(mulRes.asUInt())
85cafb3558SLinJiawei
86cafb3558SLinJiawei  for(i <- 1 to latency){
87cafb3558SLinJiawei    dataVec = dataVec :+ PipelineReg(i)(dataVec(i-1))
88cafb3558SLinJiawei  }
89cafb3558SLinJiawei
90cafb3558SLinJiawei  val xlen = io.out.bits.data.getWidth
91cafb3558SLinJiawei  val res = Mux(ctrlVec.last.isHi, dataVec.last(2*xlen-1, xlen), dataVec.last(xlen-1,0))
92cafb3558SLinJiawei  io.out.bits.data := Mux(ctrlVec.last.isW, SignExt(res(31,0),xlen), res)
93cafb3558SLinJiawei
94cafb3558SLinJiawei  XSDebug(p"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n")(this.name)
95cafb3558SLinJiawei
96cafb3558SLinJiawei  //  printf(p"t=${GTimer()} in: v${io.in.valid} r:${io.in.ready}\n")
97cafb3558SLinJiawei  //  printf(p"t=${GTimer()} out: v:${io.out.valid} r:${io.out.ready} vec:${Binary(Cat(validVec))}\n")
98cafb3558SLinJiawei}