C/C++ code for Vitis HLS can use std::complex<T>
or hls::x_complex<T>
to model complex signals for xmcImportFunction
blocks. However, Vitis HLS does not support streaming std::complex<T>
variables unless <T> is ap_fixed<..>
or ap_int<..>
. Large array variables that are non-streaming can use
significant hardware resoources.
The code generated by Model Composer uses hls::x_complex
for
representing complex signals. If your imported C/C++ block function is modeled with
std::complex
, when generating the output code Model Composer will
automatically insert hls::x_complex
-to-std::complex
adapters to convert the complex types for the block ports.
Importing functions that use std::complex
is
still supported. However, if the imported function has non-scalar argument of data type
std::complex<T>
a warning message will be
issued during code generation that indicates that rewriting the function using hls::x_complex
will improve the quality of results and
allows streaming of complex variables.
The C/C++ code must also include the required header file for the complex type
declaration. For the hls::x_complex
type, the xmcImportFunction
command must also include ‘$XILINX_VIVADO/include’ search path for the hls_x_complex.h
header file. For example, the following
imports the complex_mult
function, and specifies the
needed include path:
xmcImportFunction('my_lib',{'complex_mult'}, 'complex_mult.h', {}, {'$XILINX_VIVADO/include'});
Example Functions Using Complex Types
#include "hls_x_complex.h"
hls::x_complex<double>
complex_mult(hls::x_complex<double> in1, hls::x_complex<double> in2)
{ return in1 * in2; }
#include <complex>
std::complex<double>
complex_mult2(std::complex<double> in1, std::complex<double> in2)
{ return in1 * in2; }
#include <complex>
void
complex_mult3(std::complex<double> in1, std::complex<double> in2, std::complex<double> &out1)
{ out1.real(in1.real() * in2.real() - in1.imag() * in2.imag());
out1.imag(in1.real() * in2.imag() + in1.imag() * in2.real()); }