输入 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
的新克隆,而您只需将 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
这是一个古老的问题,我们没有很好的解决方案,在您的情况下,您应该在 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)
}
}
我需要为复杂 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
的新克隆,而您只需将 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
这是一个古老的问题,我们没有很好的解决方案,在您的情况下,您应该在 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)
}
}