What tones to select when testing your DAC?

This post touches upon an older post I did once (cannot find it right now).

In a sampled system, we will “suffer” from folded tones back and forth in our spectrum. For example, if we apply a 3-MHz sinusoid to a digital-to-analog converter (DAC) sampling at 10 MHz, we will get a tone at 3 MHz at the output too (luckily).

However, if there is distortion in the sampling process (notice that it has to be distortion in the components that are sampled/updated at regular basis, i.e., on the sample frequency). If we have distortion of the second and third order, we would expect to see a fundamental tone at 3 MHz and the distortion terms at 6 and 9 MHz. Due to the folding principles (well, essentially Poisson’s formula), we will also see the distortion terms coming in at 4 MHz (the second) and 1 MHz (the third).

This is not necessarily a problem, but if the tones are too close to each other, it might be difficult to isolate them properly with your test script, and if they are strong enough, the might hide some vital information wrt. the system you would like to evaluate (assume you are testing your DAC).

For example, assume you have a signal at 2.5 MHz and distortion up to fifth order, then the fifth harmonic will land right on top of your fundamental. Or why not take the classical example of displaying a fully linear DAC in your test case: use a signal frequency at a quarter of the sample frequency. All distortion terms will end up at DC, half the sample frequency (often omitted due to “clock feedthrough” or similar), and on top of the signal it self. Display the spectrum and you would have an amazingly linear converter…

Anyways, just for some inspiration. Below I show the results when I have simulated the tones that are “acceptable” under the following conditions:

  • The number of bins in your FFT is 2048
  • The order of distortion is (up to) 9
  • The number of Poisson repetitions is 100 (take ten times the order of the distortion for the fun of it).
  • The distance between two terms cannot be less than the number of bins / 32 (a “fixed” frequency makes sense here rather than something depending on the signal frequency.)

The values that are 0 indicate a poorly chosen tone/bin for your signal. So, select one of the non-zero terms and apply your ifft and voila – you have a well-behaved spectrum in which you can determine your SNDR/SFDR/THD a bit more easy.


And I am only plotting the values up to half the sample frequency. Anything above would be folded (agtain …)

4 thoughts on “What tones to select when testing your DAC?

  1. Extremely useful post for me and I made some of these mistakes initially during my measurements too. Could you throw some light in a future post about 2-tone test (IM3) and even multi-tone power tests for DACs.

    • Thanks! Please stay tuned for another post – it’s a work in progress 😉

      Notice that, in some sense (my colleague will disagree), two-tone tests are somewhat over-the-top for DAC testing. One of the reasons for testing with two-tones in an analog environment is that you want to avoid the effect of filtering out distortion terms in case you have a bandwidth limited system. For high frequencies you would thus not capture the true nonlinearity of your system.

      Therefore, in the continuous-time case, the two-tone test is useful by placing the signals close to the bandwidth frequency. The IMD terms will then appear neatly in band.

      In the DAC case – given that the distortion is generated by the sampled elements of your converter – the distortion terms will fold and you can directly calculate the IMD anyway.

      However, more on this in the other post.

  2. %
    % User: jacobw
    % Project name: stuck
    % Project area: /proj/es/shekes/stuck
    % Department of Electrical Engineering
    % Linkoping University
    % Mon Apr 15 14:38:26 CEST 2013

    % Number of samples in the FFT
    % This is vital as it indicates how many prime numbers
    % that are eligable for testing.

    NOS = 1024*2;

    DISTORDER = 7; % Should be higher than 2.

    POISORDER = 100; % Should be higher than 1.

    FREQSPAN = NOS/32;

    % Use only prime numbers to guarantee coherent sampling.
    % The sinusoid will later be generated as
    % sin(2*pi*(0:(NOS-1))*origsBins(x)/NOS)
    % effectively guaranteeing zero spectral leakage and
    % maximum code coverage (another nice feature of
    % coherent sampling).

    % So find the primes
    origsBins = primes(NOS);
    goodFreq = [];

    % Then loop over the prime numbers found in the interval
    for m = 1:length(origsBins)
    % These are positive and negative tones of the signal
    binX = [-origsBins(m) origsBins(m)];

    % Then check the distortion terms up to DISTORDER
    binD = [];
    for d = 2:DISTORDER
    binD = [binD d*binX];
    % binD will now contain a list of all positions of
    % distortion terms (in an absolute scale).
    binD = sort(binD);

    % Then check with Poisson. If distortion order is high
    % and the signal frequency close to Nyquist, the distortion terms
    % will leak over to neighbouring (and far neighbours) spectral
    % images

    % Now loop over a large set of images and combine them.
    binP = [binD];
    for p = 1:POISORDER
    binP = [binP NOS*p+binD -NOS*p+binD];
    % binP now contains a (possibly) large set of components
    % and we will sort them and find the ones that are within the
    % Nyquist range.
    binP = sort(binP);
    binP = binP(find(binP = 0));

    % Then add the original tone back to the distortion terms.
    binZ = sort([origsBins(m) binP]);

    % Now we will look for the tones close to each other.

    deltaBin = [];
    deltaBin(1) = binZ(1); % The first is the one closest (could be
    % equal) to zero.
    for k = 2:length(binZ)
    deltaBin(k) = binZ(k)-binZ(k-1);

    % Now we have to look for the frequencies that have all tones
    % separated by FREQSPAN from each other.
    goodFreq(m) = unique(min(deltaBin)) > FREQSPAN;
    % Notice that there is slight flaw as we do not compare with the
    % tones just above NOS/2 (f_sample / 2).
    % This is a quick hack though...

    % And some plotting for sake of presentation.
    stem(primes(NOS), goodFreq.*primes(NOS))
    axis([0 NOS/2 0 NOS/2])
    title('Example of "good" bins to select');
    xlabel('Bin number');
    ylabel('Good tone or not (0 = "bad")');

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.