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