xref: /XiangShan/src/main/scala/xiangshan/backend/PipeGroupConnect.scala (revision 1c6572a60e0280d38a76fba88d647f136635e60c)
15b70e4b0SXuan Hupackage xiangshan.backend
25b70e4b0SXuan Hu
35b70e4b0SXuan Huimport chisel3._
45b70e4b0SXuan Huimport chisel3.util._
55b70e4b0SXuan Hu
65b70e4b0SXuan Huclass PipeGroupConnect[T <: Data](n: Int, gen: => T) extends Module {
75b70e4b0SXuan Hu  val io = IO(new Bundle {
85b70e4b0SXuan Hu    val in = Vec(n, Flipped(DecoupledIO(gen)))
95b70e4b0SXuan Hu    val out = Vec(n, DecoupledIO(gen))
105b70e4b0SXuan Hu    val flush = Input(Bool())
11f5c17053Sxiaofeibao-xjtu    val outAllFire = Input(Bool())
125b70e4b0SXuan Hu  })
135b70e4b0SXuan Hu
145b70e4b0SXuan Hu  // Input Alias
155b70e4b0SXuan Hu  // Use private[this] to limit the wrong usage for not IO hardware in object with the same name.
165b70e4b0SXuan Hu  private[this] val flush = io.flush
175b70e4b0SXuan Hu  private[this] val inValidSeq  = io.in.map(_.valid)
185b70e4b0SXuan Hu  private[this] val inDataSeq   = io.in.map(_.bits)
195b70e4b0SXuan Hu  private[this] val outReadySeq = io.out.map(_.ready)
205b70e4b0SXuan Hu
215b70e4b0SXuan Hu  // Regs
225b70e4b0SXuan Hu  private[this] val validVec = RegInit(VecInit.fill(n)(false.B))
235b70e4b0SXuan Hu  private[this] val dataVec  = Reg(Vec(n, gen))
245b70e4b0SXuan Hu
255b70e4b0SXuan Hu  // Logic
265b70e4b0SXuan Hu  private[this] val valids    = Cat(validVec.reverse)
275b70e4b0SXuan Hu  private[this] val inValids  = Cat(inValidSeq.reverse)
285b70e4b0SXuan Hu  private[this] val outReadys = Cat(outReadySeq.reverse)
295b70e4b0SXuan Hu
305b70e4b0SXuan Hu  // Todo: canAccVec for each elem
315b70e4b0SXuan Hu  // Todo: no outReadys version for better timing and lower performance
32*1c6572a6Sxiaofeibao  private[this] val canAcc = io.outAllFire || !valids.orR
335b70e4b0SXuan Hu
345b70e4b0SXuan Hu  (validVec zip inValids.asBools zip outReadys.asBools).foreach { case ((valid, inValid), outReady) =>
355b70e4b0SXuan Hu    valid := MuxCase(
365b70e4b0SXuan Hu      default = valid /*keep*/,
375b70e4b0SXuan Hu      Seq(
385b70e4b0SXuan Hu        flush               -> false.B,
395b70e4b0SXuan Hu        (inValid && canAcc) -> true.B,
405b70e4b0SXuan Hu        outReady            -> false.B
415b70e4b0SXuan Hu      )
425b70e4b0SXuan Hu    )
435b70e4b0SXuan Hu  }
445b70e4b0SXuan Hu
455b70e4b0SXuan Hu  (dataVec zip inValids.asBools zip inDataSeq).foreach { case ((data, inValid), inData) =>
465b70e4b0SXuan Hu    when (inValid && canAcc) {
475b70e4b0SXuan Hu      data := inData
485b70e4b0SXuan Hu    }
495b70e4b0SXuan Hu  }
505b70e4b0SXuan Hu
515b70e4b0SXuan Hu  // Output connections
525b70e4b0SXuan Hu  for (i <- 0 until n) {
535b70e4b0SXuan Hu    io.in(i).ready  := canAcc
545b70e4b0SXuan Hu    io.out(i).valid := validVec(i)
555b70e4b0SXuan Hu    io.out(i).bits  := dataVec(i)
565b70e4b0SXuan Hu  }
575b70e4b0SXuan Hu}
585b70e4b0SXuan Hu
595b70e4b0SXuan Huobject PipeGroupConnect {
605b70e4b0SXuan Hu  def apply[T <: Data](
615b70e4b0SXuan Hu    // Left can be not Vec, but right must be Vec
625b70e4b0SXuan Hu    left: Seq[DecoupledIO[T]],
635b70e4b0SXuan Hu    right: Vec[DecoupledIO[T]],
645b70e4b0SXuan Hu    flush: Bool,
65f5c17053Sxiaofeibao-xjtu    rightAllFire: Bool,
665b70e4b0SXuan Hu    suggestName: String = null,
675b70e4b0SXuan Hu  ): Unit =  {
685b70e4b0SXuan Hu    require(left.size == right.size, "The sizes of left and right Vec Bundle should be equal in PipeGroupConnect")
695b70e4b0SXuan Hu    require(left.size > 0, "The size of Vec Bundle in PipeGroupConnect should be more than 0")
705b70e4b0SXuan Hu    val mod = Module(new PipeGroupConnect(left.size, chiselTypeOf(left.head.bits)))
715b70e4b0SXuan Hu    mod.io.flush := flush
725b70e4b0SXuan Hu    mod.io.in.zipWithIndex.foreach { case (in, i) =>
735b70e4b0SXuan Hu      in.valid := left(i).valid
745b70e4b0SXuan Hu      in.bits := left(i).bits
755b70e4b0SXuan Hu      left(i).ready := in.ready
765b70e4b0SXuan Hu    }
77f5c17053Sxiaofeibao-xjtu    mod.io.outAllFire := rightAllFire
785b70e4b0SXuan Hu    right <> mod.io.out
795b70e4b0SXuan Hu
805b70e4b0SXuan Hu    if (suggestName != null)
815b70e4b0SXuan Hu      mod.suggestName(suggestName)
825b70e4b0SXuan Hu  }
835b70e4b0SXuan Hu}
84