HDL Coder 

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

This model implements a simple OFDM transmitter and receiver. The OFDM receiver part contains a 512point Radix2 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 512point 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'; open_system(modelname);
Serial FFT Block Specification
CooleyTukey Radix2 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 512point 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 512element vector at the sample rate of 512 by the Buffer block.
open_system([modelname '/deserialize']);
This FFT block implements the DecimationinTime FFT algorithm which requires bit reverseordered input data. So the naturalordered input data will pass through the stage Start_BitReverse in the beginning.
open_system([modelname '/FFT_512Pt_EML_Serial/Serialized_FFT']);
The serial FFT block is composed of log2(512)= 9 stages of radix2 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 8point 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.
Each radix2 FFT stage includes one radix2 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 radix2 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. %#codegen
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 512Point Serial FFT example.