What is DDS?
The objective of DDS is to provide a highly flexible and accurate analog/digital output generation mechanism. It excels at producing signals with extremely sensitive timing requirements, like frequency sweeps and high-frequency voltage switching (>1MHz). Before learning how to design a basic DDS engine, let's review the basics of traditional output engines and the pitfalls they present with highly dynamic output requirements.
Traditional Output Engines: Data Buffering
Data is continuously buffered and maintained to produce a desired output
The low-level drivers will constantly index through samples until the buffer is empty or the output task is stopped. It is up to the host environment to constantly supply the driver with new samples or the engine will stop and fail. These are easy to implement, maintain, and are highly effective with known and slow signals. Highly dynamic signals can be produced in this environment, but they are immutable the moment they enter the buffer. If your system requires rapid response times from the output engine, this buffering scheme will cause significant issues. To increase the responsiveness of the generation, the buffer needs to made smaller or the output sampling rate increased. To keep up with those changes, the host maintenance routine for the buffer data needs to run faster. This increases CPU usage on the host and altogether is resource-limited significantly. Additionally, numerous engines will not let you perform these operations continuously, needing tasks to be stopped, reconfigured, and restarted to generate the new output.
Needless to say, dynamic signal generation is clearly not well supported by this kind of engine.
Note: Regeneration in DAQmx allows for something very similar to DDS. It's only available on a specific subset of DAQmx output modules, but provides a similar non-FPGA solution to cyclic output data. It has it's own special variety of drawbacks and benefits that I will not explore at this time.
Direct Digital Synthesis (DDS): Continuous Table-Based Generation
A 1D table of data is constantly looped through at high speeds to produce an output
The general idea of DDS is to build a table of samples (Sample Table) ahead of time and to give your output engine instructions on how to move through the table to produce the desired output. This is done through a few additional components: A Source Clock, Accumulator, and a Tuning Word.
Sample Table – Holds the waveform/data you want to output.
Source Clock – Supplies the base rate for indexing through the Sample Table.
Tuning Word – An additional modifier that tells the engine how far to move through Sample Table on each tick of the Source Clock.
Accumulator – Remembers where the engine is in the Sample Table.
When used correctly, these pieces allow you to construct a basic DDS engine that can reliably produce highly complex and dynamic output signals at very little expense to the host environment. Changes to the output signal frequently only entail modifying one or two of the aforementioned components during runtime operation, which does not require the output engine to cease execution.
Stay tuned for Part II on Direct Digital Synthesis!
What Makes a DDS Engine?
- Design Guidelines
- Advantages and Disadvantages
- Example Implementation