xref: /XiangShan/src/main/scala/xiangshan/backend/issue/MultiWakeupQueue.scala (revision 25bcff47f9bc19c872a1647b16fdfefdd4bae3f5)
1*25bcff47SXuan Hupackage xiangshan.backend.issue
2*25bcff47SXuan Hu
3*25bcff47SXuan Huimport chisel3._
4*25bcff47SXuan Huimport chisel3.util._
5*25bcff47SXuan Huimport utils.PipeWithFlush
6*25bcff47SXuan Hu
7*25bcff47SXuan Huclass MultiWakeupQueueIO[T <: Data, TFlush <: Data](
8*25bcff47SXuan Hu  gen       : T,
9*25bcff47SXuan Hu  flushGen  : TFlush,
10*25bcff47SXuan Hu  latWidth  : Int,
11*25bcff47SXuan Hu) extends Bundle {
12*25bcff47SXuan Hu  class EnqBundle extends Bundle {
13*25bcff47SXuan Hu    val uop = Output(gen)
14*25bcff47SXuan Hu    val lat = Output(UInt(latWidth.W))
15*25bcff47SXuan Hu  }
16*25bcff47SXuan Hu
17*25bcff47SXuan Hu  val flush = Flipped(flushGen)
18*25bcff47SXuan Hu  val enq = Flipped(Valid(new EnqBundle))
19*25bcff47SXuan Hu  val deq = Output(Valid(gen))
20*25bcff47SXuan Hu}
21*25bcff47SXuan Hu
22*25bcff47SXuan Huclass MultiWakeupQueue[T <: Data, TFlush <: Data](
23*25bcff47SXuan Hu  val gen       : T,
24*25bcff47SXuan Hu  val flushGen  : TFlush,
25*25bcff47SXuan Hu  val latencySet: Set[Int],
26*25bcff47SXuan Hu  flushFunc : (T, TFlush) => Bool,
27*25bcff47SXuan Hu) extends Module {
28*25bcff47SXuan Hu  require(latencySet.min >= 0)
29*25bcff47SXuan Hu
30*25bcff47SXuan Hu  val io = IO(new MultiWakeupQueueIO(gen, flushGen, log2Up(latencySet.max)))
31*25bcff47SXuan Hu
32*25bcff47SXuan Hu  val pipes = latencySet.map(x => Module(new PipeWithFlush[T, TFlush](gen, flushGen, x, flushFunc))).toSeq
33*25bcff47SXuan Hu
34*25bcff47SXuan Hu  pipes.zipWithIndex.foreach {
35*25bcff47SXuan Hu    case (pipe, i) =>
36*25bcff47SXuan Hu      pipe.io.flush := io.flush
37*25bcff47SXuan Hu      pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === i.U
38*25bcff47SXuan Hu      pipe.io.enq.bits := io.enq.bits.uop
39*25bcff47SXuan Hu  }
40*25bcff47SXuan Hu
41*25bcff47SXuan Hu  private val pipesValidVec = VecInit(pipes.map(_.io.deq.valid))
42*25bcff47SXuan Hu  private val pipesBitsVec = VecInit(pipes.map(_.io.deq.bits))
43*25bcff47SXuan Hu
44*25bcff47SXuan Hu  io.deq.valid := pipesValidVec.asUInt.orR
45*25bcff47SXuan Hu  io.deq.bits := Mux1H(pipesValidVec, pipesBitsVec)
46*25bcff47SXuan Hu
47*25bcff47SXuan Hu  assert(PopCount(pipesValidVec) > 1.U, "PopCount(pipesValidVec) should be no more than 1")
48*25bcff47SXuan Hu}
49