异常连接IO的Vec
Exception connecting Vec of IO
谁能解释一下这个结构的问题是什么?我有一个带有 IO Vec 的子模块,我试图将其附加到父模块中的等效 IO。
这只使用一个 Seq 就可以很好地工作,但是当我在 Vec 中进行详细说明时,我得到了一个异常。 Vec 是必需的,因为在我的真实情况下,它在子模块中使用硬件信号进行索引。
错误:
[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.
代码:
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"))
}
这里的问题是 VecInit
创建了类型 Vec
的 Wire
并将 Seq
中的所有内容连接到 Wire
的元素。您基本上在做的是创建 IOs
的 Seq
,然后将它们连接到 Wire
.
错误消息中提到了这一点(例如 (MyBundle[3](Wire in Lower))
),但我完全明白其中的困惑——并不是那么清楚,而且 VecInit
可能命名有误。 API 中的这种特殊歧义来自 Chisel 中的历史设计决策,这些决策正在慢慢得到修复,但它是一个有时会伤害用户的疣,对此深表歉意。
这是完成您想要的事情的正确方法,只需使用 IO(Vec(<n>, <type>))
。 Vec(<n>, <type>)
是创建 Vec
类型的方法,在本例中是 Vec
类型的 IO
,而不是创建 Wire
并连接所有字段:
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
}
}
(斯卡斯蒂 link: https://scastie.scala-lang.org/COb88oXGRmKQb7BZ3id9gg)
谁能解释一下这个结构的问题是什么?我有一个带有 IO Vec 的子模块,我试图将其附加到父模块中的等效 IO。
这只使用一个 Seq 就可以很好地工作,但是当我在 Vec 中进行详细说明时,我得到了一个异常。 Vec 是必需的,因为在我的真实情况下,它在子模块中使用硬件信号进行索引。
错误:
[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.
代码:
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"))
}
这里的问题是 VecInit
创建了类型 Vec
的 Wire
并将 Seq
中的所有内容连接到 Wire
的元素。您基本上在做的是创建 IOs
的 Seq
,然后将它们连接到 Wire
.
错误消息中提到了这一点(例如 (MyBundle[3](Wire in Lower))
),但我完全明白其中的困惑——并不是那么清楚,而且 VecInit
可能命名有误。 API 中的这种特殊歧义来自 Chisel 中的历史设计决策,这些决策正在慢慢得到修复,但它是一个有时会伤害用户的疣,对此深表歉意。
这是完成您想要的事情的正确方法,只需使用 IO(Vec(<n>, <type>))
。 Vec(<n>, <type>)
是创建 Vec
类型的方法,在本例中是 Vec
类型的 IO
,而不是创建 Wire
并连接所有字段:
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
}
}
(斯卡斯蒂 link: https://scastie.scala-lang.org/COb88oXGRmKQb7BZ3id9gg)