How to generate sine wave in FPGA?
Here are the most practical ways to generate a sine wave on an FPGA—from “quick & clean” to “resource-lean.” I’ll give you design rules, formulas, and drop-in HDL.
The main approaches (pick one)
| Method | When to use | Notes |
|---|---|---|
| DDS/NCO + LUT | Easiest, precise frequency control | Phase accumulator → lookup table. Best with an external DAC or 1-bit ΣΔ + RC. |
| CORDIC | You want to save BRAM / make sin/cos on the fly | Uses add/shift stages; needs scaling factor compensation. |
| PWM or ΣΔ DAC | No external DAC available | Filter the pin with RC/active LPF. ΣΔ generally cleaner than plain PWM. |
1) DDS / NCO + LUT (golden path)
How it works
-
Phase accumulator:
phase <= phase + phase_inc; -
Top M bits of
phaseindex a sine LUT (ROM/BRAM). -
Frequency:
-
Resolution example (N=32, fclk=100 MHz): ~0.0233 Hz steps.
Compute phase_inc: round(f_out * 2^N / f_clk)
– 1 MHz @ 100 MHz, N=32 → 42949673
– 440 Hz @ 100 MHz, N=32 → 18898
Minimal SystemVerilog (NCO + LUT, optional linear interpolation)
Notes
-
If you prefer quarter-wave LUT to save BRAM: store 1/4 cycle and mirror/negate by the two MSBs (quadrant).
-
To output signed samples, center them around 0 (e.g., subtract 2^(AMP_BITS-1)).
-
For sin & cos, just tap different phase offsets (cos = sine with +90° phase).
Getting it out of the FPGA
-
Best quality: send samples to a parallel or SPI DAC, then analog-filter.
-
No DAC? Use a 1-bit ΣΔ DAC to a pin + RC/active low-pass filter (see below).
-
Clocking: Derive
f_clkfrom a PLL/MMCM with low jitter if spurs matter.
2) 1-bit ΣΔ DAC (cleaner than PWM)
A simple second-order ΣΔ pushes noise up in frequency; RC filter recovers the sine.
RC example for ~10 kHz cutoff: R=3.3 kΩ, C=4.7 nF (fc ≈ 10.3 kHz). Use a higher ΣΔ clock (e.g., 25–100 MHz) so most noise is above the audio band. For better THD/IMD, consider a 2-pole or active LPF.
3) CORDIC (no LUT)
Computes sin/cos by iterative rotate-add-shift. Great when BRAM is tight or you need variable amplitude/phase with small footprint.
-
Scale factor: rotation mode gains 1/K ≈ 1.64676; compensate by pre-scaling inputs or right-shifting after the pipeline (K ≈ 0.607252935).
-
Latency: ≈ number of iterations (e.g., 16–20 stages), but fully pipelinable (1 result/cycle).
-
Excellent for NCO/mixer chains (sin/cos from a single phase word).
4) Plain PWM (works, but noisier)
-
Use a fast carrier (e.g., ≥200 kHz) and modulate duty with your sine samples.
-
THD is generally worse than ΣΔ; filter must strongly attenuate the carrier.
Practical design checklist
-
Pick your clock (
f_clk) and accumulator width (N). Wider N → finer frequency steps & lower phase-truncation spurs. -
LUT depth vs. spurs: 1–4 k points is typical. Interpolation (even 4 frac bits) helps a lot.
-
Dither the truncated phase bits to reduce pattern spurs if needed.
-
Amplitude scaling: fixed-point multiply your sine by a gain for volume control/AM.
-
Output stage: prefer a real DAC if you need low noise; otherwise ΣΔ + LPF.
-
Constraints: add timing constraints for the NCO/ΣΔ paths; keep ROM and adders near each other to meet Fmax.
Tiny “full path” example (NCO → ΣΔ → pin)
Hardware: route audio_pin through R=3.3 kΩ to an RC low-pass (e.g., 3.3 kΩ + 4.7 nF to GND). For line-level, buffer with an op-amp LPF.
.jpg)
评论
发表评论