cordic_fft / cordic_ifft

cordic_fft / cordic_ifft

Radix-2 DIT FFT and IFFT for N=8. Twiddle factors computed in hardware via cordic_core rotation mode.


Implementation

FFT

Algorithm: In-place Radix-2 DIT. One butterfly per clock, sequential stages.

Twiddle generation: N/2 cordic_core instances launched in parallel on start. Each computes W_N^k = cos(2πk/N) − j·sin(2πk/N) by rotating x_init=K_SCALE, y_init=0, z=−2πk/N. All twiddles are ready before the first butterfly stage.

CORDIC rotation converges only for |z| < π/2. Angles outside this range are folded at elaboration time via localparam: if angle < −π/2, use angle + π and negate both outputs since cos(a+π) = −cos(a), sin(a+π) = −sin(a).

Fixed-point chain:

  • Data: Q1.30 (WIDTH=32, ANGLE_FRAC_BITS=30)
  • Twiddle: x_out >> 16 = Q1.14 (x_out = cos × 2^30 → shift gives cos × 2^14)
  • Butterfly multiply: Q1.30 × Q1.14 >> 14 = Q1.30
  • Guard: >> 1 per stage against overflow
  • Output scale: X[k] = DFT(x) / N

FSM:

  1. S_WTTW — wait for all N/2 twiddle cores
  2. S_BITREV — bit-reversal, one conditional swap per clock
  3. S_BF — butterfly, iterates stage 0..N_LOG2−1, bfcnt 0..N/2−1
  4. S_DONE — pulse valid, drop busy

Latency (N=8, ITER=16): 19 cycles (twiddle) + 8 (bit-reversal) + 12 (3 stages × 4 butterflies) = ~39 cycles.

IFFT

Wrapper around cordic_fft using the identity:

IFFT(X) = conj( FFT( conj(X) ) ) / N

cordic_fft already divides by N. Conjugation is two wire negations — din_im negated on input, dout_im negated on output. No extra logic. Output scale: x[n] = IDFT(X) / N.


Interface

Both modules share the same interface:

cordic_fft #(.N_LOG2(3), .WIDTH(`CORDIC_WIDTH), .ITER(`CORDIC_ITER)) u (
    .clk, .rst_n,
    .load_en, .din_re, .din_im, .din_idx,  // load before start
    .start,
    .busy, .valid,
    .rd_idx, .dout_re, .dout_im            // combinatorial readback
);

Load N samples via load_en/din_re/din_im/din_idx, pulse start, wait for valid, read via rd_idx.


Directed Tests

FFT — sim/fft_tb.v

Real-valued inputs. Reference = exact DFT / N.

Test Input Expected
1 Impulse at n=0 All bins = 1/N
2 DC (all ones) X[0]=1, rest≈0
3 cos(2π·1·n/N) X[1]=X[7]=0.5, rest≈0
4 cos(2π·2·n/N) X[2]=X[6]=0.5, rest≈0
Test Max error
1 0
2 9.2e-05
3 3.4e-05
4 3.1e-05

IFFT — sim/ifft_tb.v

Reference = exact IDFT / N.

Test Input X[k] Expected x[n]
1 delta[k=0] 1/N uniform
2 All ones delta[n=0]
3 delta[k=1] + delta[k=7] cos(2π·n/N) / 4
4 Round-trip: cos → FFT → IFFT x[n] / N
5 Round-trip: complex exp → FFT → IFFT x[n] / N
Test Max error
1 0
2 9.2e-05
3 3.1e-05
4 1.1e-05
5 7.6e-06

Round-trip error (tests 4–5) is lower than single-pass — quantization errors partially cancel through conjugation symmetry.


Verification — FFT

Stress Tests

Case Max error Mean error SNR
impulse 0.00e+00 0.00e+00 ∞ dB
all_ones 1.29e-04 3.92e-05 76.5 dB
all_zeros 0.00e+00 0.00e+00 ∞ dB
pure_tone 3.62e-05 2.08e-05 80.8 dB
max_pos 1.29e-04 3.92e-05 76.5 dB
max_neg 1.29e-04 3.92e-05 76.5 dB
alternating 1.29e-04 3.92e-05 76.5 dB
ramp 4.32e-05 2.43e-05 78.6 dB

Impulse and all-zeros are exact (zero error) as expected — no butterfly arithmetic is exercised for trivial spectra.

Monte-Carlo Results (200 tests, 1600 samples)

Max error         : 0.000083
Mean error        : 0.000021
RMS error         : 0.000024
SNR  mean/min/max : 78.79 / 74.27 / 84.46 dB
SFDR (random)     : 1.11 dBc mean
SFDR (pure-tone)  : 87.08 dBc avg across bins
Phase err mean/max: 0.0082 / 0.7267 deg

SNR ~79 dB is consistent with the theoretical limit for a 30-bit fractional CORDIC implementation. The SFDR of 87 dBc under pure-tone excitation is measured using the correct conjugate-pair metric for a real-input FFT — the symmetric bins (k, N-k) are treated as the fundamental, not as spurs. Phase error mean of 0.008° is negligible.

Per-Bin Mean Error

Bin Mean Error
0 2.4e-05
1 1.8e-05
2 2.3e-05
3 1.7e-05
4 2.4e-05
5 1.9e-05
6 2.3e-05
7 1.6e-05

Even-indexed bins carry slightly higher error than odd-indexed bins — a known butterfly symmetry pattern in Cooley-Tukey at small N. The variation is minor (~30%) and within expected fixed-point rounding behaviour.

Error Distribution

FFT Error Distribution

Errors are tightly concentrated near zero with a long tail — typical of fixed-point CORDIC quantisation noise. The distribution is consistent across all 200 trials.

SNR Distribution

FFT SNR Distribution

SNR ranges from 74 to 85 dB across random inputs, with mean ~79 dB. Variation is driven by input-dependent signal power, not by implementation instability.

SFDR

FFT SFDR

Left panel shows SFDR distribution for random multi-tone inputs — low values here are expected as random inputs excite all bins simultaneously and there is no dominant fundamental. Right panel shows the meaningful measurement: SFDR for a single cosine tone at each bin, ~87 dBc uniformly, demonstrating clean twiddle computation with minimal spurious content.

Per-Bin Error

FFT Per-Bin Error

Phase Error Distribution

FFT Phase Error

Phase error mean of 0.008° across all active bins. Occasional outliers up to ~1° occur when the reference bin has small magnitude (denominator near zero in angle computation) — not representative of typical operation.

Error vs Input Amplitude

FFT Error vs Amplitude

Error is largely independent of input amplitude, confirming that the fixed-point noise floor is dominated by twiddle quantisation rather than input-level scaling.

Stress Test Max Errors

FFT Stress Tests

CORDIC Iteration Sweep

FFT Iteration Sweep

SNR converges monotonically with iteration count. At 4 iterations the design is already usable at ~23 dB; 12 iterations gives ~67 dB; 16 iterations reaches the fixed-point noise floor at ~79 dB. Further iterations yield no improvement as angle quantisation (30-bit) becomes the limiting factor.

Iterations Mean SNR
4 23.5 dB
8 40.3 dB
12 67.4 dB
16 79.2 dB

Verification — IFFT

Stress Tests

Case Max error Mean error SNR
dc_only 0.00e+00 0.00e+00 ∞ dB
single_tone 4.32e-05 2.77e-05 75.6 dB
all_ones_spec 1.29e-04 3.92e-05 76.5 dB
all_zeros_spec 0.00e+00 0.00e+00 ∞ dB
max_pos 1.29e-04 3.92e-05 76.5 dB
max_neg 1.29e-04 3.92e-05 76.5 dB
alternating 1.29e-04 3.92e-05 76.5 dB
random_phase 7.34e-05 2.58e-05 80.8 dB

DC-only and all-zeros inputs are exact. The IFFT is implemented as a thin conjugation wrapper over the FFT core, so its error floor matches the FFT directly.

Monte-Carlo Results (200 tests, 1600 samples)

Max error         : 0.000104
Mean error        : 0.000031
RMS error         : 0.000035
SNR  mean/min/max : 78.40 / 75.43 / 82.61 dB
Phase err mean/max: 0.0059 / 0.1514 deg

IFFT SNR (~78 dB) matches the FFT closely — expected since the IFFT adds no arithmetic beyond two wire negations. The slightly higher mean error vs FFT (~31e-06 vs ~21e-06) is due to the IFFT accepting complex spectrum inputs, which exercise more of the butterfly datapath.

Roundtrip Test (FFT → IFFT, 50 trials)

Roundtrip max error  : 0.000025
Roundtrip mean error : 0.000007
Roundtrip SNR mean   : 78.26 dB
Roundtrip SNR min    : 75.54 dB

Real inputs are passed through hardware FFT, then the spectrum is fed directly into hardware IFFT. The recovered signal achieves 78 dB SNR end-to-end. Roundtrip error (7e-06 mean) is lower than single-pass IFFT error (31e-06 mean) — CORDIC angle quantisation errors partially cancel through the conjugation symmetry of the roundtrip.

Per-Bin Mean Error

Sample Mean Error
0 3.9e-05
1 2.5e-05
2 3.4e-05
3 2.3e-05
4 4.0e-05
5 2.6e-05
6 3.3e-05
7 2.4e-05

Same even/odd alternating pattern as the FFT, consistent with shared butterfly structure.

Error Distribution

IFFT Error Distribution

SNR Distribution

IFFT SNR Distribution

Roundtrip Error and SNR

IFFT Roundtrip

Left panel shows roundtrip absolute error distribution — tightly concentrated below 2e-05. Right panel shows roundtrip SNR, mean 78 dB, confirming that FFT + IFFT in series introduces no significant error accumulation beyond the single-pass floor.

Per-Bin Error

IFFT Per-Bin Error

Phase Error Distribution

IFFT Phase Error

IFFT phase error (mean 0.006°, max 0.15°) is tighter than FFT (max 0.73°). The conjugate-symmetry path through the IFFT wrapper suppresses phase error buildup.

Error vs Input Amplitude

IFFT Error vs Amplitude

Stress Test Max Errors

IFFT Stress Tests

CORDIC Iteration Sweep

IFFT Iteration Sweep

IFFT convergence curve is nearly identical to the FFT — as expected for a wrapper implementation sharing the same CORDIC core.

Iterations Mean SNR
4 23.2 dB
8 40.4 dB
12 67.4 dB
16 78.5 dB

Summary

Metric FFT IFFT
SNR mean 78.8 dB 78.4 dB
SNR min 74.3 dB 75.4 dB
Max error 8.3e-05 1.0e-04
Mean error 2.1e-05 3.1e-05
RMS error 2.4e-05 3.5e-05
SFDR (pure-tone) 87.1 dBc — (complex output)
Phase err mean 0.008° 0.006°
Roundtrip SNR 78.3 dB
Iterations to floor 16 16