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