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