Search code examples
chisel

Chisel: Decoupled directionality lost in nested Vecs


I have a Vec[Decoupled[UInt]] that I want to connect to a Vec of Vec[Decoupled[UInt]] based on a select signal. However, once it seems the directionality of the Decoupled is lost once it is nested two layers deep, so it won't let me initialize the ready signals or drive the output with the input.

For example, Chisel allows me to instantiate this:

class Example extends Module {
  val io = IO(new Bundle {
    val in = Vec(3, Flipped(Decoupled(UInt(3.W))))
    val out = Vec(3, Decoupled(UInt(3.W)))
  })
  io.in.foreach(_.ready := false.B) // Only here for consistency
  io.out <> io.in
}

But this yields an error:

class Example extends Module {
  val io = IO(new Bundle {
    val sel = Input(UInt(4.W))
    val in = Vec(10, Vec(3, Flipped(Decoupled(UInt(3.W)))))
    val out = Vec(3, Decoupled(UInt(3.W)))
  })
  io.in.foreach(_.foreach(_.ready := false.B))
  io.out <> io.in(io.sel)
}

The latter gives errors that read

Sink is unwriteable by current module (line 7)
Both left and right are drivers (line 8)

Is this an error with Chisel or am I missing something? How can I work around this?


Solution

  • This is... weird. I haven't found the cause yet but I have confirmed the buggy behavior you are seeing. Fortunately, there is an easy workaround, put the Flipped outside the Vec.

    class Example extends Module {
      val io = IO(new Bundle {
        val sel = Input(UInt(4.W))
        val in = Flipped(Vec(10, Vec(3, Decoupled(UInt(3.W)))))
        val out = Vec(3, Decoupled(UInt(3.W)))
      })
      io.in.foreach(_.foreach(_.ready := false.B))
      io.out <> io.in(io.sel)
    }
    

    I've filed an issue on the Chisel repo to track this bug.