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