Intel® FPGA SDK for OpenCL™ Pro Edition: Programming Guide

ID 683846
Date 12/19/2022
Public
Document Table of Contents

5.4.5.4. Implementing I/O Channels Using the io Channels Attribute

Include an io attribute in your channel declaration to declare a special I/O channel to interface with input or output features of an FPGA board.
These features might include network interfaces, PCIe®, cameras, or other data capture or processing devices or protocols.

The io("chan_id") attribute specifies the I/O feature of an accelerator board with which a channel is connected, where chan_id is the name of the I/O interface listed in the board_spec.xml file of your Custom Platform.

Because peripheral interface usage might differ for each device type, consult your board vendor's documentation when you implement I/O channels in your kernel program. Your OpenCL™ kernel code must be compatible with the type of data generated by the peripheral interfaces.

CAUTION:
  • Implicit data dependencies might exist for channels that connect to the board directly and communicate with peripheral devices via I/O channels. These implicit data dependencies might lead to unexpected behavior because the Intel® FPGA SDK for OpenCL™ Offline Compiler does not have visibility into these dependencies.
  • External I/O channels communicating with the same peripherals do not obey any sequential ordering. Ensure that the external device does not require sequential ordering because unexpected behavior might occur.
  1. Consult the board_spec.xml file in your Custom Platform to identify the input and output features available on your FPGA board.

    For example, a board_spec.xml file might include the following information on I/O features:

    <channels>
      <interface name="udp_0" port="udp0_out"  type="streamsource" width="256"
       chan_id="eth0_in"/>
      <interface name="udp_0" port="udp0_in"  type="streamsink" width="256"
       chan_id="eth0_out"/>
      <interface name="udp_0" port="udp1_out"  type="streamsource" width="256"
       chan_id="eth1_in"/>
      <interface name="udp_0" port="udp1_in"  type="streamsink" width="256"
       chan_id="eth1_out"/>
    </channels>

    The width attribute of an interface element specifies the width, in bits, of the data type used by that channel. For the example above, both the uint and float data types are 32 bits wide. Other bigger or vectorized data types must match the appropriate bit width specified in the board_spec.xml file.

  2. Implement the io channel attribute as demonstrated in the following code example. The io channel attribute names must match those of the I/O channels (chan_id) specified in the board_spec.xml file.
    channel QUDPWord udp_in_IO __attribute__((depth(0)))
                               __attribute__((io("eth0_in"))); 
    channel QUDPWord udp_out_IO __attribute__((depth(0)))
                                __attribute__((io("eth0_out"))); 
    
    __kernel void io_in_kernel (__global ulong4 *mem_read,
                                uchar read_from,
                                int size) 
    {
      int index = 0;
      ulong4 data;
      int half_size = size >> 1;
      while (index < half_size)
      {
        if (read_from & 0x01)
        {
          data = read_channel_intel(udp_in_IO);
        } 
        else
        {
          data = mem_read[index];
        }
        write_channel_intel(udp_in, data);
        index++;
      }
    }
    
    __kernel void io_out_kernel (__global ulong2 *mem_write,
                                 uchar write_to,
                                 int size)
    {
      int index = 0;
      ulong4 data;
      int half_size = size >> 1;
      while (index < half_size)
      {
        ulong4 data = read_channel_intel(udp_out);
        if (write_to & 0x01)
        {
          write_channel_intel(udp_out_IO, data);
        }
        else
        {
          //only write data portion
          ulong2 udp_data;
          udp_data.s0 = data.s0;
          udp_data.s1 = data.s1;
          mem_write[index] = udp_data;
        }
        index++;
      }
    }
    Attention: Declare a unique io("chan_id") handle for each I/O channel specified in the channels eXtensible Markup Language (XML) element within the board_spec.xml file.