Spinal无法克隆类(Spinal can’t clone class)
一、简介
当SpinalHDL想要通过cloneOf
函数创建一个新的数据类型实例, 但是不能这样做时, 就会发生这个错误。出现这种情况的原因总是因为它无法检索Bundle
的构造参数。
二、例子1
下述代码:
// cloneOf(this)无法检索用于构造自身的位宽
class RGB(width : Int) extends Bundle {
val r, g, b = UInt(width bits)
}
class TopLevel extends Component {
val tmp = Stream(new RGB(8)) // Stream需要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(请见”其他语言特性”章节中)