package xiangshan.backend.issue import chisel3._ import chisel3.util._ import utils.PipeWithFlush import xiangshan.backend.Bundles.ExuInput import xiangshan.backend.exu.ExeUnitParams class MultiWakeupQueueIO[T <: Data, TFlush <: Data]( gen : T, lastGen : T, flushGen : TFlush, latWidth : Int, ) extends Bundle { class EnqBundle extends Bundle { val uop = Output(gen) val lat = Output(UInt(latWidth.W)) } val flush = Input(flushGen) val enq = Flipped(Valid(new EnqBundle)) val og0IssueFail = Input(Bool()) val og1IssueFail = Input(Bool()) val deq = Output(Valid(lastGen)) } class MultiWakeupQueue[T <: Data, TFlush <: Data]( val gen : T, val lastGen : T, val flushGen : TFlush, val latencySet: Set[Int], flushFunc : (T, TFlush, Int) => Bool, modificationFunc: (T, T) => T ) extends Module { require(latencySet.min >= 0) val io = IO(new MultiWakeupQueueIO(gen, lastGen, flushGen, log2Up(latencySet.max + 1) + 1)) val pipes = latencySet.map(x => Module(new PipeWithFlush[T, TFlush](gen, lastGen, flushGen, x + 1, flushFunc, modificationFunc))).toSeq pipes.zip(latencySet).foreach { case (pipe, lat) => pipe.io.flush := io.flush pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === lat.U pipe.io.enq.bits := io.enq.bits.uop } private val pipesValidVec = VecInit(pipes.map(_.io.deq.valid)) private val pipesBitsVec = VecInit(pipes.map(_.io.deq.bits)) io.deq.valid := pipesValidVec.asUInt.orR io.deq.bits := Mux1H(pipesValidVec, pipesBitsVec) assert(PopCount(pipesValidVec) <= 1.U, "PopCount(pipesValidVec) should be no more than 1") }