Spinal无法克隆类(Spinal can’t clone class)
简介
当SpinalHDL想要通过 cloneOf
函数创建一个新的数据类型实例,但做不到这一点时,就会出现此错误。出现这种情况的原因几乎都是因为它无法检索 Bundle
的构造参数。
例子1
下面的代码:
// cloneOf(this) isn't able to retrieve the width value that was used to construct itself
class RGB(width : Int) extends Bundle {
val r, g, b = UInt(width bits)
}
class TopLevel extends Component {
val tmp = Stream(new RGB(8)) // Stream requires the capability to cloneOf(new RGB(8))
}
会报错:
*** Spinal can't clone class spinal.tester.PlayDevMessages$RGB datatype
*** You have two way to solve that :
*** In place to declare a "class Bundle(args){}", create a "case class Bundle(args){}"
*** Or override by your self the bundle clone function
***
Source file location of the RGB class definition via the stack trace
***
一个可能的修复方法是:
case class RGB(width : Int) extends Bundle {
val r, g, b = UInt(width bits)
}
class TopLevel extends Component {
val tmp = Stream(RGB(8))
}
例子2
下面的代码:
case class Xlen(val xlen: Int) {}
case class MemoryAddress()(implicit xlenConfig: Xlen) extends Bundle {
val address = UInt(xlenConfig.xlen bits)
}
class DebugMemory(implicit config: Xlen) extends Component {
val io = new Bundle {
val inputAddress = in(MemoryAddress())
}
val someAddress = RegNext(io.inputAddress) // -> ERROR *****************************
}
报错:
[error] *** Spinal can't clone class debug.MemoryAddress datatype
在这种情况下,一种解决方案是覆盖克隆函数以传递隐式参数。
case class MemoryAddress()(implicit xlenConfig: Xlen) extends Bundle {
val address = UInt(xlenConfig.xlen bits)
override def clone = MemoryAddress()
}
备注
我们需要克隆的是硬件的单元,而不是最终在其中赋值的值。
备注
另一种方法是使用 ScopeProperty。