Can anyone explain what the problem with this construction is? I have a child module with a Vec of IO that I'm trying to attach to the equivilent IO in the parent module.
This works out fine with just a Seq but I get an exception during elaboration when wrapped up in Vec. The Vec is needed since in my real case that gets indexed with a hardware signal in the child module.
The error:
[error] chisel3.internal.ChiselException: Connection between left (MyBundle[3](Wire in Lower)) and source (MyBundle[3](Wire in Upper)) failed @(0).out: Left or Right unavailable to current module.
The code:
package Testcase
import chisel3._
import chisel3.util._
import chisel3.stage.ChiselStage
import amba._
class MyBundle extends Bundle {
val out = Output(UInt(32.W))
}
class Upper (n : Int) extends RawModule {
val io = VecInit(Seq.fill(n)(IO(new MyBundle)))
val lower = Module(new Lower(n))
// This should word in the Vec case but gets the same error
// lower.io <> io
// This works for non Vec case
(lower.io, io).zipped map (_ <> _)
}
class Lower (n : Int) extends RawModule {
val io = VecInit(Seq.fill(n)(IO(new MyBundle)))
for (i <- 0 to n - 1) {
io(i).out := 0.U
}
}
object VerilogMain extends App {
(new ChiselStage).emitVerilog(new Upper(3), Array("--target-dir", "generated"))
}
The issue here is that VecInit creates a Wire of type Vec and connects everything in the Seq to the elements of that Wire. What you're basically doing is creating a Seq of IOs and then connecting them to a Wire.
This is mentioned in the error message (eg. (MyBundle[3](Wire in Lower))) but I totally see the confusion--it's not all that clear and VecInit is probably misnamed. This particular ambiguity in the API comes from historical design decisions in Chisel that are slowly getting fixed but it is a wart that sometimes bites users, sorry about that.
Here's the right way to accomplish what you want, just using IO(Vec(<n>, <type>)). Vec(<n>, <type>) is the way to create something of type Vec, in this case an IO of type Vec, as opposed to creating a Wire and connecting all of the fields:
class Upper (n : Int) extends RawModule {
//val io = VecInit(Seq.fill(n)(IO(new MyBundle)))
val io = IO(Vec(n, new MyBundle))
val lower = Module(new Lower(n))
// This should word in the Vec case but gets the same error
lower.io <> io
}
class Lower (n : Int) extends RawModule {
//val io = VecInit(Seq.fill(n)(IO(new MyBundle)))
val io = IO(Vec(n, new MyBundle))
for (i <- 0 to n - 1) {
io(i).out := 0.U
}
}
(Scastie link: https://scastie.scala-lang.org/COb88oXGRmKQb7BZ3id9gg)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With