我有一个如下所示的模块:
class ComputationIO[T <: Data](val OperandType: T) extends Bundle {
val data = OperandType.cloneType
}
class Computation [T <: Data] (OperandType: T) extends Module {
val io = IO( new Bundle {
val in = Input(new ComputationIO(OperandType))
})
// REST OF THE CODE HERE...
}
Run Code Online (Sandbox Code Playgroud)
而且,我正在实例化Computation以下内容:
val compUnit = for (i <- 0 until nParal) yield {
val Comp = Module(new Computation(UInt(32.W)))
Comp
}
Run Code Online (Sandbox Code Playgroud)
但是,虽然我传递UInt(32.W)给构造函数,但它给了我以下错误:
firrtl.passes.CheckInitialization$RefNotInitializedException:Reference compUnit is not fully initialized.
[error] : compUnit.io.in.OperandType <= VOID
Run Code Online (Sandbox Code Playgroud)
我可以通过删除valIO 类中的 并覆盖cloneType,来解决这个问题,如下所示:
class ComputationIO[T <: Data](OperandType: T) extends Bundle {
val data = OperandType.cloneType
override def cloneType = new ComputationIO(OperandType).asInstanceOf[this.type ]
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道第一种方法的问题是什么?构造函数已初始化。所以,这个not fully initialized错误没有意义。
谢谢
另一个答案中链接的文档提到了这一点,但我想强调一下:
唯一需要注意的是,如果您将 Data 类型的东西作为“生成器”参数传递,在这种情况下,您应该将其设为私有 val。
这是因为如果您将类参数设为 a val,它将成为该类的公共字段。a 的硬件字段Bundle被定义为“类型类的公共字段Data”。因此,val OperandType是类的一个字段,它与写作相同:
class ComputationIO[T <: Data](_operandType: T) extends Bundle {
val OperandType = _operandType
val data = OperandType.cloneType
}
Run Code Online (Sandbox Code Playgroud)
事实上,你只需要调用cloneType,OperandType因为你得到了字段别名OperandType并且data是完全相同的对象。这显然只是一个问题,因为您无意中OperandType将 Bundle 作为公共字段。
您可以通过将其设置为 a 来处理此问题,这private val不会导致它成为以下字段Bundle:
class ComputationIO[T <: Data](private val OperandType: T) extends Bundle {
val data = OperandType // note .cloneType not necessary
}
Run Code Online (Sandbox Code Playgroud)
请注意,从 Chisel v3.4.3 开始,可选择加入 Autoclonetype2,它不需要参数为 val 即可推断克隆类型,您可以查看发行说明以获取更多信息。Autoclonetype2 将成为 Chisel v3.5.0(尚未发布)中的默认值。
| 归档时间: |
|
| 查看次数: |
65 次 |
| 最近记录: |