A Numerically-Controlled Oscillator (NCO) is a digital signal generator that produces a sine, cosine, or other periodic waveform at a frequency determined by a programmable integer increment added to a phase accumulator on each clock cycle. The output frequency is set entirely in the digital domain, making NCOs highly stable, repeatable, and easy to tune; analog components such as a DAC and reconstruction filter are typically still required to produce a physical analog output.
In practice
The core of an NCO is a phase accumulator, typically 24 to 48 bits wide, that increments by a fixed tuning word (phase increment) every clock cycle. The upper bits of the accumulator commonly index into a sine lookup table (LUT) to produce the output sample, though other methods such as CORDIC, polynomial approximation, or quarter-wave tables are also used. Output frequency is f_out = (tuning_word / 2^N) * f_clk, where N is the accumulator width and f_clk is the system clock. Frequency resolution can be made arbitrarily fine by widening the accumulator: a 32-bit accumulator clocked at 100 MHz gives a resolution of about 0.023 Hz.
In embedded communications systems, NCOs appear in software-defined radio (SDR) receivers and transmitters, FSK/PSK modulators, tone generators, and clock recovery circuits. FPGAs (Xilinx, Intel/Altera) and DSP-capable MCUs (TI C2000, STM32 with CORDIC accelerator) are common implementation targets. Dedicated DDS ICs such as the Analog Devices AD9850 and AD9914 integrate the accumulator, LUT, and DAC on a single chip and are driven over SPI or parallel interfaces from an MCU.
A common pitfall is ignoring phase truncation spurs. Only the top M bits of the N-bit accumulator address the sine table, discarding the lower (N-M) bits. This introduces periodic phase error that creates spurious tones (spurs) in the output spectrum. Spur levels depend on table size, accumulator width, waveform symmetry, and implementation details, but increasing M directly improves spur-free dynamic range. Techniques such as phase dithering or Taylor series correction can reduce spurs further. The blog post "Feedback Controllers - Making Hardware with Firmware. Part 7. Turbo-charged DSP Oscillators" covers efficient firmware-side NCO implementations including CORDIC-based approaches that avoid a large LUT entirely.
NCOs are also the tunable element inside digital phase-locked loops (DPLLs). A phase detector compares the NCO output to an incoming reference, and a loop filter drives the tuning word, pulling the NCO into lock. The blog series "Digital PLL's -- Part 1" and "Digital PLL's, Part 3 -- Phase Lock an NCO to an External Clock" walk through implementing this structure on FPGAs and DSP platforms, covering loop bandwidth selection, phase detector design, and locking behavior.
Frequently asked
What is the difference between an NCO and a DDS?
The terms are often used interchangeably, but there is a technical distinction. An NCO is the digital
phase-accumulator-plus-LUT block that produces digital samples. A Direct Digital Synthesizer (DDS) is a complete system that includes the NCO plus a
DAC and reconstruction filter to produce an analog output. In common usage, especially for dedicated ICs like the AD9850, 'DDS' usually implies the full analog-output chain.
How do I choose the accumulator width?
Accumulator width N determines frequency resolution: resolution = f_clk / 2^N. A 32-bit accumulator at 100 MHz gives ~0.023 Hz resolution; a 48-bit accumulator gives sub-millihertz resolution. Wider accumulators cost more logic or memory but do not by themselves reduce spurs -- spur performance depends on how many of those bits address the sine table.
What causes spurs in NCO output, and how can I reduce them?
Phase truncation is the dominant spur source in a table-lookup NCO. Only the top M bits of the accumulator index the table; the discarded lower bits create a periodic phase error. Increasing M (larger table) directly improves spur-free dynamic range (SFDR), at the cost of memory. Alternatives include phase dithering (adding a pseudo-random LSB to break the periodicity), Taylor series phase-to-amplitude correction, or replacing the table with a CORDIC engine, which has no truncation spurs of this type.
Can I implement an NCO on a small MCU without an FPU or DSP instructions?
Yes, though at reduced sample rates. A 32-bit
phase accumulator can be maintained with ordinary integer addition on any MCU. The sine table can be stored in flash. On an 8-bit AVR or PIC, interrupt-driven NCOs producing audio-range tones (up to a few tens of kHz) are practical. On Cortex-M MCUs with the CMSIS DSP library or a CORDIC peripheral (available on some STM32G4 and STM32H7 variants, for example), much higher output rates are achievable.
How is an NCO used in a digital PLL?
The NCO replaces the voltage-controlled oscillator (VCO) of an analog
PLL. A digital
phase detector measures the phase difference between the NCO output and an incoming reference signal. A loop filter (often a simple
IIR) smooths that error and drives the NCO tuning word, pulling the output frequency and phase into lock with the reference. The blog posts 'Digital PLL's -- Part 1' and 'Digital PLL's, Part 3 -- Phase Lock an NCO to an External Clock' cover the design and implementation of this scheme in detail.
Differentiators vs similar concepts
NCO vs DDS: An NCO is the digital subsystem (
phase accumulator plus waveform mapping). DDS typically refers to a complete synthesizer that adds a
DAC and analog output filter; many DDS ICs integrate all three stages. In firmware-only contexts, 'NCO' is the more precise term. NCO vs
PLL: A PLL locks a local oscillator (analog VCO or digital NCO) to an external reference via feedback; an NCO alone is open-loop and free-running at whatever frequency its tuning word selects. When an NCO is used as the tunable element inside a feedback loop, the combination is called a digital PLL (DPLL) or all-digital PLL (ADPLL).