[time-nuts] frequency generation algorithm.

Gabs Ricalde gsricalde at gmail.com
Wed Jun 29 00:44:49 EDT 2016


I did something similar in the Beaglebone Black AM335x PRU. Division is
done using a delay loop with variable number of cycles instead of an
interrupt. Converting a delay with a fractional amount to integer is
essentially a quantization problem. I'm using a triangular PDF dither
and first order noise shaping/error feedback ([1], last slide). The
dither randomizes the errors which should eliminate spurs. The feedback
reduces the error at DC to zero but will increase the jitter at high
frequencies. Zero error at DC means the time interval error (TIE) will
not drift. I don't have equipment to test the implementation in the BBB
so I'm just assuming it works.

The disadvantage is that you need a PRNG and do fixed point arithmetic.

I think this method is related to sigma-delta fractional-N techniques in
PLLs.

[1] Udo Zölzer, Quantization_Web_Summary.pdf
http://www.hsu-hh.de/ant/index_vNIYuPdokWfAvSaT.html

The code below is a Matlab/Octave simulation which plots the TIE and TIE
jitter spectrum.

% -------------------------------------------------------------------------
% cycle period (200 MHz)
T = 1/200e6;
% output frequency
f = 24000;
% delay in clock cycles, with fractional part
delay = 1/(f*T);
% enable/disable error feedback
feedback = true;

err = 0;
t = zeros(2048, 2);
for i = 2:2048
    % exact
    t(i,1) = t(i-1,1) + delay;

    d2 = delay - err;
    % add triangular PDF noise then quantize
    qd = floor(d2 + rand()+rand()-0.5);
    if feedback
        err = qd - d2;
    end
    % delay d3 cycles
    t(i,2) = t(i-1,2) + qd;
end
tie = t(:,1)-t(:,2);
plot(tie);
title('Time interval error (cycles)');
figure;
f = fft(tie);
f = f(1:end/2);
plot(20*log10(abs(f)));
title('TIE jitter spectrum');


More information about the time-nuts mailing list