You're reading the documentation for a development version.
For the latest stable release version, please have a look at master.

Spinal can’t clone class

Introduction

This error happens when SpinalHDL wants to create a new datatype instance via the cloneOf function but isn’t able to do it. The reason for this is nearly always because it can’t retrieve the construction parameters of a Bundle.

Example 1

The following code:

// 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))
}

will throw:

*** 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
  ***

A fix could be:

case class RGB(width : Int) extends Bundle {
  val r, g, b = UInt(width bits)
}

class TopLevel extends Component {
  val tmp = Stream(RGB(8))
}

Example 2

The following code:

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 *****************************
}

raises an exeption:

[error] *** Spinal can't clone class debug.MemoryAddress datatype

In this case, a solution is to override the clone function to propagate the implicit parameter.

case class MemoryAddress()(implicit xlenConfig: Xlen) extends Bundle {
  val address = UInt(xlenConfig.xlen bits)

  override def clone = MemoryAddress()
}

Note

We need to clone the hardware element, not the eventually assigned value in it.

Note

An alternative is to used ScopeProperty.