When synthesis is performed, Vitis HLS uses the timing constraints specified by the clock, the delays specified by the target device together with any directives specified by you, to determine which hardware implementations to use for various operators in the code. For example, to implement a multiplier operation, Vitis HLS could use the combinational multiplier or use a pipeline multiplier.
The implementations which are mapped to operators during synthesis can be limited by specifying the ALLOCATION pragma or directive, in the same manner as the operators. Instead of limiting the total number of multiplication operations, you can choose to limit the number of combinational multipliers, forcing any remaining multiplications to be performed using pipelined multipliers (or vice versa).
The BIND_OP or BIND_STORAGE pragmas or directives are used to explicitly
specify which implementations to use for specific operations or storage types. The following
command informs Vitis HLS to use a two-stage pipelined
multiplier using fabric logic for variable c
. It is left to
Vitis HLS which implementation to use for variable d
.
int foo (int a, int b) {
int c, d;
#pragma HLS BIND_OP variable=c op=mul impl=fabric latency=2
c = a*b;
d = a*c;
return d;
}
In the following example, the BIND_OP pragma specifies that the add operation
for variable temp
is implemented using the dsp
implementation. This ensures that the operation is implemented
using a DSP module primitive in the final design. By default, add operations are implemented
using LUTs.
void apint_arith(dinA_t inA, dinB_t inB,
dout1_t *out1
) {
dout2_t temp;
#pragma HLS BIND_OP variable=temp op=add impl=dsp
temp = inB + inA;
*out1 = temp;
}
Refer to the BIND_OP or BIND_STORAGE pragmas or directives to obtain details on the implementations available for assignment to operations or storage types.
In the following example, the BIND_OP pragma specifies the multiplication for
out1
is implemented with a 3-stage pipelined multiplier.
void foo(...) {
#pragma HLS BIND_OP variable=out1 op=mul latency=3
// Basic arithmetic operations
*out1 = inA * inB;
*out2 = inB + inA;
*out3 = inC / inA;
*out4 = inD % inA;
}
If the assignment specifies multiple identical operators, the code must be
modified to ensure there is a single variable for each operator to be controlled. For example,
in the following code, if only the first multiplication (inA * inB
) is to be
implemented with a pipelined multiplier:
*out1 = inA * inB * inC;
The code should be changed to the following with the pragma specified on the
Result_tmp
variable:
#pragma HLS BIND_OP variable=Result_tmp op=mul latency=3
Result_tmp = inA * inB;
*out1 = Result_tmp * inC;