R
rickman
Guest
On 12/24/2014 3:24 AM, Rob Doyle wrote:
I understand, but the distinction between a multiplier and a CORDIC
implementation is pretty pointless these days. If you have the space to
implement a CORDIC wouldn't you have the space to implement an
iterative multiply? I did a linear interpolation just because I could
do the multiply iteratively while the previous sample was shifted out to
the CODEC. One adder is the same as the CORDIC, no?
I guess the difference is you only need one CORDIC while for a sine that
is not an approximation you need two multipliers. I don't see how one
would be faster than the other except for the case of a dedicated
multiplier being much faster.
--
Rick
On 12/23/2014 9:40 PM, rickman wrote:
On 12/23/2014 11:02 PM, Rob Doyle wrote:
On 12/23/2014 6:10 PM, robert bristow-johnson wrote:
this did not seem to get posted so i am reposting. sorry for any
repeated post.
On 12/22/14 5:17 PM, Rob Doyle wrote:
On 12/21/2014 5:13 PM, Eric Jacobsen wrote:
On Sun, 21 Dec 2014 14:52:40 -0500, robert bristow-johnson
rbj@audioimagination.com> wrote:
On 12/19/14 11:04 PM, Eric Jacobsen wrote:
On Fri, 19 Dec 2014 18:19:24 -0500, robert bristow-johnson
rbj@audioimagination.com> wrote:
On 12/19/14 10:06 AM, rickman wrote:
I want to analyze the output of a DDS circuit and am
wondering if an FFT is the best way to do this. I'm
mainly concerned with the "close
in"
spurs that are often generated by a DDS.
i still get the concepts of DDS and NCO mixed up. what are
the differences?
One is spelled DDS and the other is spelled NCO.
is the NCO the typical table-lookup kind (with phase
accumulator)? or can it be algorithmic? like
y[n] = (2*cos(omega_0))*y[n-1] - y[n-2]
where omega_0 is the normalized angular frequency of the
sinusoid and with appropriate initial states, y[-1] and y[-2]
to result in the amplitude and initial phase desired.
is that an NCO that can be used in this DDS? or must it be
LUT?
Generally NCO or DDS refers to a phase accumulator with a LUT,
since it is easily implemented in hardware. That's a general
architecture that is well-known and can be adjusted to produce
very clean local oscillators. If somebody tried to sell me a
block of IP with an "NCO" built some other way I'd be asking a
lot of questions.
I have built NCOs using CORDIC rotators. No lookup tables. They
pipeline nicely and are therefore very fast, they require no
multipliers [1],
???
i don't s'pose Ray Andraka is hanging around (he was Dr. CORDIC here
a while back), but i always thought that CORDIC did essentially
x[n] = cos(2*pi*f0/Fs) * x[n-1] - sin(2*pi*f0/Fs) * y[n-1]
y[n] = sin(2*pi*f0/Fs) * x[n-1] + cos(2*pi*f0/Fs) * y[n-1]
Yes. So far. So good. These are my notes if anyone is interested...
[snip]
Assume theta = 2*pi*f0*t/fs, i.e., theta is the output of a phase
accumulator for an NCO application.
Factor out the cos(theta):
x[n] = cos(theta) {x[n-1] - y[n-1] tan(theta)}
y[n] = cos(theta) {y[n-1] + x[n-1] tan(theta)}
If you select tan(theta) from the set of 1/(2**i) then [1] this becomes:
x[n] = cos(theta) {x[n-1] - y[n-1] / 2**i}
y[n] = cos(theta) {y[n-1] + x[n-1] / 2**i}
At this point you might be thinking "Holy crap. That's one heck of a
constraint!" Yeh... but keep reading anyway.
You can drop the cos(theta) common term. It's just a gain term that
rapidly converges to 1.647. Therefore the gain of a CORDIC is not 0 dB.
x[n] = x[n-1] - y[n-1] / 2**i
y[n] = y[n-1] + x[n-1] / 2**i
or (assuming twos complement math) - simply:
x[n] = x[n-1] - y[n-1] >> i
y[n] = y[n-1] + x[n-1] >> i
where >> is a shift right operation
[1] As this point it seems as if an *extreme* limitation has been placed
on the selection of rotation angles. The equation above only describes
how to rotate an input signal by tan(theta) = 1/(2**i) - or by one of
the following angles:
atan(1) (45.000000000000000000000000000000 degrees)
atan(1/2) (26.565051177077989351572193720453 degrees)
atan(1/4) (14.036243467926478582892320159163 degrees)
atan(1/8) (7.1250163489017975619533008412068 degrees)
atan(1/16) (3.5763343749973510306847789144588 degrees)
atan(1/32) (1.7899106082460693071502497760791 degrees)
...and so forth.
The equation above does not describe how to rotate an input signal an
arbitrary angle! Although this is true; all is not lost.
Notice that in general that theta/2 < tan(theta).
This truth allows the CORDIC to be used iteratively to rotate any input
to any angle with any precision. IMO this is the genius of the CORDIC.
I probably should have mentioned that you swap the rotation direction by
flipping the additions and subtractions.
The term z[n] is introduced to accumulate the angle as the CORDIC
iterates. The term d[n] swaps the direction of rotation. Finally the
familiar recursive CORDIC equation can be written as follows:
x[n] = x[n-1] - d[n] y[n-1] >> i
y[n] = y[n-1] + d[n] x[n-1] >> i
z[n] = z[n-1] - d[n] tan(1/2**i)
where:
d[n] is +1 for z[n-1] < theta. Clockwise rotation next.
d[n] is -1 for z[n-1] > theta. Counter-clockwise rotation next.
No multiplies here.
But this is the same as a multiply in terns of complexity, no? One
large difference is that a multiply can be supported in commonly
available hardware while this algorithm requires dedicated hardware or
iterative software.
I agree that the CORDIC has the same complexity as a multiply. I agree
that table-based algorithms using multipliers use less FPGA fabric.
I was simply pointing out that there might be places where a CORDIC has
advantages over LUT-based NCOs.
Especially if have ROM or multiplier limitations.
I also wanted to point out that if you need to do a 20-bit (using your
120dB example) complex downconversion for example, the CORDIC still
requires zero multipliers.
If you want to do a 20-bit complex downconversion using a table-based
NCO followed by a complex mixer, you might need a *lot* of multipliers.
If you only have an 18-bit multiplier, each multiplication requires
(maybe up to) 4 multiplier blocks and you need 8 multiplications.
I also /suspect/ that for any given device technology the CORDIC will
execute at higher speeds.
Thats all...
I understand, but the distinction between a multiplier and a CORDIC
implementation is pretty pointless these days. If you have the space to
implement a CORDIC wouldn't you have the space to implement an
iterative multiply? I did a linear interpolation just because I could
do the multiply iteratively while the previous sample was shifted out to
the CODEC. One adder is the same as the CORDIC, no?
I guess the difference is you only need one CORDIC while for a sine that
is not an approximation you need two multipliers. I don't see how one
would be faster than the other except for the case of a dedicated
multiplier being much faster.
--
Rick