我需要为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)
这是怎么了?如何解决该问题?
答案 0 :(得分:2)
问题是,Chisel递归调用cloneType时,它需要任何Data
的新鲜克隆,而您只是将re
和im
传递给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)
}
}