I've read the Wikipedia article about Direct Digital Synthesis ( http://en.wikipedia.org/wiki/Direct_digital_synthesis ) and building a DDS generator with a FPGA, which interpolates between adjacent entries in the lookup table, looks like some fun. This is my first try: http://it4systems.de/SignalGenerator/doc/index.html Maybe when I have some more time, I'll add more features, like a SPI interface to control it from an external microcontroller and multiple outputs. Any ideas how to improve it? I have read this paper: http://www.analog.com/UploadedFiles/Tutorials/450968421DDS_Tutorial_rev12-2-99.pdf In this document an Inverse Sinc Filter is mentioned, but without details about it. Do you know how to implement it? And does it improve the output of an interpolating generator or is this useful for non-interpolating generators, only? -- Frank Buss, fb@frank-buss.de http://www.frank-buss.de, http://www.it4-systems.de
DDS generator with interpolated samples for Spartan3E development board
Started by ●December 8, 2007
Reply by ●December 8, 20072007-12-08
Frank Buss wrote:> I've read the Wikipedia article about Direct Digital Synthesis ( > http://en.wikipedia.org/wiki/Direct_digital_synthesis ) and building a DDS > generator with a FPGA, which interpolates between adjacent entries in the > lookup table, looks like some fun. This is my first try: > > http://it4systems.de/SignalGenerator/doc/index.htmlThanks for posting the code examples. Good work. I like your coding style, and judging from the scope trace, it must be working.> Any ideas how to improve it?I would work on the testbench. It is stuck in idle as is. Then add an assertion or two to verify some functionality. -- Mike Treseler
Reply by ●December 8, 20072007-12-08
On Dec 8, 6:15 am, Frank Buss <f...@frank-buss.de> wrote:> I've read the Wikipedia article about Direct Digital Synthesis (http://en.wikipedia.org/wiki/Direct_digital_synthesis) and building a DDS > generator with a FPGA, which interpolates between adjacent entries in the > lookup table, looks like some fun. This is my first try: > > http://it4systems.de/SignalGenerator/doc/index.html > > Maybe when I have some more time, I'll add more features, like a SPI > interface to control it from an external microcontroller and multiple > outputs. > > Any ideas how to improve it? I have read this paper: > > http://www.analog.com/UploadedFiles/Tutorials/450968421DDS_Tutorial_r... > > In this document an Inverse Sinc Filter is mentioned, but without details > about it. Do you know how to implement it? And does it improve the output > of an interpolating generator or is this useful for non-interpolating > generators, only? > > -- > Frank Buss, f...@frank-buss.dehttp://www.frank-buss.de,http://www.it4-systems.deA few suggestions: * Use a longer Sine lookup table instead of interpolation. * Store only 1/4 cycle of the sinewave in the lookup table and use bit operations on the address and output to map the 1/4 cycle onto the full wave. * Use a dual-port RAM for the lookup table to simultaneously generate sine & cosine (useful for digital radio applications) Inverse sinc filters are common ways to equalize the spectral droop caused by the zero-order hold nature of the DAC. Typically a simple FIR filter with a few taps (<10) can 'lift' the high frequency response of the signal to compensate for this rolloff. This page describes one way to do it: http://www.maxim-ic.com/appnotes.cfm/an_pk/3853 EB
Reply by ●December 8, 20072007-12-08
"Frank Buss" <fb@frank-buss.de> wrote in message news:1pksute7pasie.9eglznqt557g.dlg@40tude.net...> > Any ideas how to improve it? I have read this paper: >Nice job. You should synchronize 'reset' to the clock and then use that synchronized reset to reset your state machine and the counter signal). If reset happens to go away inside of the setup/hold window of any of the flops you'll get into an odd initial state or count. KJ
Reply by ●December 9, 20072007-12-09
On Sat, 8 Dec 2007 14:15:57 +0100, Frank Buss <fb@frank-buss.de> wrote:>I've read the Wikipedia article about Direct Digital Synthesis ( >http://en.wikipedia.org/wiki/Direct_digital_synthesis ) and building a DDS >generator with a FPGA, which interpolates between adjacent entries in the >lookup table, looks like some fun. This is my first try: > >http://it4systems.de/SignalGenerator/doc/index.html > >Maybe when I have some more time, I'll add more features, like a SPI >interface to control it from an external microcontroller and multiple >outputs. > >Any ideas how to improve it? I have read this paper:Consider redesigning it to incorporate the following features: 1. Produce an output every clock. This allows much higher output update rates, which can greatly improve the quality of the output. You'll have to throw away your state machine and go to a fully pipelined datapath approach. 2. Increase the maximum clock rate. Design it so that the Fmax of the ram is the only limitation. 3. The mid-sized rams from both X and A are dual port. This allows you to do two lookups in the same clock, which is needed for step 1. 4. As others have pointed out, utilise the symmetry of the sine function to reduce the size of the lookup table by a factor of 4. Equivalently, get 4 times the phase resolution in your table for a given size of ram. Regards, Allan.
Reply by ●December 9, 20072007-12-09
On Sun, 09 Dec 2007 15:37:20 +1100, Allan Herriman <allanherriman@hotmail.com> wrote:>On Sat, 8 Dec 2007 14:15:57 +0100, Frank Buss <fb@frank-buss.de> >wrote: > >>I've read the Wikipedia article about Direct Digital Synthesis ( >>http://en.wikipedia.org/wiki/Direct_digital_synthesis ) and building a DDS >>generator with a FPGA, which interpolates between adjacent entries in the >>lookup table, looks like some fun. This is my first try: >> >>http://it4systems.de/SignalGenerator/doc/index.html >> >>Maybe when I have some more time, I'll add more features, like a SPI >>interface to control it from an external microcontroller and multiple >>outputs. >> >>Any ideas how to improve it? I have read this paper: > >Consider redesigning it to incorporate the following features: > >1. Produce an output every clock. This allows much higher output >update rates, which can greatly improve the quality of the output. >You'll have to throw away your state machine and go to a fully >pipelined datapath approach. > >2. Increase the maximum clock rate. Design it so that the Fmax of >the ram is the only limitation. > >3. The mid-sized rams from both X and A are dual port. This allows >you to do two lookups in the same clock, which is needed for step 1. > >4. As others have pointed out, utilise the symmetry of the sine >function to reduce the size of the lookup table by a factor of 4. >Equivalently, get 4 times the phase resolution in your table for a >given size of ram. > >Regards, >Allan.We've done that: dual-port out of the lookup table, mul+add to interpolate based on lower-order bits of the phase accumulator, do all that and load the dac every clock. We got 128 MHz on a Spartan3, with a 4k x 16 full-cycle lookup table (we need to do arbs, too, and you can't fold arbitrary waveforms) and 16 bit interpolation into, err, a 14 bit dac. It doesn't help harmonic distortion much (that's mostly an analog problem) but it whacks the heck out of close-in spurs. John
Reply by ●December 10, 20072007-12-10
John Larkin wrote:> We've done that: dual-port out of the lookup table, mul+add to > interpolate based on lower-order bits of the phase accumulator, do all > that and load the dac every clock. We got 128 MHz on a Spartan3, with > a 4k x 16 full-cycle lookup table (we need to do arbs, too, and you > can't fold arbitrary waveforms) and 16 bit interpolation into, err, a > 14 bit dac.This sounds interesting, but I wonder why do you need to interpolate at all, if you have only a 14 bit dac, because then it should be possible to use 14 bit width words and a dense table, with only 1 LSB difference between two adjacent samples max. The only interpolation needed then is to decide if you need to use the index from the higher order bits of the accumulator, or the next index, if the lower order bits are >0.5. Of course, you'll need a bit more memory, but e.g. a 14k, 14bit memory could fit easily in the smallest Cyclone III, which you can buy for $15. -- Frank Buss, fb@frank-buss.de http://www.frank-buss.de, http://www.it4-systems.de
Reply by ●December 10, 20072007-12-10
On Mon, 10 Dec 2007 08:11:30 +0100, Frank Buss <fb@frank-buss.de> wrote:>John Larkin wrote: > >> We've done that: dual-port out of the lookup table, mul+add to >> interpolate based on lower-order bits of the phase accumulator, do all >> that and load the dac every clock. We got 128 MHz on a Spartan3, with >> a 4k x 16 full-cycle lookup table (we need to do arbs, too, and you >> can't fold arbitrary waveforms) and 16 bit interpolation into, err, a >> 14 bit dac. > >This sounds interesting, but I wonder why do you need to interpolate at >all, if you have only a 14 bit dac, because then it should be possible to >use 14 bit width words and a dense table, with only 1 LSB difference >between two adjacent samples max. The only interpolation needed then is to >decide if you need to use the index from the higher order bits of the >accumulator, or the next index, if the lower order bits are >0.5. Of >course, you'll need a bit more memory, but e.g. a 14k, 14bit memory could >fit easily in the smallest Cyclone III, which you can buy for $15.We have 8 channels, which used up all the block rams in the biggest Spartan. So we could only use 4k points per channel. The interpolation does have a dramatic effect on near-carrier spurs. We have an option to turn it off, for situations where the customer wants to make step edges in an arbitrary waveform... the interpolation turns everything into slopes. John
Reply by ●December 10, 20072007-12-10
Frank Buss wrote:> I've read the Wikipedia article about Direct Digital Synthesis ( > http://en.wikipedia.org/wiki/Direct_digital_synthesis ) and building a DDS > generator with a FPGA, which interpolates between adjacent entries in the > lookup table, looks like some fun. This is my first try: > > http://it4systems.de/SignalGenerator/doc/index.html > > Maybe when I have some more time, I'll add more features, like a SPI > interface to control it from an external microcontroller and multiple > outputs. > > Any ideas how to improve it? I have read this paper: > > http://www.analog.com/UploadedFiles/Tutorials/450968421DDS_Tutorial_rev12-2-99.pdf > > In this document an Inverse Sinc Filter is mentioned, but without details > about it. Do you know how to implement it? And does it improve the output > of an interpolating generator or is this useful for non-interpolating > generators, only? >Xilinx has a good DDS in their CoreGen library so you could just use that if you need something already completed. The sinx/x filter could be skipped if your DAC sample rate is high enough compared to the DDS frequency. Some DACs also have built-in sinx/x correction. Interpolation in a DDS is usually handled differently than in, say, an interpolation filter. Normally it is done with a Taylor polynomial, which yields much better results than a linear interpolator. The usual problem with a Taylor polynomial is that it requires derivatives of the function. In a DDS, though, the derivitaves of the sine and cosine functions are the very same sines and cosines (and their opposites). So with a BRAM-based lookup table with two read ports, you can read both sine and cosine at the same time, so you effectively also have, for free, the first (and second and third, etc.) derivatives of the outputs. So then with little hardware you can make a first-order Taylor, and with a bit more you could even make a second-order, although rarely is this necessary. I'll send you a Xilinx paper that explains this. It's by Chris Dick and Fred Harris and called "Direct Digital Syhthesis - Some Options for FPGA Implementation". -Kevin
Reply by ●December 10, 20072007-12-10
"Frank Buss" <fb@frank-buss.de> wrote in message news:1pksute7pasie.9eglznqt557g.dlg@40tude.net...> > Any ideas how to improve it? I have read this paper: >Hi Frank, Google for Sunderland algorithm and/or the sine phase difference algorithm. HTH, Syms. http://groups.google.com/group/comp.arch.fpga/browse_thread/thread/702e081f02d6124/fd9afb0c72f61276?lnk=st&q=#fd9afb0c72f61276






