The AMD FIR IP block can be called within a C++ design using the library hls_fir.h. This section explains how the FIR can be configured in your C++ code.
To use the FIR in your C++ code:
- Include the hls_fir.h library in the code.
- Set the default parameters using the library predefined struct
hls::ip_fir::params_t, or copy it as your own configuration struct.Important: The Vivado LogiCORE IP through its dialog wizard detects and prevents incompatibilities in settings. Check your own configuration struct parameters into these Vivado IP dialogs to avoid unsupported or faulty configurations. - Call the FIR function.
- Optionally, define a runtime input configuration to modify some parameters dynamically.
The following code examples provide a summary of how each of these steps is performed. Each step is discussed in more detail below.
First, include the FIR library in the source code. This header file resides in the include directory in the Vitis HLS installation area. This directory is automatically searched when Vitis HLS executes. There is no need to specify the path to this directory if compiling inside Vitis HLS.
#include "hls_fir.h"
Define the static parameters of the FIR. This includes such static
attributes such as the input width, the coefficients, the filter rate (single, decimation,
hilbert). The FIR library includes a
parameterization struct hls::ip_fir::params_t to
initialize all static parameters with default values.
In this example, the coefficients are defined as residing in array
coeff_vec and the default values for the number
of coefficients, the input width and the quantization mode are over-ridden using a
user-defined struct myconfig based on the
predefined struct.
struct myconfig : hls::ip_fir::params_t {
coeff_vec[sg_fir_srrc_coeffs_len] = { ... };
num_coeffs = sg_fir_srrc_coeffs_len;
input_width = INPUT_WIDTH;
quantization = hls::ip_fir::quantize_only;
OVERRIDE(coefficient_width) = COEFF_WIDTH; // errors out and suggests correct spelling: "no member named 'coefficient_width' in 'hls::ip_fir::params_t'; did you mean 'coeff_fract_width'?"
num_coefficients = sg_fir_srrc_coeffs_len; // errors out with confusing message: "a type specifier is required for all declarations"
Create an instance of the FIR function using the HLS namespace with
the defined static parameters (myconfig in this
example) and then call the function with the run
method to execute the function. The function arguments are, in order, input data and
output data.
static hls::FIR<param1> fir1;
fir1.run(fir_in, fir_out);
Optionally, a runtime input configuration can be used. In some modes of the FIR, the data on this input determines how the coefficients are used during interleaved channels or when coefficient reloading is required. This configuration can be dynamic and is therefore defined as a variable. For a complete description of which modes require this input configuration, refer to the FIR Compiler LogiCORE IP Product Guide (PG149).
When the runtime input configuration is used, the FIR function is called with three arguments: input data, output data, and input configuration.
// Define the configuration type
typedef ap_uint<8> config_t;
// Define the configuration variable
config_t fir_config = 8;
// Use the configuration in the FIR
static hls::FIR<param1> fir1;
// Define input and output data types
const int axis_data_width = ((myconfig::data_width+7)>>3<<3); // AXIS data width rounded up to byte boundary
const int axis_output_width = ((myconfig::output_width+7)>>3<<3); // AXIS data width rounded up to byte boundary
typedef ap_fixed<axis_data_width, axis_data_width - myconfig::data_fract_width> in_data_t;
typedef ap_fixed<axis_output_width, axis_output_width - myconfig::output_fract_width> out_data_t;
// input and output data should be declared locally or as arguments as follows:
// in_data_t fir_in[_CONFIG_T::data_length * _CONFIG_T::num_channels];
// out_data_t fir_out[_CONFIG_T::output_length * _CONFIG_T::num_channels];
fir1.run(fir_in, fir_out, &fir_config);
hls::stream for arguments. Refer to Vitis HLS Introductory Examples for more information. - Observe that for SSR==1 and interpolation_rate==1, the
fir_inandfir_outformal arguments can either have an array data type. In this case they can be passed as actual arguments:- Local arrays with #pragma HLS stream
- Top arguments with #pragma HLS interface
ap_fifo
-
hls::streamData type, in this case they can be passed as actual arguments:- Local
hls::streams - Top
hls::streamarguments #pragma HLS interfaceap_fifo
- Local
- Observe that for SSR>1 or interpolation_rate>1. the fir_in and fir_out arguments
must only satisfy the usual C++ type constraints and can have any interface type
for arrays and
hls::streams.