异常连接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 创建了类型 VecWire 并将 Seq 中的所有内容连接到 Wire 的元素。您基本上在做的是创建 IOsSeq,然后将它们连接到 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)