Skip to content

Commit 8c2115f

Browse files
authored
Make DspComplex multiplies use growing addition. (#157)
DspComplex relies on using the underlying Ring's multiplication. For UInt, SInt, FixedPoint, etc. these additions wrap instead of grow. For our implementation of complex multiplication, growing is more desirable than wrapping. This commit adds specialized versions of the DspComplex for UInt, SInt, FixedPoint, etc. that use growing addition.
1 parent 617449d commit 8c2115f

File tree

2 files changed

+39
-5
lines changed

2 files changed

+39
-5
lines changed

src/main/scala/dsptools/numbers/chisel_types/DspComplexTypeClass.scala

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,30 @@
33
package dsptools.numbers
44

55
import chisel3._
6+
import chisel3.experimental.FixedPoint
67
import dsptools.hasContext
78
import implicits._
89
import chisel3.util.ShiftRegister
910
import dsptools.DspException
1011

11-
class DspComplexRing[T <: Data:Ring] extends Ring[DspComplex[T]] with hasContext {
12+
abstract class DspComplexRing[T <: Data:Ring] extends Ring[DspComplex[T]] with hasContext {
1213
def plus(f: DspComplex[T], g: DspComplex[T]): DspComplex[T] = {
1314
DspComplex.wire(f.real + g.real, f.imag + g.imag)
1415
}
1516
def plusContext(f: DspComplex[T], g: DspComplex[T]): DspComplex[T] = {
1617
DspComplex.wire(f.real context_+ g.real, f.imag context_+ g.imag)
1718
}
19+
20+
/**
21+
* The builtin times calls +. Ideally we'd like to use growing addition, but we're relying on typeclasses and the
22+
* default + for UInt, SInt, etc. is wrapping. Thus, we're making an escape hatch just for the default (non-context)
23+
* complex multiply.
24+
* @param l
25+
* @param r
26+
* @return the sum of l and r, preferrably growing
27+
*/
28+
protected def plusForTimes(l: T, r: T): T
29+
1830
def times(f: DspComplex[T], g: DspComplex[T]): DspComplex[T] = {
1931
val c_p_d = g.real + g.imag
2032
val a_p_b = f.real + f.imag
@@ -59,6 +71,22 @@ class DspComplexRing[T <: Data:Ring] extends Ring[DspComplex[T]] with hasContext
5971
}
6072
}
6173

74+
class DspComplexRingUInt extends DspComplexRing[UInt] {
75+
override def plusForTimes(l: UInt, r: UInt): UInt = l +& r
76+
}
77+
78+
class DspComplexRingSInt extends DspComplexRing[SInt] {
79+
override def plusForTimes(l: SInt, r: SInt): SInt = l +& r
80+
}
81+
82+
class DspComplexRingFixed extends DspComplexRing[FixedPoint] {
83+
override def plusForTimes(l: FixedPoint, r: FixedPoint): FixedPoint = l +& r
84+
}
85+
86+
class DspComplexRingData[T <: Data : Ring] extends DspComplexRing[T] {
87+
override protected def plusForTimes(l: T, r: T): T = l + r
88+
}
89+
6290
class DspComplexEq[T <: Data:Eq] extends Eq[DspComplex[T]] with hasContext {
6391
override def eqv(x: DspComplex[T], y: DspComplex[T]): Bool = {
6492
Eq[T].eqv(x.real, y.real) && Eq[T].eqv(x.imag, y.imag)
@@ -81,9 +109,15 @@ class DspComplexBinaryRepresentation[T <: Data:Ring:BinaryRepresentation] extend
81109
DspComplex.wire(BinaryRepresentation[T].trimBinary(a.real, n), BinaryRepresentation[T].trimBinary(a.imag, n))
82110
}
83111

84-
trait DspComplexImpl {
85-
implicit def DspComplexRingImpl[T<: Data:Ring] = new DspComplexRing[T]()
112+
trait GenericDspComplexImpl {
113+
implicit def DspComplexRingDataImpl[T<: Data:Ring] = new DspComplexRingData[T]()
86114
implicit def DspComplexEq[T <: Data:Eq] = new DspComplexEq[T]()
87115
implicit def DspComplexBinaryRepresentation[T <: Data:Ring:BinaryRepresentation] =
88116
new DspComplexBinaryRepresentation[T]()
89117
}
118+
119+
trait DspComplexImpl extends GenericDspComplexImpl {
120+
implicit def DspComplexRingUIntImpl = new DspComplexRingUInt
121+
implicit def DspComplexRingSIntImpl = new DspComplexRingSInt
122+
implicit def DspComplexRingFixedImpl = new DspComplexRingFixed
123+
}

src/test/scala/dsptools/numbers/DspComplexSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
// See LICENSE for license details.
22

3-
package dsptools.numbers
3+
package testing.dsptools.numbers
44

55
import chisel3._
66
import chisel3.iotesters.ChiselPropSpec
77
import chisel3.testers.BasicTester
8-
import dsptools.numbers.implicits._
8+
import dsptools.numbers._
99

1010
//scalastyle:off magic.number
1111
class DspComplexExamples extends Module {

0 commit comments

Comments
 (0)