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 = Flipped(flushGen) 18 val enq = Flipped(Valid(new EnqBundle)) 19 val deq = Output(Valid(gen)) 20} 21 22class MultiWakeupQueue[T <: Data, TFlush <: Data]( 23 val gen : T, 24 val flushGen : TFlush, 25 val latencySet: Set[Int], 26 flushFunc : (T, TFlush) => Bool, 27) extends Module { 28 require(latencySet.min >= 0) 29 30 val io = IO(new MultiWakeupQueueIO(gen, flushGen, log2Up(latencySet.max) + 1)) 31 32 val pipes = latencySet.map(x => Module(new PipeWithFlush[T, TFlush](gen, flushGen, x, flushFunc))).toSeq 33 34 pipes.zipWithIndex.foreach { 35 case (pipe, i) => 36 pipe.io.flush := io.flush 37 pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === i.U 38 pipe.io.enq.bits := io.enq.bits.uop 39 } 40 41 private val pipesValidVec = VecInit(pipes.map(_.io.deq.valid)) 42 private val pipesBitsVec = VecInit(pipes.map(_.io.deq.bits)) 43 44 io.deq.valid := pipesValidVec.asUInt.orR 45 io.deq.bits := Mux1H(pipesValidVec, pipesBitsVec) 46 47 assert(PopCount(pipesValidVec) <= 1.U, "PopCount(pipesValidVec) should be no more than 1") 48} 49