This section describes mechanisms available to manipulate datapath for kernel variables.
The Intel® oneAPI DPC++/C++ Compiler provides FPGA extension fpga_reg() that you can include in your kernel code.
The fpga_reg() function directs the compiler to insert at least one register between the operand and the return value of the function call. In general, it is not necessary to include the fpga_reg() function in your kernel code to achieve desired performance.
Intel® strongly recommends that you use the fpga_reg() function only if you are experienced in using the Intel® Quartus® Prime Pro Edition software performing advanced optimization for a specific target device. You must have sufficient knowledge about the placement of portions of the datapath on an FPGA device.
T fpga_reg(T op)
Where, T may be any sized type, such as standard SYCL* device data types, or a user-defined struct containing SYCL types.
Consider the following example:
#include <sycl/ext/intel/fpga_extensions.hpp> ... r[k] = ext::intel::fpga_reg(a[k]) + b[k]; ...
Use the fpga_reg() function to perform the following:
- Break critical paths between spatially distant portions of a datapath, such as between processing elements of a large systolic array.
- Reduce the pressure on placement and routing efforts caused by spatially distinct portions of the kernel implementation.
The fpga_reg() function directs the compiler to insert at least one hardware pipelining register on the signal path that assigns the operand to the return value. This built-in function operates as an assignment in the SYCL programming language where the operand is assigned to the return value. The assignment has no implicit semantic or functional meaning beyond a standard-C assignment. Functionally, you can consider the fpga_reg() function being always optimized away by the compiler.
The compiler does not provide feedback on where you should insert the fpga_reg() function calls in your code. Use the Intel® Quartus® Prime Pro Edition software to determine where you should insert the calls to address specific aspects of performance.
You may introduce nested fpga_reg() function calls in your kernel code to increase the minimum number of registers that the compiler inserts on the assignment path. Because each function call guarantees the insertion of at least one register stage, the number of calls provides a lower limit on the number of registers.