Intel FPGA OpenCL: выявить причину низкой тактовой частоты ядра

Я реализую проект OpenCL для ПЛИС Intel Cyclone V. Он основан на модифицированной версии стандартного OpenCL BSP Terasic DE10.

Модификация содержит подключение к плате внешнего аналого-цифрового преобразователя, подключенной к плате FPGA, для которой был реализован специальный блок Qsys на основе VHDL, который передает сэмплы с частотой дискретизации около 16 МГц в avalon dual-clock FIFO. Выходные данные FIFO подключаются к домену часов ядра, а выходные данные FIFO интерфейса Avalon Streaming экспортируются в ядро ​​OpenCL как канал, как описано в Руководстве по программированию Intel® FPGA SDK для OpenCLTM Standard Edition в разделе 5.4.5.4. (Реализация каналов ввода-вывода с использованием атрибута io Channels).

В настоящее время ядро ​​CL просто выбирает блоки непрерывных данных из канала и записывает их в глобальный буфер памяти. Затем хост добавляет образцы в файл. Это стабильно работает для частот дискретизации аналого-цифрового преобразователя до 1 МГц, более высокие частоты дискретизации приводят к большим потерям.

Включение профилирования и использование Intel Dynamic Profiler для OpenCL показало причину: средняя частота ядра составляет всего 1,3 МГц. Однако, поскольку система OpenCL компилируется не через Quartus IDE, а через командную строку черезaoc, информации о том, что было синтезировано и в чем причина столь низкой тактовой частоты, не так много. Так как же отследить узкое место моего дизайна с помощью инструментов, предоставляемых Intel?

Вот скриншот результатов профилирования:

Редактировать:

Вот соответствующая часть ядра CL и проекта Qsys. Обратите внимание, что путь TX, который вы найдете в обоих, в настоящее время не используется.

#pragma OPENCL EXTENSION cl_intel_channels: enable

struct TwoChannelSample
{
    short2 chanA;
    short2 chanB;
};

#define FIFO_DEPTH 32768

channel struct TwoChannelSample rxSamps __attribute__((depth(0))) __attribute__((io("THDB_ADA_rxSamples")));
channel struct TwoChannelSample txSamps __attribute__((depth(0))) __attribute__((io("THDB_ADA_txSamples")));
channel ushort                  stateChan    __attribute__((depth(0))) __attribute__((io("THDB_ADA_state")));

kernel void thdbADARxTxCallback (global const       float2* restrict txSamples,
                                 global             float2* restrict rxSamples,
                                 global             ushort* restrict interfaceState)
{
    // get state from interface
    *interfaceState = read_channel_intel (stateChan);

    // Process sample-wise
    for (int i = 0; i < FIFO_DEPTH; ++i)
    {
        struct TwoChannelSample rxSample = read_channel_intel (rxSamps);

        rxSamples[i].x = (float)rxSample.chanA.x;
        rxSamples[i].y = (float)rxSample.chanA.y;
        rxSamples[i + FIFO_DEPTH].x = (float)rxSample.chanB.x;
        rxSamples[i + FIFO_DEPTH].y = (float)rxSample.chanB.y;
    }
}

0 ответов

Другие вопросы по тегам