1package xiangshan.backend.issue 2 3import chisel3._ 4import chisel3.util._ 5import utils.PipeWithFlush 6import xiangshan.backend.Bundles.{ExuInput, connectSamePort} 7import xiangshan.backend.exu.ExeUnitParams 8 9class MultiWakeupQueueIO[T <: Bundle, TFlush <: Data]( 10 gen : ExuInput, 11 lastGen : ExuInput, 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 deq = Output(Valid(lastGen)) 23} 24 25class MultiWakeupQueue[T <: Bundle, TFlush <: Data]( 26 val gen : ExuInput, 27 val lastGen : ExuInput, 28 val flushGen : TFlush, 29 val latencySet: Set[Int], 30 flushFunc : (ExuInput, TFlush, Int) => Bool, 31 modificationFunc: ExuInput => ExuInput = { x: ExuInput => x }, 32 lastConnectFunc: (ExuInput, ExuInput) => ExuInput, 33) extends Module { 34 require(latencySet.min >= 0) 35 36 val io = IO(new MultiWakeupQueueIO(gen, lastGen, flushGen, log2Up(latencySet.max) + 1)) 37 38 val pipes = latencySet.map(x => Module(new PipeWithFlush[T, TFlush](gen, flushGen, x, flushFunc, modificationFunc))).toSeq 39 40 val pipesOut = Wire(Valid(gen)) 41 val lastConnect = Reg(Valid(lastGen)) 42 43 pipes.zip(latencySet).foreach { 44 case (pipe, lat) => 45 pipe.io.flush := io.flush 46 pipe.io.enq.valid := io.enq.valid && io.enq.bits.lat === lat.U 47 pipe.io.enq.bits := io.enq.bits.uop 48 } 49 50 private val pipesValidVec = VecInit(pipes.map(_.io.deq).zip(latencySet).map(_ match { 51 case (deq, 0) => deq.valid 52 case (deq, i) => deq.valid && !flushFunc(deq.bits, io.flush, i) 53 })) 54 private val pipesBitsVec = VecInit(pipes.map(_.io.deq.bits).zip(latencySet).map(_ match { 55 case (deq, 0) => deq 56 case (deq, i) => modificationFunc(deq) 57 })) 58 59 pipesOut.valid := pipesValidVec.asUInt.orR 60 pipesOut.bits := Mux1H(pipesValidVec, pipesBitsVec) 61 pipesOut.bits.rfWen .foreach(_ := pipesValidVec.zip(pipesBitsVec.map(_.rfWen .get)).map{case(valid,wen) => valid && wen}.reduce(_||_)) 62 pipesOut.bits.fpWen .foreach(_ := pipesValidVec.zip(pipesBitsVec.map(_.fpWen .get)).map{case(valid,wen) => valid && wen}.reduce(_||_)) 63 pipesOut.bits.vecWen.foreach(_ := pipesValidVec.zip(pipesBitsVec.map(_.vecWen.get)).map{case(valid,wen) => valid && wen}.reduce(_||_)) 64 65 lastConnect.valid := pipesOut.valid 66 lastConnect.bits := lastConnectFunc(pipesOut.bits, lastConnect.bits) 67 68 io.deq.valid := lastConnect.valid 69 io.deq.bits := lastConnect.bits 70 71 assert(PopCount(pipesValidVec) <= 1.U, "PopCount(pipesValidVec) should be no more than 1") 72} 73