DDS question: why sine lookup?

May 06, 2025 Last reply: 1 year ago 51 Replies

A DDS clock generator uses an NCO (a phase accumulator) and takes some number of MSBs, maps through a sine lookup table, drives a DAC and a lowpass filter and finally a comparator. The DAC output gets pretty ratty near Nyquist, and the filter smooths out and interpolates the steps and reduces jitter.



But why do the sine lookup? Why not use the phase accumulator MSBs directly and get a sawtooth, and filter that?



The lowpass filter looks backwards in time for a bunch of ugly samples to average into a straight line. The older sine samples are the wrong polarity! If the filter impulse response is basically zero over the period of the sawtooth, and we compare near the peak, we'll average a lot of steps and forget the big sawtooth reset.



I want to make four programmable clocks and don't want to buy DDS chips. So use a cheap FPGA and a few resistors as the DAC. Synthesize one octave and divide down for lower frequencies. Gotta sim that.



LT Spice really sucks with digital stuff. Building a phase accumulator would be a horror. I'm working on a PowerBasic program that can dump waveforms to a PWL file that LT Spice can import and filter. Qspice would be better but I'd have to learn that and hack the phase accumulator in c.


Two things are immediately obvious: First, the sawtooth will have a variable frequency, and the filter won't have a zero response for all possible frequencies.

Second, the usual reconstruction filters do *not* interpolate into straight lines.

Beyond that, I would have to think this over a bit more.

Jeroen Belleman

Am 06.05.25 um 17:48 schrieb john larkin:

Spice was made for solving systems of differential equations with some semantic sugar added, but it was never intended as a digital simulator. Yes, you can abuse it but the simulation drowns in details that no one is interested in. The right tools would be Modelsim/Questasim/GHDL or <

formatting link
>

I did publish a DDS in VHDL. It's on opencores.org under arithmetic named sincos. The number of pipeline stages, log table dimensions etc can be set at will; bus sizes auto-adjust to the busses that are attached. Mirroring of the sine table is also automatic. sin and cos are available at the same time without requiring more hardware.

The only thing that's missing is Sunderland's lookup table optimization that decomposes the ROM into two and gets a

10...50 times reduction in ROM size. I did not need it and its added delay was not welcome in my PLL application. <
formatting link
>

On a Spartan 6 eval board it runs at 200 MHz out of the box.

Cheers, Gerhard

Sure, the point of DDS is to generate a high-resolution (and low jitter) clock.

Seems to me that what we want the filter to do is make the best-possible-fit straight line, a linear ramp, out of the sawtooth made from nasty DAC steps. But we need to ignore the giant sharp edge of the sawtooth, which would cause a bunch of jitter. So the impulse response of the filter has to go to zero after, say, 3/4 of the sawtooth time, to forget that big jump.

I'm thinking in time domain about making a low-jitter DDS clock. There are a zillion papers that analyze this in the frequency domain.

We've sold a lot of these

formatting link
but it's old and it's hard to find parts. It uses four expensive parallel-input ADI DDS chips to make the clocks. I was thinking about making my own DDS with an FPGA and some home-made DACs.

I don't need RF spectral purity. I'm simulating rotating machines, so nobody will notice a couple nanoseconds of jitter.

<snip>

^^^^^^^^^^^^^^^^^^^

Artful alliteration acknowledgement - attaboy!

formatting link

Thank you for sharing.

Danke,

Even better is no sinewave lookup!

I'm thinking that I could run at 80 MHz and generate an octave from 10 to 20. It would be great to clock at 160 MHz. I probably have to clock at a multiple of 40 for strict backward compatibility to the old product.

But after the DDS math we still need a DAC and an analog lowpass filter and a comparator and some jitter analysis, which are Spice territory.

Looks like a plain vanilla Bessel filter would be good to smooth an ugly stepwise sawtooth.

You don't want to use a sawtooth if you can help it, because it has huge contributions from all harmonic orders. It also puts a lot of demands on the slew rate and settling of the DAC and any amplifiers used in the filtering. Errors there are of course nonlinear, because once an amp is in slew limiting, it stops responding to its inputs for a bit.

It also emphasizes the close-in spurs. Say you have two N-bit DDSes running at the same average frequency but different phases. The DAC samples only the M high-order bits. It happens that at time t=0 the accumulator overflows on the same clock cycle on both.

This will continue to happen until one of them overflows a cycle early because the bottom N-M bits rolled over.

The resulting voltage difference between them is a full-scale, one-clock-wide pulse, followed by a noisy baseline as the bottom N-M bits roll over into the DAC's LSB at different times. This will repeat every cycle until the other DDS catches up. This scenario will play out some number of times in a full period, i.e. the least common multiple of the accumulator size and the increment in clocks.

The energy in that glitch is much larger than in the noisy baseline, and its timing is variable in complicated ways.

A triangle would be better, and of course that could be done pretty simply, e.g. with a flip flop controlling a bunch of XOR gates, if you don't mind halving the frequency.

Once you have a lookup table, a sine is as easy as anything else, and minimizes the demands on the DAC, filters and amplifiers.

Cheers

Phil Hobbs

I was thinking that my DAC is just 5 or 6 resistors hanging off some FPGA pins, and that drives a 3rd order (CLC) LC filter and the comparator. So no opamps.

If I'm using, say, 8 MS phase accumulator bits and a 5-bit DAC and synthesizing one octave of frequency, the sine table is no big deal.

256 bytes of RAM per DDS unfolded.

I've been playing with sims. The sawtooth works OK but may be too cute. I'll compare it to sines.

The pseudo-DAC output is always positive. It can go into one comparator input and I can RC lowpass filter same into the other, to switch on the waveform midpoint.

I reall need to get my FPGA kids to run the phase accumulator at 160 MHz. Run way below Nyquist.

Because the sawtooth has much the same harmonic content as a triangular wave, all the odd harmonics (up to the speed of the switches involved) at amplitudes that decrease as the square of the harmonic number

But they are delayed as they go through the low pass filter, and that gets the polarity right, if you use a linear phase low pass filter, which doesn't have a sharp cut-off.

Read Williams and Taylor's "Electronic Filer Design Handbook". I've got the second edition - ISBN 0-07-070434-1 - and the third - 0-07-070430-9

- on my Kindle.

You can simulate that in LTSpice, whic is safer than hand-waving speculation.

Trading off development time against parts cost. The Analog Devices development engineers have had longer to get their design right than you will have, so their end result may be more nearly perfect.

Good idea.

Since you don't need to simulate the digital stuff, LTSpice will work fine. Getting the PWL file to simulate the phase accumulator output may be a chore, but google might find one for you.

Can't you fold the LIN to SIN conversion in the resistor values?

Arie

I don't know. I can buy a small cheap R-2R resistor network, and a 8-8 bit sine lookup is easy in an FPGA.

Resistors are linear and sine is nonlinear.

I'm Spicing things and what I'm seeing in the FFT of my DAC output, with the sawtooth, is giant subharmonics at some magic frequencies. Those contribute the most period jitter.

May as well use a sine, I guess. Still, my sim tools are useful in tweaking the detais: NCO clock rate, lookup table size, DAC bits, filter order. I have several products in design that need DDS clocks, so some time playing with this is worth it. And it's interesting.

My Basic program generates a PWL file, given choices of clock rates, bits, and waveform. I can import that to LT Spice and take over with filtering and such. If I just output the obvious steps to the PWL file, Spice will draw straight lines between points and it looks awful. I want DAC steps. The fix is to output each point twice, suitably spaced.

My FPGA guys say that an Efinix T55 can run a 48-bit phase accumulator at 280 MHz. Yikes. One $10 T20 could make a dozen DDS's.

Right, those are the nasty ones I'm talking about. They're smaller with a sine output, because the nasty tall spike (which contributes power quadratically) isn't there. They're closer in and much smaller with higher resolution DACs, and go away entirely when the DAC has the full resolution of the accumulator, because what you have then is a correctly sampled sine wave.

You could synthesize more cow bell that way.

Cheers

Phil Hobbs

You really ought to find out. Hanging resistors on successive taps of a shift register creates a Finite Impulse Response Filter. You have to taper the resistor values with a Hamming window to avoid Gibbs oscillations - I found out about that the hard way, but it isn't difficult.

You can certainly use one to convert a square wave into a pretty good approximation to a sine wave.

It doesn't lend itself to non-integer frequency division.

I ended up having to use 10ppm 0.1% E96 resistors, and the more critical to get each resistance sufficiently correct, but I used a fairly long shift register. I was quite fond of the female bat acoustician I put the gear together for, and went in for a bit of over-kill.

Not a relevant point.

Seems unlikely to be true. A DAC synthesises a staircase approximation to a sine wave, where the individual steps can be seen as sawtooth elements added onto the sine wave. The imperfections of the DAC make each little sawtooth a bit different from the next in amplitude, and the fact that the sine wave has a variable slope means that each sawtooth element has a different period.

They can't go away entirely. You can filter them out pretty effectively

<snip>

A saw tooth wave has a huge step like discontinuity in it which looks very ugly in the frequency domain with strong harmonics. Strong sharp features in time domain are broad in frequency space and vice versa.

If you wanted something a bit different then detecting the phase accumulator overflow and reversing the count sense to get a triangle wave might be an option (at half the frequency). Needs some very careful maths at the boundary flips to avoid introducing jitter.

From that triangle wave you can use HP's wizard diode shaping network trick to get a pretty good clean sine wave.

Yes, a triangle would be better than a sawtooth... fewer nasty subharmonics. But we may as well stick with the classic boring sine wave. The sine lookup is trivial in an FPGA.

A band-limited square wave is pretty space & computation-efficient, you just store the Gibbs phenomena portion of the wave to whatever harmonic level you desire, play it back, and then sit there and wait during the DC parts of the wave.

If you then integrate a band-limited square wave you get a band-limited triangle wave directly.

If I could make a square wave from the MSBs of the phase accumulator, I might not need the DAC and filter and comparator.

Just using the MSB of the phase accumulator is the right frequency, but it's very jitterey.

So, is there a way to examine some number of MSBs and make an edge with high time resolution, all digitally, all inside the FPGA? To even

1 clock resolution, preferably better?

There probably is.

The existence of Direct Digital Synthesis chips is pretty convincing evidence that there isn't. If you can't do it an application specific integrated circuit, you aren't going to be able to do it an FPGA.

Creating a sine wave lets you work with not-perfectly-integral divisors, with a low pass filter to smooth out the residual discontinuities. A Bessel linear phase low pass filter is apparently the preferred choice. The second editions of Williams and Taylor list up to 10th order in table 11-43, and two equiripple close approximations in tables 11-44 and

11-45.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required