HDL Coder

OFDM Receiver with 512-Point Serial FFT

This example shows how to use HDL Coder™ to check, generate, and verify HDL code for a 512-point complex serial FFT block built using the MATLAB Function blocks and Simulink® blocks.


This model implements a simple OFDM transmitter and receiver. The OFDM receiver part contains a 512-point Radix-2 complex FFT to convert signal back to the frequency domain. There are two FFT implementations in this model:

  • The Behavioral FFT block is the complex FFT block in DSP System Toolbox™ library. It calculates a 512-point vector input each sample and works at a sample rate of 512.

  • The FFT_512Pt_EML_Serial block implements a serialized, streaming I/O FFT block using the MATLAB Function blocks and Simulink blocks and is suitable for hardware. This implementation accepts streaming complex input data and generates streaming complex results continuously after the initial pipelining latency.

The results of the two FFT implementations are shown to be equal after matching the initial pipelining latency.

Additional Requirements:

  • Communications System Toolbox

  • DSP System Toolbox

% To open this model, run the following commands:
modelname = 'hdlcoder_ofdm_fft_eml';

Serial FFT Block Specification

  • Cooley-Tukey Radix-2 Serialized FFT

  • Complex input, complex output

  • Streaming input, streaming output

  • Decimation in time

  • 512 point

  • Bit width: 12 bits

  • Initial pipelining latency: 1298 clock cycles

  • Input ports:

  • enable -> enable signal indicates the first valid input data

  • data_in -> streaming input data

  • Output ports:

  • data_en -> enable signal indicates the first valid output data

  • data_out -> streaming output data

  • index_out -> index of output data


The serialize block generates the streaming input data for the FFT block. The original 512-point vector input is converted to one data point per sample by the Unbuffer block.

open_system([modelname '/serialize']);

In the deserialize block, the streaming output of the serial FFT block is converted back to a 512-element vector at the sample rate of 512 by the Buffer block.

open_system([modelname '/deserialize']);

Bit Reversal

This FFT block implements the Decimation-in-Time FFT algorithm which requires bit reverse-ordered input data. So the natural-ordered input data will pass through the stage Start_BitReverse in the beginning.

open_system([modelname '/FFT_512Pt_EML_Serial/Serialized_FFT']);

Serial FFT Stages

The serial FFT block is composed of log2(512)= 9 stages of radix-2 butterfly units. These FFT stages are pipelined and connected in tandem.

open_system([modelname '/FFT_512Pt_EML_Serial/Serialized_FFT/FFT_Stages']);

The following picture shows a typical 8-point FFT with 3 (log2(8)) stages. Each stage uses 4 (8/2) butterfly units. A serial FFT implemented in this model uses only one butterfly resource for each stage of implementation.

FFT Stage

Each radix-2 FFT stage includes one radix-2 butterfly computing unit, memory blocks to cache the streaming data, a ROM to store the FFT twiddle factors, and control logic implemented in MATLAB Function blocks. The memory size of each stage equals the Stage Number.

open_system([modelname '/FFT_512Pt_EML_Serial/Serialized_FFT/FFT_Stages/FFT_Stage5']);


The radix-2 FFT butterfly algorithm is implemented in MATLAB file hdlcoder_serial_fft_butterfly.m on the MATLAB® path. All the Butterfly_FFT2_Computing_Unit blocks call this function.

The Butterfly_FFT2_Computing_Unit block uses a right shift to scale down the result data after every FFT stage to avoid overflow. In this model the Scale variable is set to 1 to turn off the scaling.

function [fft2_x, fft2_y] = fcn(fft2_u, fft2_v, fft2_twiddle)
% FFT2 Computing Unit
% Scale down number for this stage. Need to be power of 2.
Scale = 1;
% Call function in MATLAB file hdlcoder_serial_fft_butterfly_scale.m on path
[x, y] = hdlcoder_serial_fft_butterfly(fft2_u, fft2_v, fft2_twiddle);
% scaling down by 2 for each FFT2 stage.
fft2_x = bitsra(x, log2(Scale));
fft2_y = bitsra(y, log2(Scale));
function [x, y] = hdlcoder_serial_fft_butterfly(u, v, twiddle)
% FFT2 butterfly block
% This function is used in hdlcoder_ofdm_fft_eml example model.
nt = numerictype(u);
fm = fimath(u);
% multiply twiddle and butterfly.
twv = fi(v * twiddle, nt, fm);
x = fi(u + twv, nt, fm);
y = fi(u - twv, nt, fm);

Check, Generate and Verify HDL

checkhdl( [modelname '/FFT_512Pt_EML_Serial']);
makehdl(  [modelname '/FFT_512Pt_EML_Serial']);
makehdltb([modelname '/FFT_512Pt_EML_Serial']);

This concludes the OFDM Receiver with 512-Point Serial FFT example.