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