Free-Running Kernel - 2022.1 English

Vitis Unified Software Platform Documentation: Application Acceleration Development (UG1393)

Document ID
Release Date
2022.1 English

The Vitis core development kit provides support for one or more free-running kernels. Free-running kernels have no control signal ports, and cannot be started or stopped. The no-control signal feature of the free-running kernel results in the following characteristics:

  • The free-running kernel has no memory input or output port, and therefore it interacts with the host or other kernels (other kernels can be regular kernel or another free-running kernel) only through streams.
  • When the FPGA is programmed by the binary container (xclbin), the free-running kernel starts running on the FPGA, and therefore it does not need to be started from the host code.
  • The kernel works on the stream data as soon as it starts receiving from the platform I/O or other kernels, and it stalls when the data is not available.

The main advantage of a free-running kernel is that it does not follow the C-semantics where all the functions should be executed an equal number of times. This modeling style is more like RTL designs as shown in the example below. The compiler models the kernel to restart automatically after the previous function call finishes. This functionality is similar to a while(1) loop in software code, without having to specify the loop in the kernel code. This can be achieved if the kernel uses the mode=ap_ctrl_none mode in the INTERFACE pragma. This will create a kernel without control signals on an AXI4-Lite interface. This modeling technique is called a free-running kernel, as it is free of any control handshake. The kernel will start automatically and run continuously.

Important: Free-running kernels exhibit the behavior of having a while(1) loop around the kernel. Therefore, you should not explicitly define a while(1) loop in your source code to prevent non-deterministic behavior.

In addition, the kernel only supports streaming interfaces (axis). It should not use m_axi or s_axilite interfaces, as shown in the example below.

void increment(hls::stream<ap_axiu<32, 0, 0, 0> >& input, 
   hls::stream<ap_axiu<32, 0, 0, 0> >& output){

#pragma HLS interface ap_ctrl_none port = return
   ap_axiu<32, 0, 0, 0> v =; = + 1;
   if (v.last){
Tip: Software emulation is not supported for free-running kernels.