Sinusoidal Generation in HDL
Show older comments
I am trying to generate an HDL-convertible sinusoidal wave at ±2.5 MHz using the unsigned fixdt(0,12,11) data type, but I am unable to achieve my target Signal-to-Noise Ratio (SNR) of >72 dB using the standard NCO block. How can I correctly configure the NCO parameters to meet this SNR requirement, or what alternative method should I use for this HDL implementation?



1 Comment
Answer from AI:
To achieve an SNR of >72 dB with an HDL-convertible sinusoidal wave, your current data type configuration fixdt(0,12,11) acts as the primary bottleneck.
In quantized digital synthesis (like a Numerically Controlled Oscillator / NCO), the theoretical peak Signal-to-Quantization-Noise Ratio (SQNR) for an B-bit output signal is bounded by the well-known formula:
For a 12-bit output (
), the absolute maximum theoretical SNR is 74 dB under perfect conditions (infinite phase resolution, no interpolation loss). However, in a standard NCO, phase truncation noise and lookup table quantization drop the practical SNR well below this ideal limit—often down to 60–68 dB, making it impossible to reliably exceed 72 dB.
Here is how to resolve this constraint and reconfigure your system for HDL generation.
Method 1: Upgrade the Word Length (Recommended)
If your hardware architecture allows it, the most robust solution is to increase your output word length to 14 or 16 bits. This provides the necessary headroom to clear the 72 dB threshold comfortably.
- fixdt(0,14,13): Theoretical maximum
dB. Practical NCO SNR
dB. - fixdt(0,16,15): Theoretical maximum
dB. Practical NCO SNR
dB.
Note on Unsigned Format: Since you are using an unsigned type (fixdt(0,12,11)), your sine wave must be biased (offset) so that it spans from 0 to 2.0 (with 1.0 as the midpoint). Ensure your NCO or subsequent logic accounts for this
DC bias.
Method 2: Standard NCO Parametric Optimization
If you are strictly locked into a 12-bit output, you must eliminate phase truncation noise completely to get as close to the 74 dB physical limit as possible. Configure the Simulink/HDL Coder NCO block with the following parameters:
1. Quantizer Accumulator Output: Enable this. You must truncate the phase accumulator to match the lookup table address size exactly.
2. Number of Quantizer Bits: Set this to 14 bits or higher. A larger phase resolution reduces the spurious free dynamic range (SFDR) impacts.
3. Dither Generation: Turn Dither ON.
- Why: Without dithering, phase truncation creates periodic errors that manifest as discrete, high-power spectral spurs (lowering your effective SNR/SFDR).
- Effect: Dithering adds a small amount of pseudo-random noise to the phase before quantization. This breaks up the periodic spurs and spreads the noise energy uniformly across the spectrum as white noise, raising your SNR closer to the true mathematical maximum.
4. Lookup Table Compression: Choose None or Quarter Wave. Quarter-wave compression saves hardware area on the FPGA/ASIC without degrading the SNR performance.
Method 3: The CORDIC Alternative (High Precision)
If large lookup tables are costing too many memory resources (BRAMs) on your hardware, use the HDL Coder CORDIC Sine/Cosine block instead of a standard NCO.
- How it works: CORDIC uses a shift-and-add iterative algorithm rather than a memory-based lookup table.
- Configuration: Set the number of iterations to 14 or 16. Even with a 12-bit output data type, the internal high-precision iterations minimize calculation noise, allowing the output to tightly hug the theoretical
dB envelope.
Summary Checklist for >72 dB SNR
Parameter / Approach Target Setting Impact
Output Data fixdt(0,14,13) or Highest Impact. Drastically
Type fixdt(0,16,15) lowers the quantization noise floor.
Phase Dithering Enabled Spreads systematic harmonic spurs into
benign white noise.
Quantizer Bits
Bits Reduces phase error variance prior to table
lookup.
Architecture Choice CORDIC (Iterative) Replaces memory blocks with logic fabric
while maintaining high precision.
Answers (1)
Dharma Bade
on 9 Nov 2026 at 9:28
0 votes
A 12 bit output can reach 72 dB, but the ideal limit for 12 bits is only about 74 dB. So the other noise sources in the NCO have to stay small. The default settings don't do this. Change these:
- Phase word length (Data Types tab): 14 or more. The default of 12 limits SNR to about 67 dB.
- LUT compression: off. It cost me 1 to 4 dB.
- Dither: None. It helps spurs, not SNR.
- Accumulator: 32 bits.
- Output: word length 12, fraction length 11.
- ±2.5 MHz: Complex exponential output, with a negative phase increment for -2.5 MHz.


The NCO output is always signed. To get fixdt(0,12,11), add the constant 1+1i and set the output type of the Add block to fixdt(0,12,11). This only flips the MSB, so nothing is lost. Avoid 0.5 + 0.5*sin, because that wastes a bit.

With these settings I get about 72.6 dB, or 73.5 dB with a phase word length of 16.
Categories
Find more on Transforms in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!