引用未完全初始化

Ali*_*Sed 2 scala chisel

我有一个如下所示的模块:

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错误没有意义。

谢谢

Jac*_*nig 6

另一个答案中链接的文档提到了这一点,但我想强调一下:

唯一需要注意的是,如果您将 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)

事实上,你只需要调用cloneTypeOperandType因为你得到了字段别名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(尚未发布)中的默认值。