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) extends Module { 30 require(latencySet.min >= 0) 31 32 val io = IO(new MultiWakeupQueueIO(gen, flushGen, log2Up(latencySet.max) + 1)) 33 34 val pipes = latencySet.map(x => Module(new PipeWithFlush[T, TFlush](gen, flushGen, x, flushFunc))).toSeq 35 36 pipes.zip(latencySet).foreach { 37 case (pipe, lat) => 38 pipe.io.flush := io.flush 39 pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === lat.U 40 pipe.io.enq.bits := io.enq.bits.uop 41 } 42 43 private val pipesValidVec = VecInit(pipes.map(_.io.deq.valid).zip(latencySet).map(_ match { 44 case (valid, 1) => valid && !io.og0IssueFail 45 case (valid, 2) => valid && !io.og1IssueFail 46 case (valid, _) => valid 47 })) 48 private val pipesBitsVec = VecInit(pipes.map(_.io.deq.bits)) 49 50 io.deq.valid := pipesValidVec.asUInt.orR 51 io.deq.bits := Mux1H(pipesValidVec, pipesBitsVec) 52 53 assert(PopCount(pipesValidVec) <= 1.U, "PopCount(pipesValidVec) should be no more than 1") 54} 55