输入 Class 作为复数

Type Class for Complex Numbers

我需要为复杂 DSP 和复杂环操作实现自定义类型 class。我知道 DspTools 项目,但故意不考虑它。

我有一个硬件模块,我想用 diff 类型实例化它 classes: UInt, SInt, FixedPoint, Real and Complex(FixedPoint, FixedPoint)。

这是我的最小值 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)
}

当我使用来自 Chisel3.Core 的不同数据类型对其进行实例化时,代码会编译并运行。 但是,当我尝试这样做时:

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))
...

我编译了代码,但 FIRRTL 发出错误:

[信息] 使用 --backend-name verilator [信息] chisel3.core.Binding$RebindingException:尝试重新分配绑定到 chisel3.core.FixedPoint@d [信息] 在 chisel3.core.Data.binding_$eq(Data.scala:250)

这是怎么回事?如何解决这个问题?

问题是 Chisel 在递归调用 cloneType 时需要任何 Data 的新克隆,而您只需将 reim 传递给 Complex构造函数产生完全相同的对象。说得具体一点:

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

这是一个古老的问题,我们没有很好的解决方案,在您的情况下,您应该在 re 上调用 .cloneType 并在 Complex.cloneType

我知道你没有使用 DSPTools,但它仍然可以提供参考,他们这样做了:https://github.com/ucb-bar/dsptools/blob/fe8f9d08987f3a403f6281ba4face1c26b627b71/src/main/scala/dsptools/numbers/chisel_concrete/DspComplex.scala#L75

这是对我有用的实际简约实现。 @jkoenig 为我指明了正确的方向。非常感谢!

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

object Complex {

  def apply[A <: Data, B <: Data](re:A, im:B):Complex[A,B] = {
    val real  = re.cloneType
    val imag  = im.cloneType
    new Complex(real,imag)
  }  
}