Лабораторная 5.4 — Обёртка AXI-Stream для IQ-потока¶
Цель¶
Перейти от учебного valid-only интерфейса к интерфейсу AXI-Stream, который ближе к реальному Vivado/Zynq потоку данных.
Что выполняется¶
В работе студент:
- изучает сигналы
tvalid,tready,tdata,tlast; - разбирает упаковку IQ-отсчётов в 32-битное слово;
- запускает RTL wrapper
axis_iq_passthrough; - проверяет работу backpressure;
- анализирует сохранение
tdataиtlast.
Результат¶
После выполнения работы должны быть получены:
- AXI-Stream style wrapper;
- self-checking testbench;
- VCD waveform;
- PASS/FAIL лог симуляции;
- понимание handshaking-правила
tvalid && tready.
Что приложить к отчёту¶
- таблицу AXI-Stream сигналов;
- формат упаковки IQ в
tdata; - пример backpressure;
- лог успешной симуляции;
- вывод о применимости wrapper для FIR/mixer блоков.
Подробная техническая часть¶
Исполняемый HDL-пакет¶
| Файл | Назначение |
|---|---|
blocks/block_05_fpga_hdl_flow/rtl/axis_iq_passthrough.v |
сквозная обёртка IQ в стиле AXI-Stream |
blocks/block_05_fpga_hdl_flow/tb/tb_axis_iq_passthrough.v |
самопроверяющийся testbench AXI-Stream |
Запуск из корня репозитория:
iverilog -g2012 \
-o blocks/block_05_fpga_hdl_flow/tb/tb_axis_iq_passthrough.out \
blocks/block_05_fpga_hdl_flow/rtl/axis_iq_passthrough.v \
blocks/block_05_fpga_hdl_flow/tb/tb_axis_iq_passthrough.v
vvp blocks/block_05_fpga_hdl_flow/tb/tb_axis_iq_passthrough.out
Ожидаемый результат:
PASS: axis_iq_passthrough test completed without errors
Workflow GitHub Actions .github/workflows/block5_hdl.yml запускает эту симуляцию автоматически.
Инженерный вопрос¶
Как подключить потоковый IQ DSP-блок к тракту данных в стиле Vivado/Zynq, поддерживающему backpressure?
Подмножество сигналов AXI-Stream¶
Работа использует важнейшие сигналы в стиле AXI-Stream:
| Сигнал | Направление | Смысл |
|---|---|---|
s_axis_tvalid |
вход | входной отсчёт действителен |
s_axis_tready |
выход | блок может принять входной отсчёт |
s_axis_tdata |
вход | упакованный входной отсчёт I/Q |
s_axis_tlast |
вход | маркер конца кадра/пакета |
m_axis_tvalid |
выход | выходной отсчёт действителен |
m_axis_tready |
вход | нижестоящий блок может принять отсчёт |
m_axis_tdata |
выход | упакованный выходной отсчёт I/Q |
m_axis_tlast |
выход | маркер конца кадра/пакета на выходе |
Упаковка IQ¶
Учебная обёртка упаковывает комплексные отсчёты в 32-битный tdata:
tdata[15:0] = отсчёт I, знаковый Q1.15
tdata[31:16] = отсчёт Q, знаковый Q1.15
Правило handshake¶
Передача происходит только когда:
tvalid == 1 и tready == 1
Если m_axis_tready низкий, блок обязан удерживать выходной отсчёт и не терять данные.
Модель backpressure¶
sequenceDiagram
participant SRC as Источник потока
participant DUT as Обёртка AXIS
participant DST as Приёмник потока
SRC->>DUT: tvalid=1, отсчёт tdata
DST-->>DUT: tready=0
DUT-->>SRC: s_axis_tready=0, пока выход занят
DST-->>DUT: tready=1
DUT->>DST: m_axis_tvalid=1, отсчёт tdata
Поведение RTL¶
Исполняемая обёртка это однотактный регистровый сквозной канал:
входной отсчёт AXIS -> выходной регистр -> нижестоящий AXIS
Он демонстрирует:
- handshake
tvalid/tready; - удержание выходного регистра при backpressure;
- сохранение
tlast; - 32-битный упакованный тракт данных I/Q;
- сброс
aresetnс активным низким уровнем.
Стратегия testbench¶
Testbench проверяет:
- сброс обнуляет
m_axis_tvalid; - все отсчёты передаются ровно один раз;
tdataсохраняется;tlastсохраняется;- детерминированный backpressure не приводит к потере отсчётов;
- симуляция автоматически падает при расхождении.
Масштабирование к настоящему проекту Vivado¶
| Учебная работа | Расширение в реальном проекте |
|---|---|
32-битный tdata с I/Q |
более широкая шина, несколько отсчётов за такт передачи |
| сквозной тракт данных | FIR, mixer, DDC или обработчик пакетов |
| простой детерминированный backpressure | backpressure от DMA, FIFO или RF-фронтенда |
| нет метаданных по боковому каналу | tuser, tkeep, счётчики кадров, метки времени |
| учебная симуляция | AXI VIP, cocotb или верификация на SystemVerilog |
Чего ожидать¶
PASS: axis_iq_passthrough test completed without errors
Testbench посылает 6 IQ-посылок с tlast на выбранных посылках, переключает m_axis_tready, создавая backpressure, и проверяет, что все 6 посылок пришли по порядку с верными данными и tlast, и ничего лишнего.
Раннер курса генерирует векторы, компилирует, запускает симуляцию и считает ошибкой любую строку FAIL или ненулевой код выхода симулятора:
python tools/run_block5_hdl_smoke.py --test tb_axis_iq_passthrough
Упражнения¶
Каждое упражнение ниже: намеренная мутация RTL в одну строку. Внесите её, запустите testbench, прочитайте сообщения и верните файл (git checkout -- <file>). Приведённые выводы получены на Icarus Verilog 12.0.
- Игнорируйте backpressure:
assign s_axis_tready = 1'b1;. Testbench сообщаетERROR: received 4 samples, expected 6. Две посылки были перезаписаны в выходном регистре, пока следующий блок стоял. В железе это ничем не отмечается: поток просто становится короче. - Используйте более простое правило
assign s_axis_tready = m_axis_tready;. Testbench всё равно проходит. Объясните, почему эта версия никогда не теряет и не дублирует данные и чем она жертвует: пустой выходной регистр нельзя заполнить, пока следующий блок не готов. Придумайте проверку (например, подсчёт тактов на фиксированное число посылок при фиксированном шаблонеtready), которая различит две версии. - AXI-Stream запрещает источнику ждать
treadyперед выставлениемtvalid. Найдите строку RTL, которая гарантирует это дляm_axis_tvalid.
Ответы (сверены с RTL и стендом)
- Наблюдаемый вывод приведён в упражнении: игнорирование обратного давления молча теряет такты передачи.
- С
s_axis_tready = m_axis_treadyтакт принимается только тогда, когда выходной регистр опустошается, поэтому регистр никогда не держит двух тактов сразу и ничего не теряется и не дублируется. Отказывается он от заполнения пустого выходного регистра, пока потребитель стоит: после каждой остановки конвейер стартует на такт позади. Проверка, которая это показывает: отправить фиксированное число тактов при фиксированном шаблоне готовности потребителя (например, один простой из трёх) и посчитать такты до конца; полное правило заканчивает быстрее. assign s_axis_tready = (~m_axis_tvalid) || m_axis_tready;вместе сm_axis_tvalid <= s_axis_tvalid;внутриif (s_axis_tready): пустой выходной регистр загружается и поднимаетm_axis_tvalidнезависимо отm_axis_tready, поэтому источник никогда не ждёт ready перед тем, как выставить valid.
Чек-лист отчёта (расширенный)¶
- Объяснён handshake
tvalid/tready. - Определена упаковка IQ в
tdata. - Объяснена роль
tlast. - Показано, как проверяется backpressure.
- Запущена симуляция и записан вывод PASS.
- Объяснено, как обёртку можно использовать вокруг блоков FIR или mixer.
Шаблон инженерного вывода¶
Обёртка AXI-Stream передаёт 32-битные упакованные IQ-отсчёты и сохраняет tlast.
Testbench применяет детерминированный backpressure через m_axis_tready и подтверждает,
что ни один отсчёт не потерян и не продублирован. Эта обёртка — первый шаг к подключению
блоков FIR, mixer и дециматора к потоковому тракту данных Vivado/Zynq.