Search code examples
complex-numberschisel

Type Class for Complex Numbers


I need to implement a custom type class for Complex DSP and Complex Ring operations. I'm aware about DspTools project, but purposely want to exclude it from consideration.

I've got a hardware module, which I want to instantiate with diff type classes: UInt, SInt, FixedPoint, Real and Complex(FixedPoint, FixedPoint).

Here's my minimal class:

class Complex[A <: Data, B <: Data] (val re:A, val im:B) extends Bundle {
  override def cloneType: this.type = new Complex(re, im).asInstanceOf[this.type]
}

object Complex {    
  def apply[A <: Data, B <: Data](re:A, im:B) = new Complex(re, im)  
  implicit def UInt2Complex(re:UInt, im:UInt) = Complex(re,im)
}

When I instantiate this with different data types from Chisel3.Core, the code compiles and works. However, when I try to do :

import chisel3.core.{FixedPoint => FP}
...

  val inType  = Complex ( FP(20.W,10.BP), FP(20.W,10.BP))
  val outType = Complex ( FP(20.W,10.BP), FP(20.W,10.BP))
...

I get the code compiled, but FIRRTL emits an error:

[info] using --backend-name verilator [info] chisel3.core.Binding$RebindingException: Attempted reassignment of binding to chisel3.core.FixedPoint@d [info] at chisel3.core.Data.binding_$eq(Data.scala:250)

What's wrong with this? How to fix the issue?


Solution

  • The issue is that Chisel needs fresh clones of any Data when it recursively calls cloneType, and you're simply passing re and im to the Complex constructor resulting in the exact same objects. Put a little more concretely:

    val a = Complex(UInt(8.W), UInt(8.W))
    val b = a.cloneType
    a.re eq b.re // This will be true and it *must* not be
    

    This is kind of an age old problem that we don't have a great solution to, in your case, you should call .cloneType on re and im in Complex.cloneType

    I know you aren't using DSPTools, but it can still provide a reference and they do that: https://github.com/ucb-bar/dsptools/blob/fe8f9d08987f3a403f6281ba4face1c26b627b71/src/main/scala/dsptools/numbers/chisel_concrete/DspComplex.scala#L75