DDS question: why sine lookup?...

On 07/05/2025 21:01, john larkin wrote:
On Wed, 7 May 2025 20:32:41 +0100, Martin Brown
\'\'\'newspam\'\'\'@nonad.co.uk> wrote:

On 06/05/2025 16:48, john larkin wrote:
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?

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.

Actually that suggests to me a bonkers way to do it with an analogue
multiplier and a flipflop to fiddle the phase. Generate two waveforms
from the phase accumulator MSB one rising and one falling. PHACC and ~PHACC.

Multiply the two sawtooth waves together in an analogue multiplier and
then you get a nice parabolic approximation to half a sine wave.

/|/|/|/|/| x \\|\\|\\|\\| = .o.o.o.o

Then flip alternate half cycles negative with your crude square wave.

--
Martin Brown
 
On Fri, 9 May 2025 04:48:33 -0000 (UTC), piglet
<erichpwagner@hotmail.com> wrote:

Phil Hobbs <pcdhSpamMeSenseless@electrooptical.net> wrote:
john larkin <jl@glen--canyon.com> wrote:
On Thu, 8 May 2025 22:28:40 -0000 (UTC), Phil Hobbs
pcdhSpamMeSenseless@electrooptical.net> wrote:

john larkin <jl@glen--canyon.com> wrote:
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs
pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil Hobbs
pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <user@example.net> wrote:

On 5/7/2025 4:01 PM, john larkin wrote:
On Wed, 7 May 2025 20:32:41 +0100, Martin Brown
\'\'\'newspam\'\'\'@nonad.co.uk> wrote:

On 06/05/2025 16:48, john larkin wrote:
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?

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.




Don\'t think so. Since you have exactly two edges per cycle, it would
have the same problem as the sawtooth, for the same reason. You could
interpolate the same sort of way as in a DDG.

Cheers

Phil Hobbs

If some N bits can be sent to a DAC and a filter, to interpolate to
better time accuracy than just using the MS bit, then the equivalent
interpolation should be possible digitally, inside the FPGA.

We can always spin up a PLL to get as fast a clock as the logic can
stand. And sub-clock tricks have been done.

You still have the giant spike between the actual position of the edge
and where it ought to be for a subharmonic-free signal. That\'s less
than one clock wide, so there\'s no way to get rid of it digitally. You
could maybe do some noise shaping thing to put the subharmonics
someplace else, but unless your increment is a factor of 2**(accumulator
width), they\'ll be there.

A full-width DAC, followed by a brickwall lowpass, followed by a
comparator, will get rid of the subharmonics, as would a ramp/threshold
analog delay calculated on a per-cycle basis.

Cheers

Phil Hobbs

We could take the phase accumulator \"dac\" MSBs and stuff them into a
brickwall digital lowpass filter, maybe even do the sine mapping
first. The result would be a wide smooth waveform, similar to what the
analog comparator would see, only digital. The zero cross of that
would be our \"DDS comparator output\" clock, to one system clock
quantization. Going to half clock resolution wouldn\'t be hard.

If the phase accumulator clock is 160 MHz, half a clock gives us 3 ns
p-p jitter, and the RMS jitter is 900 ps. (Why square root of 12? We
live in a strange universe.)

That filter logic could be clocked faster than the phase accumulator
clock too. Some crazy PLL rate.

I don\'t want to drive a bunch of 20-bit parallel DACs, or make some
13-pole LC filters, but bits are cheap inside an FPGA.

We know what the output frequency will be, so the digital filter can
be tuned for that. Maybe a narrow bandpass? Kills subharmonics?

Some truly terrible things have been done in FPGAs to get picosecond
resolution delays and time interval measuring.

Sounds like a good senior project.



If the output frequency is known in advance, all ought to be
straightforward?pick a clock frequency that?s an integer multiple.

One VCXO-based PLL should be able to make that.

Cheers

Phil Hobbs

The gadget\'s output frequency is known when the user programs it, not
years in advance. When we know the frequency we have to do the math to
program the Fset register over our octave range, and program a
downstream divisor (for, say, a 12 Hz trigger rate) so we have time to
program a digital filter too.

An 8-bit R-2R network and a modest LC filter and an LVDS buffer as a
comparator isn\'t awful, but getting the entire DDS system inside the
FPGA would be cool.

I did consider having a fixed frequency clock and a divisor as our
internal trigger source, and telling the user he has to live with
Fxo/N as the possible choices, but even I have my limits of tackiness.





The difference between adjacent magic increments isn’t that large, at least
at lowish frequencies. It might well be possible to dork the clock to get
to the nearest one.

FPGAs have PLLs too, low GHz range, which can be programmed to be K
times our 40 MHz XO, for modest values of K. Then one can divide
down, not always by a freely chosen divider... often with a
first-stage divider of small N... some sort of ring counter maybe.

Lots of nasty number theory.


Cheers

Phil Hobbs


Yes. Surely these are lowish frequencies as early on in the discussion JL
said all this was to simulate rotating machines?

Yes. The existing product has a user-programmable clock up to 15 MHz,
all the expensive ADI DDS chip would do. With the maximum size
waveform table (65K points) the output waveform rate is 229 Hz. The
thing is due for redesign, and we\'d like to go faster on the clock, 20
MHz at least, preferably more.

https://highlandtechnology.com/Product/V375

Arbs are plentiful and cheap, but this one was designed specifically
to simulate geared rotating machines.
 
On Wed, 7 May 2025 20:27:58 -0400, bitrex wrote:

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

If you’re going to do it with integral/differential equations, why not
solve an SHM system and get a sine wave directly?
 
On 10/05/2025 5:53 am, john larkin wrote:
On Fri, 9 May 2025 04:48:33 -0000 (UTC), piglet
erichpwagner@hotmail.com> wrote:

Phil Hobbs <pcdhSpamMeSenseless@electrooptical.net> wrote:
john larkin <jl@glen--canyon.com> wrote:
On Thu, 8 May 2025 22:28:40 -0000 (UTC), Phil Hobbs
pcdhSpamMeSenseless@electrooptical.net> wrote:

john larkin <jl@glen--canyon.com> wrote:
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs
pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil Hobbs
pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <user@example.net> wrote:

On 5/7/2025 4:01 PM, john larkin wrote:
On Wed, 7 May 2025 20:32:41 +0100, Martin Brown
\'\'\'newspam\'\'\'@nonad.co.uk> wrote:

On 06/05/2025 16:48, john larkin wrote:

<snip>

The difference between adjacent magic increments isn’t that large, at least
at lowish frequencies. It might well be possible to dork the clock to get
to the nearest one.

FPGAs have PLLs too, low GHz range, which can be programmed to be K
times our 40 MHz XO, for modest values of K. Then one can divide
down, not always by a freely chosen divider... often with a
first-stage divider of small N... some sort of ring counter maybe.

Lots of nasty number theory.

The catch with a VCO inside an FPGA is going to be the ripple on the
supply voltages inside the FPGA.

Its output will have appreciable jitter. The charm of the Phil Hobbs
VCXO is that it will be a low jitter source - probably at the
pico-second level

Yes. Surely these are lowish frequencies as early on in the discussion JL
said all this was to simulate rotating machines?

Yes. The existing product has a user-programmable clock up to 15 MHz,
all the expensive ADI DDS chip would do.

You couldn\'t do that with Phil Hobbs VCXO as your VCO. A 150MHz VXCO
would limit you about 15hHz, which is probably all that your customers need.
Giving then a lot more than they need always makes the salesmen happy,
but it doesn\'t do anything for the customer.

With the maximum size
waveform table (65K points) the output waveform rate is 229 Hz. The
thing is due for redesign, and we\'d like to go faster on the clock, 20
MHz at least, preferably more.

https://highlandtechnology.com/Product/V375

Arbs are plentiful and cheap, but this one was designed specifically
to simulate geared rotating machines.

So optimise it for the frequencies they want, and chop the performance
in areas they won\'t use.

--
Bill Sloman, Sydney
 
On 5/9/25 21:53, john larkin wrote:
Yes. The existing product has a user-programmable clock up to 15 MHz,
all the expensive ADI DDS chip would do. With the maximum size
waveform table (65K points) the output waveform rate is 229 Hz. The
thing is due for redesign, and we\'d like to go faster on the clock, 20
MHz at least, preferably more.

https://highlandtechnology.com/Product/V375

Arbs are plentiful and cheap, but this one was designed specifically
to simulate geared rotating machines.

then is a the few ns of jitter with the clock rate you could get with an
FPGA really much of an issue, isn\'t that still way better than what
you\'d expect from the real sensors on a rotating assembly?
 
On Sat, 10 May 2025 19:52:48 +0200, Lasse Langwadt <llc@fonz.dk>
wrote:

On 5/9/25 21:53, john larkin wrote:
Yes. The existing product has a user-programmable clock up to 15 MHz,
all the expensive ADI DDS chip would do. With the maximum size
waveform table (65K points) the output waveform rate is 229 Hz. The
thing is due for redesign, and we\'d like to go faster on the clock, 20
MHz at least, preferably more.

https://highlandtechnology.com/Product/V375

Arbs are plentiful and cheap, but this one was designed specifically
to simulate geared rotating machines.

then is a the few ns of jitter with the clock rate you could get with an
FPGA really much of an issue, isn\'t that still way better than what
you\'d expect from the real sensors on a rotating assembly?

Yes, real machines vibrate and shake and all that. And the
position/rotation sensors aren\'t great either, usually magnetic things
that look like spark plugs, near gear teeth.

Nobody would notice a few ns of RMS jitter.

But if I can come up with a good cheap rate generator, we can use it
on other products, like our PPG precision pulse generator. Low period
jitter would be a feature on that one.

Looks like the best way is logic in the FPGA doing classic sine DDS,
maybe 6 or 8 output pins driving an R-2R network, a 3 or 5-pole
Chebyshev LC filter, and an LVDS receiver as the comparator.

It never hurts to be confused for a while, and consider possibilities.
I\'m a great fan of silly ideas and confusion.

One could parallel resonate one of the inductors in the 5-pole filter,
to make a sort of elliptical Chevyshev.
 
In article <ad7v1kttjfhjulnameem9ta8gjst5cpa45@4ax.com>,
john larkin <jl@glen--canyon.com> wrote:

Looks like the best way is logic in the FPGA doing classic sine DDS,
maybe 6 or 8 output pins driving an R-2R network, a 3 or 5-pole
Chebyshev LC filter, and an LVDS receiver as the comparator.

Be wary of that approach.

I tried something like it (sans comparator), while using a simple FPGA
to generate a (modulated) 10.7 MHz IF signal for an FM-stereo test
generator. The results were ungood.

The output waveform had some pretty horrible glitches, at the times of
the transitions between values. There\'s enough variation in delay in
the signal paths inside the FPGA to create a significant (in
picoseconds and nanoseconds) delay between the transition times of the
R2R bits. If you\'re trying to go from (for example) 0x7F to 0x81,
your MSB is going to be transitioning high when most of your LSBs are
transitioning low. There\'s very likely to be a brief moment of time
when the effective value is 0xFF (if the MSB transitions first) or
0x00 (if it transitions last), or some random and unpredictable and
ever-changing mix of bits. The resulting spikes are narrow, but can
have a pretty fierce amplitude to them.

As a result, unless your LC filter is extremely sharp, your
receiver/comparator is likely to generate occasional runt pulses,
or skew the zero-crossing time by one or more sample (adding jitter).

To make this scheme work, you really need to re-time the values going
into the R2R ladder to ensure near-as-gosh identical timing... some
form of very predictable latch with guaranteed low skew between the
pins. The normal FPGA data path probably won\'t do this for you. I
tried using the FPGA\'s own internal registered-output logic (driving
all of the latch clocks from the same internal signal) but even this
wasn\'t good enough... the internal propagation times were not zero,
alas :-( due to that cursed light-speed limit.

I switched over to using an Analog Devices DDS, shifting a new value
out into it from the FPGA via a serial interface once per sample time.
Far, far cleaner RF/IF as a result.

You could get a fairly clean 3-bit-equivalent output, using 8 pins and
8 equal-value resistors, and encoding things so that transitions are
always \"change one or more bits from 0 to 1\" or \"change 1 or more bits
from 1 to 0\".
 
On Tue, 06 May 2025 08:48:29 -0700, john larkin <jl@glen--canyon.com>
wrote:

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.

How about this?

https://www.dropbox.com/scl/fi/wefcwnm5zo70agmbsu88l/FPGA_DDS.jpg?rlkey=smexzxzd1j8o91752tw59jdas&raw=1

I only need to synthesize one octave, so I really want a bandpass
filter to chop out all the low frequency crud, especially junk from
the 3.3v supply.

R1C1 sets the comparator threshold to be the midpoint of the sine
wave. If its time constant is short, it provides some useful bandpass
effect too.

I can use a 3-pole filter in apps where a little jitter is OK.
 
On Sat, 10 May 2025 16:50:03 -0700, dplatt@coop.radagast.org (Dave
Platt) wrote:

In article <ad7v1kttjfhjulnameem9ta8gjst5cpa45@4ax.com>,
john larkin <jl@glen--canyon.com> wrote:

Looks like the best way is logic in the FPGA doing classic sine DDS,
maybe 6 or 8 output pins driving an R-2R network, a 3 or 5-pole
Chebyshev LC filter, and an LVDS receiver as the comparator.

Be wary of that approach.

I tried something like it (sans comparator), while using a simple FPGA
to generate a (modulated) 10.7 MHz IF signal for an FM-stereo test
generator. The results were ungood.

A good filter and a comparator could help, as in \"FM Capture Effect.\"


The output waveform had some pretty horrible glitches, at the times of
the transitions between values. There\'s enough variation in delay in
the signal paths inside the FPGA to create a significant (in
picoseconds and nanoseconds) delay between the transition times of the
R2R bits. If you\'re trying to go from (for example) 0x7F to 0x81,
your MSB is going to be transitioning high when most of your LSBs are
transitioning low. There\'s very likely to be a brief moment of time
when the effective value is 0xFF (if the MSB transitions first) or
0x00 (if it transitions last), or some random and unpredictable and
ever-changing mix of bits. The resulting spikes are narrow, but can
have a pretty fierce amplitude to them.

As a result, unless your LC filter is extremely sharp, your
receiver/comparator is likely to generate occasional runt pulses,
or skew the zero-crossing time by one or more sample (adding jitter).

To make this scheme work, you really need to re-time the values going
into the R2R ladder to ensure near-as-gosh identical timing... some
form of very predictable latch with guaranteed low skew between the
pins. The normal FPGA data path probably won\'t do this for you. I
tried using the FPGA\'s own internal registered-output logic (driving
all of the latch clocks from the same internal signal) but even this
wasn\'t good enough... the internal propagation times were not zero,
alas :-( due to that cursed light-speed limit.

We\'d at least retime the 8 outputs in output latches, in the same
region.

I switched over to using an Analog Devices DDS, shifting a new value
out into it from the FPGA via a serial interface once per sample time.
Far, far cleaner RF/IF as a result.

You could get a fairly clean 3-bit-equivalent output, using 8 pins and
8 equal-value resistors, and encoding things so that transitions are
always \"change one or more bits from 0 to 1\" or \"change 1 or more bits
from 1 to 0\".

I could buy an official clocked 8-bit DAC with a data latch. Some have
great glitch specs (and some are horrible.)

Parallel-load DDS chips are expensive, and serial interfaces are too
slow. And I\'d like to allow for phase coherence between clocks on the
multichannel gadget.

Maybe some not-literally-sine waveform could have less glitches.

This is all interesting but potentially time consuming. I might add
some delays, like to the MSB, to my Spice model and see what happens.

If I have a project with an FPGA and a little spare room, I could try
the R-2R thing as an experiment.
 
On 11/05/2025 9:50 am, Dave Platt wrote:
In article <ad7v1kttjfhjulnameem9ta8gjst5cpa45@4ax.com>,
john larkin <jl@glen--canyon.com> wrote:

Looks like the best way is logic in the FPGA doing classic sine DDS,
maybe 6 or 8 output pins driving an R-2R network, a 3 or 5-pole
Chebyshev LC filter, and an LVDS receiver as the comparator.

Be wary of that approach.

I tried something like it (sans comparator), while using a simple FPGA
to generate a (modulated) 10.7 MHz IF signal for an FM-stereo test
generator. The results were ungood.

The output waveform had some pretty horrible glitches, at the times of
the transitions between values. There\'s enough variation in delay in
the signal paths inside the FPGA to create a significant (in
picoseconds and nanoseconds) delay between the transition times of the
R2R bits. If you\'re trying to go from (for example) 0x7F to 0x81,
your MSB is going to be transitioning high when most of your LSBs are
transitioning low. There\'s very likely to be a brief moment of time
when the effective value is 0xFF (if the MSB transitions first) or
0x00 (if it transitions last), or some random and unpredictable and
ever-changing mix of bits. The resulting spikes are narrow, but can
have a pretty fierce amplitude to them.
One approach that might help, but isn\'t going to be all that cheap,
would be to latch the digital information coming out of the FPGA into
something like an ECLinPS latch which has very fast internal logic and
rather less variation in propagation delay between the clock edge going
into the ECLinPS latch and the output edges of the data outputs.

The other advantage is that ECL is current steering logic, so the latch
rails are a lot clean than the rails inside the FPGA and the nominally
unchanged edges aren\'t going to move as much.

--
Bill sloman. Sydney
 
On 5/11/25 08:55, Bill Sloman wrote:
On 11/05/2025 9:50 am, Dave Platt wrote:
In article <ad7v1kttjfhjulnameem9ta8gjst5cpa45@4ax.com>,
john larkin  <jl@glen--canyon.com> wrote:

Looks like the best way is logic in the FPGA doing classic sine DDS,
maybe 6 or 8 output pins driving an R-2R network, a 3 or 5-pole
Chebyshev LC filter, and an LVDS receiver as the comparator.

Be wary of that approach.

I tried something like it (sans comparator), while using a simple FPGA
to generate a (modulated) 10.7 MHz IF signal for an FM-stereo test
generator.  The results were ungood.

The output waveform had some pretty horrible glitches, at the times of
the transitions between values.  There\'s enough variation in delay in
the signal paths inside the FPGA to create a significant (in
picoseconds and nanoseconds) delay between the transition times of the
R2R bits.  If you\'re trying to go from (for example) 0x7F to 0x81,
your MSB is going to be transitioning high when most of your LSBs are
transitioning low.  There\'s very likely to be a brief moment of time
when the effective value is 0xFF (if the MSB transitions first) or
0x00 (if it transitions last), or some random and unpredictable and
ever-changing mix of bits.  The resulting spikes are narrow, but can
have a pretty fierce amplitude to them.
One approach that might help, but isn\'t going to be all that cheap,
would be to latch the digital information coming out of the FPGA into
something like an ECLinPS latch which has very fast internal logic and
rather less variation in propagation delay between the clock edge going
into the ECLinPS latch and the output edges of the data outputs.

The other advantage is that ECL is current steering logic, so the latch
rails are a lot clean than the rails inside the FPGA and the nominally
unchanged edges aren\'t going to move as much.

at that point you might as well get a real DAC, there\' quite a few cheap
triple 8-10bit +200MHz DACs mean for video

like
https://www.lcsc.com/product-detail/Digital-to-Analog-Converters-DAC_HTCSEMI-HT7123ARQZ_C2886392.html
 
On 2025-05-10 20:39, john larkin wrote:
On Sat, 10 May 2025 16:50:03 -0700, dplatt@coop.radagast.org (Dave
Platt) wrote:

In article <ad7v1kttjfhjulnameem9ta8gjst5cpa45@4ax.com>,
john larkin <jl@glen--canyon.com> wrote:

Looks like the best way is logic in the FPGA doing classic sine DDS,
maybe 6 or 8 output pins driving an R-2R network, a 3 or 5-pole
Chebyshev LC filter, and an LVDS receiver as the comparator.

Be wary of that approach.

I tried something like it (sans comparator), while using a simple FPGA
to generate a (modulated) 10.7 MHz IF signal for an FM-stereo test
generator. The results were ungood.

A good filter and a comparator could help, as in \"FM Capture Effect.\"

The capture effect forces the rate of zero crossings at the output of
the limiting stage to equal that of the strongest input signal.
Interfering signals near the same frequency can change their position,
but not their number, and this is true on a cycle-by-cycle basis.
Phase modulation is preserved in the process, of course.


The output waveform had some pretty horrible glitches, at the times of
the transitions between values. There\'s enough variation in delay in
the signal paths inside the FPGA to create a significant (in
picoseconds and nanoseconds) delay between the transition times of the
R2R bits. If you\'re trying to go from (for example) 0x7F to 0x81,
your MSB is going to be transitioning high when most of your LSBs are
transitioning low. There\'s very likely to be a brief moment of time
when the effective value is 0xFF (if the MSB transitions first) or
0x00 (if it transitions last), or some random and unpredictable and
ever-changing mix of bits. The resulting spikes are narrow, but can
have a pretty fierce amplitude to them.

As a result, unless your LC filter is extremely sharp, your
receiver/comparator is likely to generate occasional runt pulses,
or skew the zero-crossing time by one or more sample (adding jitter).

To make this scheme work, you really need to re-time the values going
into the R2R ladder to ensure near-as-gosh identical timing... some
form of very predictable latch with guaranteed low skew between the
pins. The normal FPGA data path probably won\'t do this for you. I
tried using the FPGA\'s own internal registered-output logic (driving
all of the latch clocks from the same internal signal) but even this
wasn\'t good enough... the internal propagation times were not zero,
alas :-( due to that cursed light-speed limit.

We\'d at least retime the 8 outputs in output latches, in the same
region.

That\'ll help, but even in the ideal case, the DDS spur amplitude will be
20*log(2**6) = 36 dB worse than with a 14-bit DAC output.

I switched over to using an Analog Devices DDS, shifting a new value
out into it from the FPGA via a serial interface once per sample time.
Far, far cleaner RF/IF as a result.

You could get a fairly clean 3-bit-equivalent output, using 8 pins and
8 equal-value resistors, and encoding things so that transitions are
always \"change one or more bits from 0 to 1\" or \"change 1 or more bits
from 1 to 0\".

Some years ago, we had a long and informative discussion about that in a
thread started by the late lamented George Herold. (I don\'t mean that
he\'s passed on, just that we very rarely see him in these hallowed
halls.) A 74HC4017 and 10 resistors made a sine wave approximation that
nulled out the second through tenth harmonics, iirc. Didn\'t do anything
about phase modulation on the clock.

I could buy an official clocked 8-bit DAC with a data latch. Some have
great glitch specs (and some are horrible.)

Parallel-load DDS chips are expensive, and serial interfaces are too
slow. And I\'d like to allow for phase coherence between clocks on the
multichannel gadget.

Maybe some not-literally-sine waveform could have less glitches.

This is all interesting but potentially time consuming. I might add
some delays, like to the MSB, to my Spice model and see what happens.

If I have a project with an FPGA and a little spare room, I could try
the R-2R thing as an experiment.

Cheers

Phil Hobbs


--
Dr Philip C D Hobbs
Principal Consultant
ElectroOptical Innovations LLC / Hobbs ElectroOptics
Optics, Electro-optics, Photonics, Analog Electronics
Briarcliff Manor NY 10510

http://electrooptical.net
http://hobbs-eo.com
 
In sci.electronics.design john larkin <jl@glen--canyon.com> wrote:
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.

Sine is close to optimal for high quality DDS. The math is
as follows. First, your DAC has some response in time
domain, but for purpose of computation one can assume that
at clock tick number n it generates delta peak centered
at nT_0 with amplitude f(nT_0/T_1) where f is function stored in
lookup table, T_0 is period of digital clock and T_1 is desired
period. Mathematically

S(t) = \\sum_n f(nT_0/T_1)\\delta(t - nT_0) = \\sum_n f(t/T_1)\\delta(t - nT_0)

where summation is over all integer n.

Fourier transform of this is

C\\sum_l \\sum_m c_l \\delta(\\omega - 2m\\pi/T_0 - 2l\\pi/T_1)

where we have double summation over integer l and m, c_l is
l-th Fourier coefficient of f and C is a constant.
Sine has only 2 Fourier components, so formula simplifies to

(1/2)C\\sum_m (\\delta(\\omega - 2m\\pi/T_0 - 2\\pi/T_1) +
\\delta(\\omega - 2m\\pi/T_0 + 2\\pi/T_1))

With aggressive filtering high freqency components can be
made arbitrarily small, so after filter Fourier transform
is

(M/2)C(\\delta(\\omega - 2\\pi/T_1) + \\delta(\\omega+ 2\\pi/T_1)) +
small distortion

where M represents transmitance of the filter at frequency
1/T_1. Back in time domain signal is

M\\sin(t) + small distortion

The point is that distortion, hence phase noise can be made
arbitrarily small.

What happens with different f? When T_0/T_1 is irrational,
the sum 2m\\pi/T_0 + 2l\\pi/T_1 can take values arbitrarily
close to 0. In particular, there will be combinations of
l and m such that this sum is in the interval [-\\pi/T_1, \\pi/T_1],
so we will get low frequency terms with wrong frequency.
Assuming fixed low pass filter such terms can not be filered
out. How bad this is? For sawtooth the second Fourier
coefficient has maginitude equal to half of the magnitude
of the first coefficient, so one can expect distortion
of order 50%, which looks quite bad. Using symmetric
troangular weave, second Fourier coefficient is 0 and
third has magnitude 1/9 of magnitude of the first
coefficient, which is much better, but still limits
possible quality.


--
Waldek Hebisch
 
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <jl@glen--canyon.com> wrote:
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.

Sine is close to optimal for high quality DDS. The math is
as follows. First, your DAC has some response in time
domain, but for purpose of computation one can assume that
at clock tick number n it generates delta peak centered
at nT_0 with amplitude f(nT_0/T_1) where f is function stored in
lookup table, T_0 is period of digital clock and T_1 is desired
period. Mathematically

S(t) = \\sum_n f(nT_0/T_1)\\delta(t - nT_0) = \\sum_n f(t/T_1)\\delta(t - nT_0)

where summation is over all integer n.

Fourier transform of this is

C\\sum_l \\sum_m c_l \\delta(\\omega - 2m\\pi/T_0 - 2l\\pi/T_1)

where we have double summation over integer l and m, c_l is
l-th Fourier coefficient of f and C is a constant.
Sine has only 2 Fourier components, so formula simplifies to

(1/2)C\\sum_m (\\delta(\\omega - 2m\\pi/T_0 - 2\\pi/T_1) +
\\delta(\\omega - 2m\\pi/T_0 + 2\\pi/T_1))

With aggressive filtering high freqency components can be
made arbitrarily small, so after filter Fourier transform
is

(M/2)C(\\delta(\\omega - 2\\pi/T_1) + \\delta(\\omega+ 2\\pi/T_1)) +
small distortion

where M represents transmitance of the filter at frequency
1/T_1. Back in time domain signal is

M\\sin(t) + small distortion

The point is that distortion, hence phase noise can be made
arbitrarily small.

What happens with different f? When T_0/T_1 is irrational,
the sum 2m\\pi/T_0 + 2l\\pi/T_1 can take values arbitrarily
close to 0. In particular, there will be combinations of
l and m such that this sum is in the interval [-\\pi/T_1, \\pi/T_1],
so we will get low frequency terms with wrong frequency.
Assuming fixed low pass filter such terms can not be filered
out. How bad this is? For sawtooth the second Fourier
coefficient has maginitude equal to half of the magnitude
of the first coefficient, so one can expect distortion
of order 50%, which looks quite bad. Using symmetric
troangular weave, second Fourier coefficient is 0 and
third has magnitude 1/9 of magnitude of the first
coefficient, which is much better, but still limits
possible quality.


Distortion and phase noise are only obliquely related.

Cheers

Phil Hobbs


--
Dr Philip C D Hobbs
Principal Consultant
ElectroOptical Innovations LLC / Hobbs ElectroOptics
Optics, Electro-optics, Photonics, Analog Electronics
Briarcliff Manor NY 10510

http://electrooptical.net
http://hobbs-eo.com
 
On Tue, 13 May 2025 20:22:09 -0400, Phil Hobbs
<pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <jl@glen--canyon.com> wrote:
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.

Sine is close to optimal for high quality DDS. The math is
as follows. First, your DAC has some response in time
domain, but for purpose of computation one can assume that
at clock tick number n it generates delta peak centered
at nT_0 with amplitude f(nT_0/T_1) where f is function stored in
lookup table, T_0 is period of digital clock and T_1 is desired
period. Mathematically

S(t) = \\sum_n f(nT_0/T_1)\\delta(t - nT_0) = \\sum_n f(t/T_1)\\delta(t - nT_0)

where summation is over all integer n.

Fourier transform of this is

C\\sum_l \\sum_m c_l \\delta(\\omega - 2m\\pi/T_0 - 2l\\pi/T_1)

where we have double summation over integer l and m, c_l is
l-th Fourier coefficient of f and C is a constant.
Sine has only 2 Fourier components, so formula simplifies to

(1/2)C\\sum_m (\\delta(\\omega - 2m\\pi/T_0 - 2\\pi/T_1) +
\\delta(\\omega - 2m\\pi/T_0 + 2\\pi/T_1))

With aggressive filtering high freqency components can be
made arbitrarily small, so after filter Fourier transform
is

(M/2)C(\\delta(\\omega - 2\\pi/T_1) + \\delta(\\omega+ 2\\pi/T_1)) +
small distortion

where M represents transmitance of the filter at frequency
1/T_1. Back in time domain signal is

M\\sin(t) + small distortion

The point is that distortion, hence phase noise can be made
arbitrarily small.

What happens with different f? When T_0/T_1 is irrational,
the sum 2m\\pi/T_0 + 2l\\pi/T_1 can take values arbitrarily
close to 0. In particular, there will be combinations of
l and m such that this sum is in the interval [-\\pi/T_1, \\pi/T_1],
so we will get low frequency terms with wrong frequency.
Assuming fixed low pass filter such terms can not be filered
out. How bad this is? For sawtooth the second Fourier
coefficient has maginitude equal to half of the magnitude
of the first coefficient, so one can expect distortion
of order 50%, which looks quite bad. Using symmetric
troangular weave, second Fourier coefficient is 0 and
third has magnitude 1/9 of magnitude of the first
coefficient, which is much better, but still limits
possible quality.


Distortion and phase noise are only obliquely related.

Cheers

Phil Hobbs

I want a clock, so only the zero crossings matter. And I only want to
synthesize an octave, so can use a bandpass filter.

Real bandpass filters don\'t work well over an octave, so I\'m using a
3-pole Chebyhshev lowpass and a single-pole highpass, and probably a
160 MHz accumulator clock to make 12 to 24 MHz out.

Then the question becomes, how many bits into the DAC?

5 or 6 look pretty good.

I have a program that simulates the digital stuff and outputs a PWL
file, and an LT Spice thing that inputs the PWL as a voltage waveform
and does the analog filtering and compare.

I can share those if anyone is interested.

The tricky bits here are nonlinear (no pun, of course.)
 
In sci.electronics.design Phil Hobbs <pcdhSpamMeSenseless@electrooptical.net> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <jl@glen--canyon.com> wrote:
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.

Sine is close to optimal for high quality DDS. The math is
as follows. First, your DAC has some response in time
domain, but for purpose of computation one can assume that
at clock tick number n it generates delta peak centered
at nT_0 with amplitude f(nT_0/T_1) where f is function stored in
lookup table, T_0 is period of digital clock and T_1 is desired
period. Mathematically

S(t) = \\sum_n f(nT_0/T_1)\\delta(t - nT_0) = \\sum_n f(t/T_1)\\delta(t - nT_0)

where summation is over all integer n.

Fourier transform of this is

C\\sum_l \\sum_m c_l \\delta(\\omega - 2m\\pi/T_0 - 2l\\pi/T_1)

where we have double summation over integer l and m, c_l is
l-th Fourier coefficient of f and C is a constant.
Sine has only 2 Fourier components, so formula simplifies to

(1/2)C\\sum_m (\\delta(\\omega - 2m\\pi/T_0 - 2\\pi/T_1) +
\\delta(\\omega - 2m\\pi/T_0 + 2\\pi/T_1))

With aggressive filtering high freqency components can be
made arbitrarily small, so after filter Fourier transform
is

(M/2)C(\\delta(\\omega - 2\\pi/T_1) + \\delta(\\omega+ 2\\pi/T_1)) +
small distortion

where M represents transmitance of the filter at frequency
1/T_1. Back in time domain signal is

M\\sin(t) + small distortion

The point is that distortion, hence phase noise can be made
arbitrarily small.

What happens with different f? When T_0/T_1 is irrational,
the sum 2m\\pi/T_0 + 2l\\pi/T_1 can take values arbitrarily
close to 0. In particular, there will be combinations of
l and m such that this sum is in the interval [-\\pi/T_1, \\pi/T_1],
so we will get low frequency terms with wrong frequency.
Assuming fixed low pass filter such terms can not be filered
out. How bad this is? For sawtooth the second Fourier
coefficient has maginitude equal to half of the magnitude
of the first coefficient, so one can expect distortion
of order 50%, which looks quite bad. Using symmetric
troangular weave, second Fourier coefficient is 0 and
third has magnitude 1/9 of magnitude of the first
coefficient, which is much better, but still limits
possible quality.


Distortion and phase noise are only obliquely related.

Well, signal to the comparator is f(t) + r(t) where r(t)
is distortion. Assuming that distortion is reasonably
small and regular we have

phase error \\approx -r(t_0)/f\'(t_0)

where t_0 is zero of f. To minimize phase error you can
try to make f\'(t_0) big, but John is working over an
octave, so not much possibility here.

So we need small r(t_0). In general desired frequency and
and frequency of digital clock are uncorelated, so zeros
of f will be randomly distributed over quasi periods of
r, which means that to have small avarage error you
need small average of absolute value of r. Similarly
smal maximal error need small maximum of r.

Of course, there are constant factors because simple Fourier
computation works exactly only for energy. Those constants
are hard to compute but in practice do not tend to be really
large (say of order of 2 or 3). So at low accuracy there
may be some room to use different function than sine.
For higher accuracy the above calculation gives too big
term to ignore.

--
Waldek Hebisch
 
On 2025-05-14 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs <pcdhSpamMeSenseless@electrooptical.net> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <jl@glen--canyon.com> wrote:
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.

Sine is close to optimal for high quality DDS. The math is
as follows. First, your DAC has some response in time
domain, but for purpose of computation one can assume that
at clock tick number n it generates delta peak centered
at nT_0 with amplitude f(nT_0/T_1) where f is function stored in
lookup table, T_0 is period of digital clock and T_1 is desired
period. Mathematically

S(t) = \\sum_n f(nT_0/T_1)\\delta(t - nT_0) = \\sum_n f(t/T_1)\\delta(t - nT_0)

where summation is over all integer n.

Fourier transform of this is

C\\sum_l \\sum_m c_l \\delta(\\omega - 2m\\pi/T_0 - 2l\\pi/T_1)

where we have double summation over integer l and m, c_l is
l-th Fourier coefficient of f and C is a constant.
Sine has only 2 Fourier components, so formula simplifies to

(1/2)C\\sum_m (\\delta(\\omega - 2m\\pi/T_0 - 2\\pi/T_1) +
\\delta(\\omega - 2m\\pi/T_0 + 2\\pi/T_1))

With aggressive filtering high freqency components can be
made arbitrarily small, so after filter Fourier transform
is

(M/2)C(\\delta(\\omega - 2\\pi/T_1) + \\delta(\\omega+ 2\\pi/T_1)) +
small distortion

where M represents transmitance of the filter at frequency
1/T_1. Back in time domain signal is

M\\sin(t) + small distortion

The point is that distortion, hence phase noise can be made
arbitrarily small.

What happens with different f? When T_0/T_1 is irrational,
the sum 2m\\pi/T_0 + 2l\\pi/T_1 can take values arbitrarily
close to 0. In particular, there will be combinations of
l and m such that this sum is in the interval [-\\pi/T_1, \\pi/T_1],
so we will get low frequency terms with wrong frequency.
Assuming fixed low pass filter such terms can not be filered
out. How bad this is? For sawtooth the second Fourier
coefficient has maginitude equal to half of the magnitude
of the first coefficient, so one can expect distortion
of order 50%, which looks quite bad. Using symmetric
troangular weave, second Fourier coefficient is 0 and
third has magnitude 1/9 of magnitude of the first
coefficient, which is much better, but still limits
possible quality.


Distortion and phase noise are only obliquely related.

Well, signal to the comparator is f(t) + r(t) where r(t)
is distortion. Assuming that distortion is reasonably
small and regular we have

phase error \\approx -r(t_0)/f\'(t_0)

where t_0 is zero of f. To minimize phase error you can
try to make f\'(t_0) big, but John is working over an
octave, so not much possibility here.

So we need small r(t_0). In general desired frequency and
and frequency of digital clock are uncorelated, so zeros
of f will be randomly distributed over quasi periods of
r, which means that to have small avarage error you
need small average of absolute value of r. Similarly
smal maximal error need small maximum of r.

Of course, there are constant factors because simple Fourier
computation works exactly only for energy. Those constants
are hard to compute but in practice do not tend to be really
large (say of order of 2 or 3). So at low accuracy there
may be some room to use different function than sine.
For higher accuracy the above calculation gives too big
term to ignore.

\"Distortion\" to me means harmonics and IMD. The usual small-signal
analysis isn\'t too useful when the interference is at frequencies
comparable to or greater than the fundamental.

And it isn\'t really clock interference that\'s in view with a DDS,
because there\'s a zero-order hold, which in principle nulls out the
clock and all of its harmonics. (You have to have a reconstruction
filter of some sort anyway.)

What kills you with DDS is the nasty, very high-order subharmonics due
to truncation of the phase word. Power supply junk is often of the same
order, but its easier to get rid of--the truncation sidebands extend
down to the very low baseband.

Cheers

Phil Hobbs

--
Dr Philip C D Hobbs
Principal Consultant
ElectroOptical Innovations LLC / Hobbs ElectroOptics
Optics, Electro-optics, Photonics, Analog Electronics
Briarcliff Manor NY 10510

http://electrooptical.net
http://hobbs-eo.com
 
On Wed, 14 May 2025 15:05:41 -0400, Phil Hobbs
<pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-14 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs <pcdhSpamMeSenseless@electrooptical.net> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <jl@glen--canyon.com> wrote:
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.

Sine is close to optimal for high quality DDS. The math is
as follows. First, your DAC has some response in time
domain, but for purpose of computation one can assume that
at clock tick number n it generates delta peak centered
at nT_0 with amplitude f(nT_0/T_1) where f is function stored in
lookup table, T_0 is period of digital clock and T_1 is desired
period. Mathematically

S(t) = \\sum_n f(nT_0/T_1)\\delta(t - nT_0) = \\sum_n f(t/T_1)\\delta(t - nT_0)

where summation is over all integer n.

Fourier transform of this is

C\\sum_l \\sum_m c_l \\delta(\\omega - 2m\\pi/T_0 - 2l\\pi/T_1)

where we have double summation over integer l and m, c_l is
l-th Fourier coefficient of f and C is a constant.
Sine has only 2 Fourier components, so formula simplifies to

(1/2)C\\sum_m (\\delta(\\omega - 2m\\pi/T_0 - 2\\pi/T_1) +
\\delta(\\omega - 2m\\pi/T_0 + 2\\pi/T_1))

With aggressive filtering high freqency components can be
made arbitrarily small, so after filter Fourier transform
is

(M/2)C(\\delta(\\omega - 2\\pi/T_1) + \\delta(\\omega+ 2\\pi/T_1)) +
small distortion

where M represents transmitance of the filter at frequency
1/T_1. Back in time domain signal is

M\\sin(t) + small distortion

The point is that distortion, hence phase noise can be made
arbitrarily small.

What happens with different f? When T_0/T_1 is irrational,
the sum 2m\\pi/T_0 + 2l\\pi/T_1 can take values arbitrarily
close to 0. In particular, there will be combinations of
l and m such that this sum is in the interval [-\\pi/T_1, \\pi/T_1],
so we will get low frequency terms with wrong frequency.
Assuming fixed low pass filter such terms can not be filered
out. How bad this is? For sawtooth the second Fourier
coefficient has maginitude equal to half of the magnitude
of the first coefficient, so one can expect distortion
of order 50%, which looks quite bad. Using symmetric
troangular weave, second Fourier coefficient is 0 and
third has magnitude 1/9 of magnitude of the first
coefficient, which is much better, but still limits
possible quality.


Distortion and phase noise are only obliquely related.

Well, signal to the comparator is f(t) + r(t) where r(t)
is distortion. Assuming that distortion is reasonably
small and regular we have

phase error \\approx -r(t_0)/f\'(t_0)

where t_0 is zero of f. To minimize phase error you can
try to make f\'(t_0) big, but John is working over an
octave, so not much possibility here.

So we need small r(t_0). In general desired frequency and
and frequency of digital clock are uncorelated, so zeros
of f will be randomly distributed over quasi periods of
r, which means that to have small avarage error you
need small average of absolute value of r. Similarly
smal maximal error need small maximum of r.

Of course, there are constant factors because simple Fourier
computation works exactly only for energy. Those constants
are hard to compute but in practice do not tend to be really
large (say of order of 2 or 3). So at low accuracy there
may be some room to use different function than sine.
For higher accuracy the above calculation gives too big
term to ignore.

\"Distortion\" to me means harmonics and IMD. The usual small-signal
analysis isn\'t too useful when the interference is at frequencies
comparable to or greater than the fundamental.

And it isn\'t really clock interference that\'s in view with a DDS,
because there\'s a zero-order hold, which in principle nulls out the
clock and all of its harmonics. (You have to have a reconstruction
filter of some sort anyway.)

What kills you with DDS is the nasty, very high-order subharmonics due
to truncation of the phase word. Power supply junk is often of the same
order, but its easier to get rid of--the truncation sidebands extend
down to the very low baseband.

A highpass filter stage can help that some. It helps reject logic
supply junk too.

Cheers

Phil Hobbs

Yeah, math is instructive but a real nonlinear circuit needs to be
simulated and then built and tested.

The number of bits into and out of the sine table, time skew into the
resistive DAC, the real-life filter, FPGA digital supply noise, all
that grody stuff.

I\'m simulating an 8-bit sine lookup, a 5-bit resistive DAC, 160 MHz
clock, 10-20 MHz out, and under 1 ns p-p jitter.

It\'s hard to measure jitter in Spice. I\'m just randomly measuring
cycles with the cursor. There must be a better way. Maybe something
with a delay line, compared against clock cycles?
 
On 2025-05-14 17:53, john larkin wrote:
On Wed, 14 May 2025 15:05:41 -0400, Phil Hobbs
pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-14 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs <pcdhSpamMeSenseless@electrooptical.net> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <jl@glen--canyon.com> wrote:
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.

Sine is close to optimal for high quality DDS. The math is
as follows. First, your DAC has some response in time
domain, but for purpose of computation one can assume that
at clock tick number n it generates delta peak centered
at nT_0 with amplitude f(nT_0/T_1) where f is function stored in
lookup table, T_0 is period of digital clock and T_1 is desired
period. Mathematically

S(t) = \\sum_n f(nT_0/T_1)\\delta(t - nT_0) = \\sum_n f(t/T_1)\\delta(t - nT_0)

where summation is over all integer n.

Fourier transform of this is

C\\sum_l \\sum_m c_l \\delta(\\omega - 2m\\pi/T_0 - 2l\\pi/T_1)

where we have double summation over integer l and m, c_l is
l-th Fourier coefficient of f and C is a constant.
Sine has only 2 Fourier components, so formula simplifies to

(1/2)C\\sum_m (\\delta(\\omega - 2m\\pi/T_0 - 2\\pi/T_1) +
\\delta(\\omega - 2m\\pi/T_0 + 2\\pi/T_1))

With aggressive filtering high freqency components can be
made arbitrarily small, so after filter Fourier transform
is

(M/2)C(\\delta(\\omega - 2\\pi/T_1) + \\delta(\\omega+ 2\\pi/T_1)) +
small distortion

where M represents transmitance of the filter at frequency
1/T_1. Back in time domain signal is

M\\sin(t) + small distortion

The point is that distortion, hence phase noise can be made
arbitrarily small.

What happens with different f? When T_0/T_1 is irrational,
the sum 2m\\pi/T_0 + 2l\\pi/T_1 can take values arbitrarily
close to 0. In particular, there will be combinations of
l and m such that this sum is in the interval [-\\pi/T_1, \\pi/T_1],
so we will get low frequency terms with wrong frequency.
Assuming fixed low pass filter such terms can not be filered
out. How bad this is? For sawtooth the second Fourier
coefficient has maginitude equal to half of the magnitude
of the first coefficient, so one can expect distortion
of order 50%, which looks quite bad. Using symmetric
troangular weave, second Fourier coefficient is 0 and
third has magnitude 1/9 of magnitude of the first
coefficient, which is much better, but still limits
possible quality.


Distortion and phase noise are only obliquely related.

Well, signal to the comparator is f(t) + r(t) where r(t)
is distortion. Assuming that distortion is reasonably
small and regular we have

phase error \\approx -r(t_0)/f\'(t_0)

where t_0 is zero of f. To minimize phase error you can
try to make f\'(t_0) big, but John is working over an
octave, so not much possibility here.

So we need small r(t_0). In general desired frequency and
and frequency of digital clock are uncorelated, so zeros
of f will be randomly distributed over quasi periods of
r, which means that to have small avarage error you
need small average of absolute value of r. Similarly
smal maximal error need small maximum of r.

Of course, there are constant factors because simple Fourier
computation works exactly only for energy. Those constants
are hard to compute but in practice do not tend to be really
large (say of order of 2 or 3). So at low accuracy there
may be some room to use different function than sine.
For higher accuracy the above calculation gives too big
term to ignore.

\"Distortion\" to me means harmonics and IMD. The usual small-signal
analysis isn\'t too useful when the interference is at frequencies
comparable to or greater than the fundamental.

And it isn\'t really clock interference that\'s in view with a DDS,
because there\'s a zero-order hold, which in principle nulls out the
clock and all of its harmonics. (You have to have a reconstruction
filter of some sort anyway.)

What kills you with DDS is the nasty, very high-order subharmonics due
to truncation of the phase word. Power supply junk is often of the same
order, but its easier to get rid of--the truncation sidebands extend
down to the very low baseband.

A highpass filter stage can help that some. It helps reject logic
supply junk too.

No, because it appears as PM sidebands on the fundamental output. Even
a narrowband PLL won\'t get rid of all of them, if the size of the phase
increment isn\'t a favorable value.

Yeah, math is instructive but a real nonlinear circuit needs to be
simulated and then built and tested.

I\'m all for doing all those things, but a bit of math can narrow down
the search space amazingly, and help prevent two equal and opposite
mistakes: going off on a snark hunt after an impossible goal(*), or
settling for something much worse than you ought to. It\'s super
valuable to know how good something _might_ be.
The number of bits into and out of the sine table, time skew into the
resistive DAC, the real-life filter, FPGA digital supply noise, all
that grody stuff.

I\'m simulating an 8-bit sine lookup, a 5-bit resistive DAC, 160 MHz
clock, 10-20 MHz out, and under 1 ns p-p jitter.

That\'ll depend on the exact increment you choose. With one of the magic
increments, the truncation jitter would be zero. The normal
clocking-system junk will remain, of course.

It\'s hard to measure jitter in Spice. I\'m just randomly measuring
cycles with the cursor. There must be a better way. Maybe something
with a delay line, compared against clock cycles?

The jitter is periodic with a potentially very long period. With an
N-bit phase accumulator, if the increment B is not divisible by 2, i.e.
if it\'s prime relative to 2**N, the repeat length will be B*2**N clocks.

With an ideal N-bit DAC (i.e. the full width of the accumulator), this
doesn\'t cause problems because the DAC produces a correctly sampled sine
wave for any value of B. The sampling artifacts go away in the
reconstruction filter, leaving a jitter-free sine wave, guaranteed by
Messrs Gauss, Shannon, and Nyquist.

Truncating the width of the DAC causes part of the jitter to get
through. With an M-bit DAC, it\'s only the lower (N-M) bits that
contribute jitter, so if your increment is divisible by 2**(N-M), those
bits will sit still and contribute zero truncation jitter.

It\'s an interesting topic.

Cheers

Phil Hobbs

(*) Such as wanting a 60-dB SNR in 100 MHz (5 ns equivalent) with a
photocurrent of 1 nA. 1 nA is 6.2E9 electrons/s, so in 5 ns you get 31
electrons, i.e. a maximum SNR of 31 (15 dB).

--
Dr Philip C D Hobbs
Principal Consultant
ElectroOptical Innovations LLC / Hobbs ElectroOptics
Optics, Electro-optics, Photonics, Analog Electronics
Briarcliff Manor NY 10510

http://electrooptical.net
http://hobbs-eo.com
 
On Wed, 14 May 2025 19:16:20 -0400, Phil Hobbs
<pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-14 17:53, john larkin wrote:
On Wed, 14 May 2025 15:05:41 -0400, Phil Hobbs
pcdhSpamMeSenseless@electrooptical.net> wrote:

On 2025-05-14 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs <pcdhSpamMeSenseless@electrooptical.net> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <jl@glen--canyon.com> wrote:
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.

Sine is close to optimal for high quality DDS. The math is
as follows. First, your DAC has some response in time
domain, but for purpose of computation one can assume that
at clock tick number n it generates delta peak centered
at nT_0 with amplitude f(nT_0/T_1) where f is function stored in
lookup table, T_0 is period of digital clock and T_1 is desired
period. Mathematically

S(t) = \\sum_n f(nT_0/T_1)\\delta(t - nT_0) = \\sum_n f(t/T_1)\\delta(t - nT_0)

where summation is over all integer n.

Fourier transform of this is

C\\sum_l \\sum_m c_l \\delta(\\omega - 2m\\pi/T_0 - 2l\\pi/T_1)

where we have double summation over integer l and m, c_l is
l-th Fourier coefficient of f and C is a constant.
Sine has only 2 Fourier components, so formula simplifies to

(1/2)C\\sum_m (\\delta(\\omega - 2m\\pi/T_0 - 2\\pi/T_1) +
\\delta(\\omega - 2m\\pi/T_0 + 2\\pi/T_1))

With aggressive filtering high freqency components can be
made arbitrarily small, so after filter Fourier transform
is

(M/2)C(\\delta(\\omega - 2\\pi/T_1) + \\delta(\\omega+ 2\\pi/T_1)) +
small distortion

where M represents transmitance of the filter at frequency
1/T_1. Back in time domain signal is

M\\sin(t) + small distortion

The point is that distortion, hence phase noise can be made
arbitrarily small.

What happens with different f? When T_0/T_1 is irrational,
the sum 2m\\pi/T_0 + 2l\\pi/T_1 can take values arbitrarily
close to 0. In particular, there will be combinations of
l and m such that this sum is in the interval [-\\pi/T_1, \\pi/T_1],
so we will get low frequency terms with wrong frequency.
Assuming fixed low pass filter such terms can not be filered
out. How bad this is? For sawtooth the second Fourier
coefficient has maginitude equal to half of the magnitude
of the first coefficient, so one can expect distortion
of order 50%, which looks quite bad. Using symmetric
troangular weave, second Fourier coefficient is 0 and
third has magnitude 1/9 of magnitude of the first
coefficient, which is much better, but still limits
possible quality.


Distortion and phase noise are only obliquely related.

Well, signal to the comparator is f(t) + r(t) where r(t)
is distortion. Assuming that distortion is reasonably
small and regular we have

phase error \\approx -r(t_0)/f\'(t_0)

where t_0 is zero of f. To minimize phase error you can
try to make f\'(t_0) big, but John is working over an
octave, so not much possibility here.

So we need small r(t_0). In general desired frequency and
and frequency of digital clock are uncorelated, so zeros
of f will be randomly distributed over quasi periods of
r, which means that to have small avarage error you
need small average of absolute value of r. Similarly
smal maximal error need small maximum of r.

Of course, there are constant factors because simple Fourier
computation works exactly only for energy. Those constants
are hard to compute but in practice do not tend to be really
large (say of order of 2 or 3). So at low accuracy there
may be some room to use different function than sine.
For higher accuracy the above calculation gives too big
term to ignore.

\"Distortion\" to me means harmonics and IMD. The usual small-signal
analysis isn\'t too useful when the interference is at frequencies
comparable to or greater than the fundamental.

And it isn\'t really clock interference that\'s in view with a DDS,
because there\'s a zero-order hold, which in principle nulls out the
clock and all of its harmonics. (You have to have a reconstruction
filter of some sort anyway.)

What kills you with DDS is the nasty, very high-order subharmonics due
to truncation of the phase word. Power supply junk is often of the same
order, but its easier to get rid of--the truncation sidebands extend
down to the very low baseband.

A highpass filter stage can help that some. It helps reject logic
supply junk too.

No, because it appears as PM sidebands on the fundamental output. Even
a narrowband PLL won\'t get rid of all of them, if the size of the phase
increment isn\'t a favorable value.

Yeah, math is instructive but a real nonlinear circuit needs to be
simulated and then built and tested.

I\'m all for doing all those things, but a bit of math can narrow down
the search space amazingly, and help prevent two equal and opposite
mistakes: going off on a snark hunt after an impossible goal(*), or
settling for something much worse than you ought to. It\'s super
valuable to know how good something _might_ be.

The number of bits into and out of the sine table, time skew into the
resistive DAC, the real-life filter, FPGA digital supply noise, all
that grody stuff.

I\'m simulating an 8-bit sine lookup, a 5-bit resistive DAC, 160 MHz
clock, 10-20 MHz out, and under 1 ns p-p jitter.

That\'ll depend on the exact increment you choose. With one of the magic
increments, the truncation jitter would be zero. The normal
clocking-system junk will remain, of course.

The highpass will at least reduce power supply noise, if I use a
resistive DAC right out of some FPGA pins.

It\'s hard to measure jitter in Spice. I\'m just randomly measuring
cycles with the cursor. There must be a better way. Maybe something
with a delay line, compared against clock cycles?

The jitter is periodic with a potentially very long period. With an
N-bit phase accumulator, if the increment B is not divisible by 2, i.e.
if it\'s prime relative to 2**N, the repeat length will be B*2**N clocks.

I should test the really worst cases. My customer can request any
frequency as a 32-bit integer. I need to emulate the old expensive ADI
DDS chip which was clocked at 40 MHz.

With an ideal N-bit DAC (i.e. the full width of the accumulator), this
doesn\'t cause problems because the DAC produces a correctly sampled sine
wave for any value of B. The sampling artifacts go away in the
reconstruction filter, leaving a jitter-free sine wave, guaranteed by
Messrs Gauss, Shannon, and Nyquist.

Truncating the width of the DAC causes part of the jitter to get
through. With an M-bit DAC, it\'s only the lower (N-M) bits that
contribute jitter, so if your increment is divisible by 2**(N-M), those
bits will sit still and contribute zero truncation jitter.

It\'s an interesting topic.

Cheers

Phil Hobbs

(*) Such as wanting a 60-dB SNR in 100 MHz (5 ns equivalent) with a
photocurrent of 1 nA. 1 nA is 6.2E9 electrons/s, so in 5 ns you get 31
electrons, i.e. a maximum SNR of 31 (15 dB).

Someone observed that of the guys who won Nobel prizes in the glory
days of Bell Labs, they all had lunch with Harry Nyquist.

I did have lunch with Walter Brattain.
 

Welcome to EDABoard.com

Sponsor

Back
Top