The FFT function with streaming interfaces is defined in the HLS namespace similarly to this:
template <typename PARAM_T>
void fft(hls::stream<complex<float or ap_fixed>> &xn_s,
hls::stream<complex<float or ap_fixed >> &xk_s,
hls::stream<ip_fft::status_t<CONFIG_T>> &status_s,
hls::stream<ip_fft::config_t<CONFIG_T>> &config_s);
and can be called as follows:
hls::fft<STATIC_PARAM> (
INPUT_DATA_STREAM,
OUTPUT_DATA_STREAM,
OUTPUT_STATUS_STREAM,
INPUT_RUN_TIME_CONFIGURATION_STREAM);
The STATIC_PARAM
is the static parameterization struct that defines
the static parameters for the FFT.
All input and outputs are supplied to the function as a hls::stream<>
. In the final implementation, the ports on the FFT
RTL block will be implemented as AXI4-Stream ports.
set_directive_dataflow
or #pragma HLS dataflow
. 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 input data and output data streams can be float
or ap_fixed
.
void fft_top(
bool direction,
complex<data_in_t> in[FFT_LENGTH],
complex<data_out_t> out[FFT_LENGTH],
bool &ovflo)
{
#pragma HLS dataflow
hls::stream<complex<data_in_t>> in_fft;
hls::stream<complex<data_out_t>> out_fft;
hls::stream<config_t> fft_config;
hls::stream<status_t> fft_status;
// convert inputs to hls::stream<> and generates fft_config stream based on input arguments
proc_fe(direction, fft_config, in, in_fft);
// FFT IP
hls::fft<config1>(in_fft, out_fft, fft_status, fft_config);
// convert fft result to outputs data type and sets output ovflo according to fft_status stream
proc_be(fft_status, ovflo, out_fft, out);
}
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 complex<data_in_t> cmpxData;
typedef 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.
Comparing Stream and Array
The following table shows the array example and stream example usage of the FFT IP. In both cases the dataflow hierarchy extends all the way to the top, without any sequential code (code that is not a dataflow region or a dataflow-in-loop function) and that copy-in and copy-out loops are pipelined with rewind.
hls::stream<>
or use the STREAM pragma or directive to the
same effect.FFT with Array Arguments | FFT with hls::stream<>
Arguments |
---|---|
|
|