1package xiangshan.backend 2 3import chisel3._ 4import chisel3.util._ 5 6class PipeGroupConnect[T <: Data](n: Int, gen: => T) extends Module { 7 val io = IO(new Bundle { 8 val in = Vec(n, Flipped(DecoupledIO(gen))) 9 val out = Vec(n, DecoupledIO(gen)) 10 val flush = Input(Bool()) 11 }) 12 13 // Input Alias 14 // Use private[this] to limit the wrong usage for not IO hardware in object with the same name. 15 private[this] val flush = io.flush 16 private[this] val inValidSeq = io.in.map(_.valid) 17 private[this] val inDataSeq = io.in.map(_.bits) 18 private[this] val outReadySeq = io.out.map(_.ready) 19 20 // Regs 21 private[this] val validVec = RegInit(VecInit.fill(n)(false.B)) 22 private[this] val dataVec = Reg(Vec(n, gen)) 23 24 // Logic 25 private[this] val valids = Cat(validVec.reverse) 26 private[this] val inValids = Cat(inValidSeq.reverse) 27 private[this] val outReadys = Cat(outReadySeq.reverse) 28 29 // Todo: canAccVec for each elem 30 // Todo: no outReadys version for better timing and lower performance 31 private[this] val canAcc = ((~valids).asUInt | outReadys).andR 32 33 (validVec zip inValids.asBools zip outReadys.asBools).foreach { case ((valid, inValid), outReady) => 34 valid := MuxCase( 35 default = valid /*keep*/, 36 Seq( 37 flush -> false.B, 38 (inValid && canAcc) -> true.B, 39 outReady -> false.B 40 ) 41 ) 42 } 43 44 (dataVec zip inValids.asBools zip inDataSeq).foreach { case ((data, inValid), inData) => 45 when (inValid && canAcc) { 46 data := inData 47 } 48 } 49 50 // Output connections 51 for (i <- 0 until n) { 52 io.in(i).ready := canAcc 53 io.out(i).valid := validVec(i) 54 io.out(i).bits := dataVec(i) 55 } 56} 57 58object PipeGroupConnect { 59 def apply[T <: Data]( 60 // Left can be not Vec, but right must be Vec 61 left: Seq[DecoupledIO[T]], 62 right: Vec[DecoupledIO[T]], 63 flush: Bool, 64 suggestName: String = null, 65 ): Unit = { 66 require(left.size == right.size, "The sizes of left and right Vec Bundle should be equal in PipeGroupConnect") 67 require(left.size > 0, "The size of Vec Bundle in PipeGroupConnect should be more than 0") 68 val mod = Module(new PipeGroupConnect(left.size, chiselTypeOf(left.head.bits))) 69 mod.io.flush := flush 70 mod.io.in.zipWithIndex.foreach { case (in, i) => 71 in.valid := left(i).valid 72 in.bits := left(i).bits 73 left(i).ready := in.ready 74 } 75 right <> mod.io.out 76 77 if (suggestName != null) 78 mod.suggestName(suggestName) 79 } 80} 81