# Fxpt\_nco vs rotator?

**URL:** <https://www.ruby-forum.com/t/fxpt-nco-vs-rotator/233647>\
**Category:** GNU Radio\
**Created:** [December 30, 2014, 11:25pm UTC](https://www.ruby-forum.com/t/fxpt-nco-vs-rotator/233647 "2014-12-30T23:25:50Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![addis\_a](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c4cdca/32.png) [@addis\_a](https://www.ruby-forum.com/u/addis_a)\
**Post date:** [December 30, 2014, 11:25pm UTC](https://www.ruby-forum.com/t/fxpt-nco-vs-rotator/233647/1 "2014-12-30T23:25:50Z")

</div>

I’m experimenting with very fine frequency measurements (i.e. uHz  
resolution)  
at high sample rates. For instance, down-converting all the WWV signals  
from a 100 Msps chunk of HF spectrum to near 0 Hz then comparing their  
drift.

I have a handle on the DDC within the USRP and the sig\_source\_c within  
GR,  
both of which use fixed point, 32-bit NCOs, thus the frequency accuracy  
is  
quantifiable, for example:

nco\_freq = int(target\_freq/(samp\_rate/2**32)) \* (samp\_rate/2**32)

Now the Frequency Translating FIR filter uses a rotator, and from what I  
can  
tell by looking at the source (and I may be wrong), that rotator uses  
VOLK  
or falls back to the normal code, both of which use a floating point  
phase  
accumulator, with the latter being double precision.

So is there anyway to quantify the frequency, over a long number of  
cycles,  
with the floating point phase accumulator?

I ran this GRC experiment:

[https://dl.dropboxusercontent.com/u/49570443/rotator\_test\_grc.png](https://dl.dropboxusercontent.com/u/49570443/rotator_test_grc.png)

I generated a 1 Hz tone at 100 Msps with both the sig\_source\_c and  
rotator,  
decimating down to 10 sps, and analysing with Baudline FFT to 8 digits  
of  
precision. The sig\_source\_c was spot on at 0.97788870 Hz, i.e.  
int(1/(100E6/2**32))\*(100E6/2**32)

For the rotator I used a phase increment of (1/100E6)_2_numpy.pi, which  
resulted in 0.99917424 Hz via Baudline.

So I concluded the rotator has higher actuary to the target frequency of  
1  
Hz, but…

Does it converge, or does it slowly drift away?  
Does it have more phase noise than the fixed point NCO?  
I noticed it has some spurs whereas the fixed point was spur-free?

I suppose in cases like this I should use an separate NCO and decimating  
FIR  
for down conversion, instead of the Frequency Translating FIR?

As a side experiment I tried the following python code, which shows  
shows an  
accumulating error over 10 cycles, but I’m not sure if this is even a  
valid  
experiment:

import numpy as np

target\_freq = np.float64(1)  
samp\_rate = np.float64(100E6)  
two\_pi = np.float64(2\*np.pi)  
phase = np.float64(0)

cycles = 10  
phase\_inc = target\_freq/samp\_rate\*two\_pi

for cycle in range(cycles):  
samp = 0  
while samp \< samp\_rate:  
samp = samp + 1  
phase = phase + phase\_inc  
freq = phase/two\_pi/(cycle+1)  
print “The frequency over %i cycles is %.15g” % (cycle+1, freq)

#################################################

The frequency over 1 cycles is 1.00000000229562  
The frequency over 2 cycles is 1.00000000453839  
The frequency over 3 cycles is 1.00000000101206  
The frequency over 4 cycles is 0.999999995386438  
The frequency over 5 cycles is 0.999999992011064  
The frequency over 6 cycles is 0.999999989760814  
The frequency over 7 cycles is 0.999999988153493  
The frequency over 8 cycles is 0.999999986948002  
The frequency over 9 cycles is 0.999999986010398  
The frequency over 10 cycles is 0.999999985260315

–  
View this message in context:  
[http://gnuradio.4.n7.nabble.com/fxpt-nco-vs-rotator-tp51750.html](http://gnuradio.4.n7.nabble.com/fxpt-nco-vs-rotator-tp51750.html)  
Sent from the GnuRadio mailing list archive at [Nabble.com](http://Nabble.com).

---

<div class="post-metadata">

**Author:** ![madengr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ec9cab/32.png) [@madengr](https://www.ruby-forum.com/u/madengr)\
**Post date:** [December 31, 2014, 7:38am UTC](https://www.ruby-forum.com/t/fxpt-nco-vs-rotator/233647/2 "2014-12-31T07:38:43Z")

</div>

On Tue, Dec 30, 2014 at 11:55 PM, Sylvain M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> periodic renormalization process, but in any case they’re like more  
> than -130 dB down which makes them irrelevant for all but the most  
> demanding applications.
> 
> Cheers,
> 
> Sylvain

Just as an aside - and a note for other folks who want to investigate  
differences between SIMD-optimized vs. generic kernels, VOLK does have  
an  
interesting (but perhaps not well-documented) feature in that if you  
set/create an environment variable called VOLK\_GENERIC (e.g. ‘export  
VOLK\_GENERIC=1’), then the VOLK dispatcher will only call the generic  
implementation.  
This shows up in most GR and OOT QA tests automatically (at least in the  
Python-based QA tests) via the GrTest.cmake module.

Doug

---

<div class="post-metadata">

**Author:** ![madengr](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/ec9cab/32.png) [@madengr](https://www.ruby-forum.com/u/madengr)\
**Post date:** [December 31, 2014, 5:56am UTC](https://www.ruby-forum.com/t/fxpt-nco-vs-rotator/233647/3 "2014-12-31T05:56:09Z")

</div>

If you need high, deterministic, quantifiable precision, you’re  
probably better off reimplementing the critical blocks yourself the  
way you want.

Most of the default blocks will have numerous optimization for speed  
that can sacrifice precision. And this will actually depend on which  
version of the volk kernel gets selected (generic / SSE / AVX / …)  
because they use different algorithm and opcodes and such.

I’m pretty sure the rotator SIMD version has spurs because of the  
periodic renormalization process, but in any case they’re like more  
than -130 dB down which makes them irrelevant for all but the most  
demanding applications.

Cheers,

Sylvain
