The FFT function with array arguments is defined in the HLS namespace and can be called as follows:
hls::fft<STATIC_PARAM> (
INPUT_DATA_ARRAY,
OUTPUT_DATA_ARRAY,
OUTPUT_STATUS,
INPUT_RUN_TIME_CONFIGURATION);
The STATIC_PARAM
is the static
parameterization struct that defines the static parameters for the FFT.
Both the input and output data are supplied to the function as arrays
(INPUT_DATA_ARRAY
and OUTPUT_DATA_ARRAY
). In the final implementation, the ports on the FFT
RTL block will be implemented as AXI4-Stream
ports. AMD recommends
set_directive_dataflow
), and to specify both arrays as streaming using
the set_directive_stream
command. The FFT cannot be
used in a region which is pipelined. If high-performance operation is required, in
particular by avoiding clock cycles in which the FFT is stalled without processing
data, then: - The entire design hierarchy including and above the FFT must be either dataflow regions or functions containing only dataflow-in-loop.
- The depth of all FIFOs must be enough to avoid blocking in cosimulation, as described in Cosim Deadlock Detection.
- All dataflow processes throughout the hierarchy must contain only:
- Pipelines with the rewind option
- Or pipelined loops with the rewind option
The data types for the arrays can be float
or
ap_fixed
.
typedef float data_t;
complex<data_t> in_fft[FFT_LENGTH];
complex<data_t> out_fft[FFT_LENGTH];
To use fixed-point data types, the Vitis HLS arbitrary precision type ap_fixed
should be
used.
#include "ap_fixed.h"
typedef ap_fixed<FFT_INPUT_WIDTH,1> data_in_t;
typedef ap_fixed<FFT_OUTPUT_WIDTH,FFT_OUTPUT_WIDTH-FFT_INPUT_WIDTH+1> data_out_t;
#include <complex>
typedef hls::x_complex<data_in_t> cmpxData;
typedef hls::x_complex<data_out_t> cmpxDataOut;
In both cases, the FFT should be parameterized with the same correct data sizes. In the case of floating point data, the data widths will always be 32-bit and any other specified size will be considered invalid.
Multi-Channel FFT
The multichannel functionality of the FFT can be used by using two-dimensional arrays for the input and output data. In this case, the array data should be configured with the first dimension representing each channel and the second dimension representing the FFT data.
typedef float data_t;
static complex<data_t> in_fft[FFT_CHANNELS][FFT_LENGTH];
static complex<data_t> out_fft[FFT_CHANNELS][FFT_LENGTH];
The FFT core consumes and produces data as interleaved channels (for example, ch0-data0, ch1-data0, ch2-data0, etc, ch0-data1, ch1-data1, ch2-data1, etc.). Therefore, to stream the input or output arrays of the FFT using the same sequential order that the data was read or written, you must fill or empty the two-dimensional arrays for multiple channels by iterating through the channel index first, as shown in the following example:
cmpxData in_fft[FFT_CHANNELS][FFT_LENGTH];
cmpxData out_fft[FFT_CHANNELS][FFT_LENGTH];
// Read data into FFT Input Array
for (unsigned i = 0; i < FFT_LENGTH; i++) {
for (unsigned j = 0; j < FFT_CHANNELS; ++j) {
in_fft[j][i] = in.read();
}
}
// Write data out from FFT Output Array
for (unsigned i = 0; i < FFT_LENGTH; i++) {
for (unsigned j = 0; j < FFT_CHANNELS; ++j) {
out.write(out_fft[j][i]);
}
}