Home
Welcome
Information


FPGA projects
Basic
Music box
LED displays
Pong game
R/C servos
Text LCD module
Quadrature decoder
PWM and one-bit DAC
Debouncer
Crossing clock domains
External contributions

Interfaces
RS-232
JTAG
I2C
EPP
SPI
PCI
PCI Express
10BASE-T

Advanced
Digital oscilloscope
Graphic LCD panel
Direct Digital Synthesis
CNC steppers
Spoc CPU core

Hands-on
A simple oscilloscope


FPGA introduction
What are FPGAs?
How FPGAs work
Internal RAM
FPGA pins
Clocks and global lines
Download cables
Configuration
Learn more

FPGA software
Design software
Pin assignment
Design-entry/HDL
Simulation/HDL
Synthesis and P&R

FPGA electronic
SMD technology
Crystals and oscillators

HDL info
HDL tutorials
Verilog tips
VHDL tips

Quick-start guides
ISE
Quartus

Site
News
FPGA links
HDL tutorials
Forum


Direct Digital Synthesis (DDS) - Phase accumulator

Phase accumulator

The second DDS trick is a long phase accumulator. It allows the DDS output signal frequency to be very flexible.

To see how it works with an example, let's start with this simple code.

reg [10:0] cnt;   // 11 bits counter
always @(posedge clk) cnt <= cnt + 11'h1;

sine_lookup my_sine(.clk(clk), .addr(cnt), .value(sine_lookup_output));

The counter is actually a "phase accumulator". That's because each time it increments, it moves the sine by 360°/2048=0.175°

So let's rename the counter to a better name.

reg [10:0] phase_acc;   // 11 bits
always @(posedge clk) phase_acc <= phase_acc + 11'h1;

sine_lookup my_sine(.clk(clk), .addr(phase_acc), .value(sine_lookup_output));

Now, if we want to double the frequency of the sine output, we increment the phase accumulator by two instead of one.

always @(posedge clk) phase_acc <= phase_acc + 11'h2;

But if we want to cut the frequency in half? We are out of luck as we can't increment the phase accumulator by 0.5 (Verilog supports integer numbers only). What we need is more resolution in the phase accumulator.

Let's see how it is done by adding more bits to the phase accumulator, but for now in a way that gives the same output as with the 11 bits phase accumulator.

reg [14:0] phase_acc;   // 4 more bits, for a total of 15 bits
always @(posedge clk) phase_acc <= phase_acc + 15'd16;   // increment by 16 instead of 1

sine_lookup my_sine(.clk(clk), .addr(phase_acc[14:4]), .value(sine_lookup_output));   // shifted lookup address

Since we increment the counter by 16 and we use phase_acc[14:4] in the lookup address, we didn't change the output.
But having four more bits gives us a better resolution phase accumulator. Now we can certainly decrease the output frequency in half for example (increment the phase accumulator by 8 instead of 16).

Having increased the phase accumulator resolution by 16, we can have any multiple of the original sine frequency in 1/16th steps.
We could certainly have added more than four bits to the phase accumulator. Typical DDS implementations use very long bits phase accumulators to have extreme precision and resolution in the output frequencies available.

For example, with a 32 bits phase accumulator and a 100MHz clock, the frequency resolution of the output is 0.023Hz!
Here's a 32 bits phase accumulator used to generate a 440Hz signal from a 100MHz clock.

reg [31:0] phase_acc;   // 32 bits phase accumulator
always @(posedge clk) phase_acc <= phase_acc + 18898;   // 440Hz output when clocked at 100MHz

sine_lookup my_sine(.clk(clk), .addr(phase_acc[31:21]), .value(sine_lookup_output));

While 440Hz is pretty slow, output frequencies up to 50MHz (or close to that) are attainable with the above code. Just modify the phase accumulator increment.



>>> NEXT: Direct Digital Synthesis (DDS) - Interpolation >>>



This page was last updated on November 17 2008.