We discussed exactly this issue in August 2022 in the thread "Re: Direct digital synthesis of square waves". My posting on 18 August about "bottom bits" is one way.
Joe
We discussed exactly this issue in August 2022 in the thread "Re: Direct digital synthesis of square waves". My posting on 18 August about "bottom bits" is one way.
Joe
Don't think so. Since you have exactly two edges per cycle, it would have the same problem as the sawtooth, for the same reason. You could interpolate the same sort of way as in a DDG.
Cheers
Phil Hobbs
If some N bits can be sent to a DAC and a filter, to interpolate to better time accuracy than just using the MS bit, then the equivalent interpolation should be possible digitally, inside the FPGA.
We can always spin up a PLL to get as fast a clock as the logic can stand. And sub-clock tricks have been done.
You still have the giant spike between the actual position of the edge and where it ought to be for a subharmonic-free signal. That's less than one clock wide, so there's no way to get rid of it digitally. You could maybe do some noise shaping thing to put the subharmonics someplace else, but unless your increment is a factor of 2**(accumulator width), they'll be there.
A full-width DAC, followed by a brickwall lowpass, followed by a comparator, will get rid of the subharmonics, as would a ramp/threshold analog delay calculated on a per-cycle basis.
Cheers
Phil Hobbs
We could take the phase accumulator "dac" MSBs and stuff them into a brickwall digital lowpass filter, maybe even do the sine mapping first. The result would be a wide smooth waveform, similar to what the analog comparator would see, only digital. The zero cross of that would be our "DDS comparator output" clock, to one system clock quantization. Going to half clock resolution wouldn't be hard.
If the phase accumulator clock is 160 MHz, half a clock gives us 3 ns p-p jitter, and the RMS jitter is 900 ps. (Why square root of 12? We live in a strange universe.)
That filter logic could be clocked faster than the phase accumulator clock too. Some crazy PLL rate.
I don't want to drive a bunch of 20-bit parallel DACs, or make some
13-pole LC filters, but bits are cheap inside an FPGA.We know what the output frequency will be, so the digital filter can be tuned for that. Maybe a narrow bandpass? Kills subharmonics?
Some truly terrible things have been done in FPGAs to get picosecond resolution delays and time interval measuring.
Sounds like a good senior project.
If the output frequency is known in advance, all ought to be straightforward—pick a clock frequency that’s an integer multiple.
One VCXO-based PLL should be able to make that.
Cheers
Phil Hobbs
The gadget's output frequency is known when the user programs it, not years in advance. When we know the frequency we have to do the math to program the Fset register over our octave range, and program a downstream divisor (for, say, a 12 Hz trigger rate) so we have time to program a digital filter too.
An 8-bit R-2R network and a modest LC filter and an LVDS buffer as a comparator isn't awful, but getting the entire DDS system inside the FPGA would be cool.
I did consider having a fixed frequency clock and a divisor as our internal trigger source, and telling the user he has to live with Fxo/N as the possible choices, but even I have my limits of tackiness.
The difference between adjacent magic increments isn’t that large, at least at lowish frequencies. It might well be possible to dork the clock to get to the nearest one.
Cheers
Phil Hobbs
Yes. Surely these are lowish frequencies as early on in the discussion JL said all this was to simulate rotating machines?
You can't pull a VCXO all that far
There's going to be a tolerance on the VCXO centre frequency as well. which isn't gong to help.
There's a reason why Direct Digital Synthesis is popular - it does finesse a lot of awkward problems.
Actually that suggests to me a bonkers way to do it with an analogue multiplier and a flipflop to fiddle the phase. Generate two waveforms from the phase accumulator MSB one rising and one falling. PHACC and ~PHACC.
Multiply the two sawtooth waves together in an analogue multiplier and then you get a nice parabolic approximation to half a sine wave.
/|/|/|/|/| x \|\|\|\| = .o.o.o.o
Then flip alternate half cycles negative with your crude square wave.
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. 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.
If you’re going to do it with integral/differential equations, why not solve an SHM system and get a sine wave directly?
The catch with a VCO inside an FPGA is going to be the ripple on the supply voltages inside the FPGA.
Its output will have appreciable jitter. The charm of the Phil Hobbs VCXO is that it will be a low jitter source - probably at the pico-second level
You couldn't do that with Phil Hobbs VCXO as your VCO. A 150MHz VXCO would limit you about 15hHz, which is probably all that your customers need. Giving then a lot more than they need always makes the salesmen happy, but it doesn't do anything for the customer.
So optimise it for the frequencies they want, and chop the performance in areas they won't use.
then is a the few ns of jitter with the clock rate you could get with an FPGA really much of an issue, isn't that still way better than what you'd expect from the real sensors on a rotating assembly?
Yes, real machines vibrate and shake and all that. And the position/rotation sensors aren't great either, usually magnetic things that look like spark plugs, near gear teeth.
Nobody would notice a few ns of RMS jitter.
But if I can come up with a good cheap rate generator, we can use it on other products, like our PPG precision pulse generator. Low period jitter would be a feature on that one.
Looks like the best way is logic in the FPGA doing classic sine DDS, maybe 6 or 8 output pins driving an R-2R network, a 3 or 5-pole Chebyshev LC filter, and an LVDS receiver as the comparator.
It never hurts to be confused for a while, and consider possibilities. I'm a great fan of silly ideas and confusion.
One could parallel resonate one of the inductors in the 5-pole filter, to make a sort of elliptical Chevyshev.
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".
How about this?
R1C1 sets the comparator threshold to be the midpoint of the sine wave. If its time constant is short, it provides some useful bandpass effect too.
I can use a 3-pole filter in apps where a little jitter is OK.
A good filter and a comparator could help, as in "FM Capture Effect."
We'd at least retime the 8 outputs in output latches, in the same region.
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.
One approach that might help, but isn't going to be all that cheap, would be to latch the digital information coming out of the FPGA into something like an ECLinPS latch which has very fast internal logic and rather less variation in propagation delay between the clock edge going into the ECLinPS latch and the output edges of the data outputs.
The other advantage is that ECL is current steering logic, so the latch rails are a lot clean than the rails inside the FPGA and the nominally unchanged edges aren't going to move as much.
Have something to add? Share your thoughts — no account required.
Ask the community — no account required