1package xiangshan.backend.issue 2 3import chisel3._ 4import chisel3.util._ 5import utils.PipeWithFlush 6import xiangshan.backend.Bundles.ExuInput 7import xiangshan.backend.exu.ExeUnitParams 8 9class MultiWakeupQueueIO[T <: Data, 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 og0IssueFail = Input(Bool()) 23 val og1IssueFail = Input(Bool()) 24 val deq = Output(Valid(lastGen)) 25} 26 27class MultiWakeupQueue[T <: Data, TFlush <: Data]( 28 val gen : T, 29 val lastGen : T, 30 val flushGen : TFlush, 31 val latencySet: Set[Int], 32 flushFunc : (T, TFlush, Int) => Bool, 33 modificationFunc: (T, T) => T 34) extends Module { 35 require(latencySet.min >= 0) 36 37 val io = IO(new MultiWakeupQueueIO(gen, lastGen, flushGen, log2Up(latencySet.max + 1) + 1)) 38 39 val pipes = latencySet.map(x => Module(new PipeWithFlush[T, TFlush](gen, lastGen, flushGen, x + 1, flushFunc, modificationFunc))).toSeq 40 41 pipes.zip(latencySet).foreach { 42 case (pipe, lat) => 43 pipe.io.flush := io.flush 44 pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === lat.U 45 pipe.io.enq.bits := io.enq.bits.uop 46 } 47 48 private val pipesValidVec = VecInit(pipes.map(_.io.deq.valid)) 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