xref: /XiangShan/src/main/scala/xiangshan/backend/issue/MultiWakeupQueue.scala (revision ec1fea84521e1ee8ec105e86782db0361564eed4)
1package xiangshan.backend.issue
2
3import chisel3._
4import chisel3.util._
5import utils.PipeWithFlush
6import xiangshan.backend.Bundles.{ExuInput, connectSamePort}
7import xiangshan.backend.exu.ExeUnitParams
8
9class MultiWakeupQueueIO[T <: Bundle, 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 deq = Output(Valid(lastGen))
23}
24
25class MultiWakeupQueue[T <: Bundle, TFlush <: Data](
26  val gen       : T,
27  val lastGen   : T,
28  val flushGen  : TFlush,
29  val latencySet: Set[Int],
30  flushFunc : (T, TFlush, Int) => Bool,
31  modificationFunc: T => T = { x: T => x },
32  lastConnectFunc: (T, T) => T,
33) extends Module {
34  require(latencySet.min >= 0)
35
36  val io = IO(new MultiWakeupQueueIO(gen, lastGen, flushGen, log2Up(latencySet.max) + 1))
37
38  val pipes = latencySet.map(x => Module(new PipeWithFlush[T, TFlush](gen, flushGen, x, flushFunc, modificationFunc))).toSeq
39
40  val pipesOut = Wire(Valid(gen))
41  val lastConnect = Reg(Valid(lastGen))
42
43  pipes.zip(latencySet).foreach {
44    case (pipe, lat) =>
45      pipe.io.flush := io.flush
46      pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === lat.U
47      pipe.io.enq.bits := io.enq.bits.uop
48  }
49
50  private val pipesValidVec = VecInit(pipes.map(_.io.deq).zip(latencySet).map(_ match {
51    case (deq, i) => deq.valid && !flushFunc(deq.bits, io.flush, i)
52  }))
53  private val pipesBitsVec = VecInit(pipes.map(_.io.deq.bits)).map(modificationFunc)
54
55  pipesOut.valid := pipesValidVec.asUInt.orR
56  pipesOut.bits := Mux1H(pipesValidVec, pipesBitsVec)
57
58  lastConnect.valid := pipesOut.valid
59  lastConnect.bits := lastConnectFunc(pipesOut.bits, lastConnect.bits)
60
61  io.deq.valid := lastConnect.valid
62  io.deq.bits := lastConnect.bits
63
64  assert(PopCount(pipesValidVec) <= 1.U, "PopCount(pipesValidVec) should be no more than 1")
65}
66