Есть ли способ синхронизировать пользовательские сигналы прерывания с мастер-транзакциями AXI в Vitis HLS?
Мне не удалось найти ответ, возможно, из-за того, что я не смог дать достаточно конкретную номенклатуру вовлеченным процессам.
Я использую Vitis HLS для синтеза проектов, в которых один вызов основной функции длится один такт, конечно, будучи конвейерным. Это прекрасно работает почти во всех наших случаях. Там, где это невозможно (например, для компонентов, где нам нужно гарантировать определенные задержки/глубину конвейерной обработки), я использую verilog.
Цель состоит в том, чтобы передать данные через DMA в память Zynq-7000, а ЗАТЕМ выдать прерывание, чтобы сообщить PS, что передача DMA завершена.
Предположим, у меня есть проект Vitis HLS, где PS может инициировать DMA-передачу uint32, используя (нарастающий фронт сигнала) интерфейс s_axilite для моего компонента, как в приведенном ниже коде:
#include <cstdint>
void Example
(
uint32_t *dmaRegion,
bool &intrSig,
volatile bool writeNow
)
{
#pragma HLS PIPELINE II=1
#pragma HLS INLINE RECURSIVE
#pragma HLS INTERFACE s_axilite port=return bundle=registers
#pragma HLS INTERFACE ap_ctrl_none port=return
#pragma HLS INTERFACE m_axi port=dmaRegion offset=slave bundle=x
#pragma HLS INTERFACE s_axilite port=dmaRegion bundle=registers
#pragma HLS INTERFACE ap_none port=dmaRegion
#pragma HLS INTERFACE s_axilite port=writeNow bundle=registers
#pragma HLS INTERFACE ap_none port=writeNow
#pragma HLS INTERFACE ap_none port=intrSig
static bool lastWriteNow { false };
static uint32_t Ctr { 0 };
bool intr = false;
if (!lastWriteNow && writeNow)
{
Ctr++;
dmaRegion[10] = Ctr;
intr = true;
}
intrSig = intr;
lastWriteNow = writeNow;
}
Теперь это, кажется , работает нормально и вызывает прерывание с 1-тактовым импульсом, пока WREADY находится в высоком уровне с помощью Zynq (и через SmartConnect к моему компоненту), и я нашел несколько примеров, где это делается таким образом. Кроме того, PS захватывает правильные данные из памяти DDR (кэш данных L2 отключен для этой области памяти) сразу после прерывания.
Однако что произойдет, если, например, больше мастеров AXI попытаются управлять Smart Connect и вызовут перегрузку, что приведет к снижению уровня этого компонента? В моих тестах, когда я доводил сигнал главного интерфейса AXI Smart Connect до постоянного нуля, чтобы имитировать (постоянную) перегрузку, сигнал прерывания (и ) был доведен до постоянного высокого уровня, что означало бы… что? Что дизайн HLS заблокирован внутри предложения if? Я не совсем понимаю, так как мне кажется, что это противоречило бы ограничению II=1 (которое Vitis HLS сообщает как выполненное).
В некотором смысле это, конечно, имеет смысл, поскольку
Это вообще возможно при каких-то гарантиях на интерфейс m_axi, или мне придется искать другие решения?
Любые подсказки и информация (особенно справочная информация об этом поведении) очень ценятся.
Редактировать:
Например, это отлично работает:
но это приводит к тому, что прерывание остается высоким навсегда:
Конечно, транзакция не может быть завершена. Но, похоже, у меня нет возможности разблокировать конструкцию, пока шина AXI перегружена.