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. [...]
On 5/6/25 17: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?
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. [...]
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
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.
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
< https://en.wikipedia.org/wiki/List_of_HDL_simulators >
I did publish a DDS in VHDL. It's on opencores.org under arithmetic
named sincos.
Am 06.05.25 um 17:48 schrieb john larkin:
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.
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
< https://en.wikipedia.org/wiki/List_of_HDL_simulators >
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.
< >https://www.researchgate.net/publication/220236321_An_Improved_Linear_Difference_Method_with_High_ROM_Compression_Ratio_in_Direct_Digital_Frequency_Synthesizer
>
On a Spartan 6 eval board it runs at 200 MHz out of the box.
Cheers, Gerhard
On 5/6/25 17: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?
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. [...]
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
On 2025-05-06 15:00, Jeroen Belleman wrote:
On 5/6/25 17: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?
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. [...]
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
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
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.
On Tue, 6 May 2025 16:46:16 -0400, Phil Hobbs <[email protected]> wrote:
On 2025-05-06 15:00, Jeroen Belleman wrote:
On 5/6/25 17: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?
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. [...]
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
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.
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.
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
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.
On 2025-05-06 15:00, Jeroen Belleman wrote:
On 5/6/25 17: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?
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. [...]
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
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
On 2025-05-07 00:50, john larkin wrote:
On Tue, 6 May 2025 16:46:16 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-06 15:00, Jeroen Belleman wrote:
On 5/6/25 17: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?
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. [...]
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
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.
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.
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
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.
Can't you fold the LIN to SIN conversion in the resistor values?
Arie
On Wed, 7 May 2025 11:44:23 +0200, Arie de Muijnck <[email protected]>
wrote:
On 2025-05-07 00:50, john larkin wrote:
On Tue, 6 May 2025 16:46:16 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-06 15:00, Jeroen Belleman wrote:
On 5/6/25 17: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?
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. [...]
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
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.
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.
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
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.
Can't you fold the LIN to SIN conversion in the resistor values?
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.
On 2025-05-07 09:55, john larkin wrote:
On Tue, 6 May 2025 16:46:16 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-06 15:00, Jeroen Belleman wrote:
On 5/6/25 17:48, john larkin wrote:
Once you have a lookup table, a sine is as easy as anything else, and
minimizes the demands on the DAC, filters and amplifiers.
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.
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.
On Tue, 6 May 2025 16:46:16 -0400, Phil Hobbs <[email protected]> wrote:
On 2025-05-06 15:00, Jeroen Belleman wrote:
On 5/6/25 17: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?
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. [...]
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
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.
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.
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.
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?
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.
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.
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
On Thu, 8 May 2025 14:20:21 -0400, Phil Hobbs <[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil HobbsYou still have the giant spike between the actual position of the edge
<[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
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
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs <[email protected]> wrote:
On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil HobbsYou still have the giant spike between the actual position of the edge
<[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
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.
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil HobbsYou still have the giant spike between the actual position of the edge
<[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
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
On Thu, 8 May 2025 22:28:40 -0000 (UTC), Phil Hobbs <[email protected]> wrote:
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil HobbsYou 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
<[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
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
straightforwardpick a clock frequency thats 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.
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 22:28:40 -0000 (UTC), Phil Hobbs
<[email protected]> wrote:
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil HobbsYou 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
<[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
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
straightforwardpick a clock frequency thats 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.
Cheers
Phil Hobbs
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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:
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.
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.
Phil Hobbs <[email protected]> wrote:
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 22:28:40 -0000 (UTC), Phil Hobbs
<[email protected]> wrote:
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil HobbsYou 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
<[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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.
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.
Cheers
Phil Hobbs
Yes. Surely these are lowish frequencies as early on in the discussion JL >said all this was to simulate rotating machines?
If you then integrate a band-limited square wave you get a band-limited triangle wave directly.
On Fri, 9 May 2025 04:48:33 -0000 (UTC), piglet
<[email protected]> wrote:
Phil Hobbs <[email protected]> wrote:
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 22:28:40 -0000 (UTC), Phil Hobbs
<[email protected]> wrote:
john larkin <[email protected]> wrote:
On Thu, 8 May 2025 16:24:29 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-08 14:58, john larkin wrote:
On Thu, 8 May 2025 14:20:21 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-07 22:21, john larkin wrote:
On Wed, 7 May 2025 20:27:58 -0400, bitrex <[email protected]> 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:
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.
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.
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 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?
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.
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.
In article <[email protected]>,
john larkin <[email protected]> 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".
In article <[email protected]>,One approach that might help, but isn't going to be all that cheap,
john larkin <[email protected]> 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.
On 11/05/2025 9:50 am, Dave Platt wrote:
In article <[email protected]>,One approach that might help, but isn't going to be all that cheap,
john larkin <[email protected]> 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.
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.
On Sat, 10 May 2025 16:50:03 -0700, [email protected] (Dave
Platt) wrote:
In article <[email protected]>,
john larkin <[email protected]> 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.
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.
In sci.electronics.design john larkin <[email protected]> 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.
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <[email protected]> wrote:Distortion and phase noise are only obliquely related.
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.
Cheers
Phil Hobbs
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <[email protected]> wrote:Distortion and phase noise are only obliquely related.
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.
In sci.electronics.design Phil Hobbs <[email protected]> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <[email protected]> wrote:Distortion and phase noise are only obliquely related.
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.
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.
On 2025-05-14 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs <[email protected]> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <[email protected]> wrote:Distortion and phase noise are only obliquely related.
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.
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
On 2025-05-14 17:53, john larkin wrote:
On Wed, 14 May 2025 15:05:41 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-14 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs <[email protected]> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <[email protected]> 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.Distortion and phase noise are only obliquely related.
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.
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).
On Wed, 14 May 2025 15:05:41 -0400, Phil Hobbs <[email protected]> wrote:
On 2025-05-14 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs <[email protected]> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <[email protected]> wrote:Distortion and phase noise are only obliquely related.
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.
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.
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 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs
<[email protected]> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <[email protected]> wrote:Distortion and phase noise are only obliquely related.
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.
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.
On Wed, 14 May 2025 19:16:20 -0400, Phil Hobbs <[email protected]> wrote:
On 2025-05-14 17:53, john larkin wrote:
On Wed, 14 May 2025 15:05:41 -0400, Phil Hobbs
<[email protected]> wrote:
On 2025-05-14 11:35, Waldek Hebisch wrote:
In sci.electronics.design Phil Hobbs <[email protected]> wrote:
On 2025-05-13 19:25, Waldek Hebisch wrote:
In sci.electronics.design john larkin <[email protected]> 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.Distortion and phase noise are only obliquely related.
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.
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.
| Sysop: | Keyop |
|---|---|
| Location: | Huddersfield, West Yorkshire, UK |
| Users: | 715 |
| Nodes: | 16 (2 / 14) |
| Uptime: | 152:56:53 |
| Calls: | 12,091 |
| Calls today: | 4 |
| Files: | 15,000 |
| Messages: | 6,517,662 |