复数的类型类别

时间:2019-01-10 20:47:33

标签: complex-numbers chisel

我需要为Complex DSP和Complex Ring操作实现一个自定义类型类。我知道DspTools项目,但有意将其排除在考虑范围之外。

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

这是我的最小课程:

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发出错误:

[info]使用--backend-name验证程序 [info] chisel3.core.Binding $ RebindingException:尝试将绑定重新分配给chisel3.core.FixedPoint@d [info]位于chisel3.core.Data.binding_ $ eq(Data.scala:250)

这是怎么了?如何解决该问题?

2 个答案:

答案 0 :(得分:2)

问题是,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

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

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

答案 1 :(得分:1)

这是对我有用的实际简约实现。 @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)
  }  
}