Перейти к содержанию

Лабораторная 11.8 — Overlay gpreg BPSK для AD9361 и первый разведочный пакет

Цель

Перейти от заглушки запуска через AXI-Lite к первому специфичному для курса аппаратному overlay AD9361, который сохраняет видимую для PS плоскость управления, пока восстанавливается точно подходящий к плате загрузочный shell:

PS / software -> axi_gpreg @ 0x79040000 -> staged sample-domain bridge -> AD9361 TX/RX path

Эта работа: первая чистая передача от исполняемого модема Блока 5 к импортированному вендорскому shell AD9361, соответствующему реальной плате курса (xc7z020clg400-2). Место работы в общей истории Блока 11 на карте лабораторных Блока 11.

Инженерное решение

По состоянию на 2026-06-21 закоммиченный режим overlay намеренно сведён к gpreg_only.

Этот откат сделан сознательно:

  • он держит путь управления простым и проверяемым;
  • он сохраняет видимую для Linux оболочку RX и TX DMA, чтобы стоковое дерево устройств по-прежнему нормально опознавалось;
  • он отделяет проверку карты адресов axi_gpreg от более трудной проблемы чистой загрузки AD9361;
  • он не позволяет считать пересобранный, но ещё не безопасный для загрузки образ PL допустимой базовой линией RF-измерений.

Прежние эксперименты с TX с включённым пакетом остаются полезным историческим доказательством, но не являются текущей безопасной закоммиченной базой. Следующий шаг с контрольной точкой: пока считать извлечённую полезную нагрузку стокового раздела BOOT единственной внешне загружаемой безопасной для загрузки опорой, а затем объяснить, почему редактируемые shell, соотнесённые с исходниками, всё ещё теряют AD9361, прежде чем продолжать разведку RF.

Новые аппаратные файлы

Файл Назначение
hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/system_project.tcl создаёт чистый проект Vivado курса для xc7z020clg400-2
hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/system_bd.tcl подключает импортированную базовую линию AD9361 и добавляет overlay курса
hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/vendor_system_bd_clg400.tcl замороженный вендорский shell block design, извлечённый из рабочего образа платы
hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/build_bitstream.tcl детерминированная пакетная сборка, выдающая bitstream и XSA курса
hardware/7020_ad936x_sdr/rebuild_vendor_xpr_snapshot_mio_patch.tcl одноразовый поток Vivado, пересобирающий сохранённый снимок вендорского zc702.xpr после правки только MIO14/15 в sys_ps7
hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/bpsk_zynq_ber_gpreg_bridge.v ступенчатый мост между доменами тактирования для следующего шага повторной интеграции тракта отсчётов
hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/course_dac_fifo_source_mux.v ступенчатый мультиплексор тракта TX для последующей повторной интеграции DAC; в текущем режиме gpreg_only не включён
hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/README.md заметки по сборке, контракт регистров и ограничения первого пакета

Новые программные помощники

Файл Назначение
blocks/block_11_integrated_sdr_project/python/lab_11_8_axi_gpreg_bpsk_bringup.py записывает управляющие слова gpreg, запускает один пакет, опрашивает busy/done/timeout и читает счётчики BER
blocks/block_11_integrated_sdr_project/python/lab_11_12_runtime_fpga_manager_reload.py загружает проверенную полезную нагрузку .bit.bin по SSH, выполняет горячую загрузку через Linux fpga_manager, затем заново опрашивает axi_gpreg и видимый хосту контекст IIO
blocks/block_11_integrated_sdr_project/python/lab_11_13_stock_vs_runtime_rx_compare.py в одном живом прогоне на плате доказывает, что приём RX в стоковом shell работает до перезагрузки, затем повторяет те же проверки после горячей загрузки и фиксирует поломку
blocks/block_11_integrated_sdr_project/python/lab_11_15_runtime_bridge_rx_host_tx_probe.py горячо загружает промежуточный overlay bridge_rx_only, снимает одно свидетельство gpreg в покое, затем повторяет его, пока стоковый хостовый TX передаёт общий пакет BPSK; теперь также декодирует необязательное слово CAPTURE_DEBUG сырого отвода RX
blocks/block_11_integrated_sdr_project/python/runtime_rx_common.py общий помощник, читающий и восстанавливающий стоковый запрос управления RX common после перезагрузки overlay во время работы
blocks/block_11_integrated_sdr_project/python/lab_11_16_runtime_rx_common_reinit_probe.py доказывает, что меняет ручная повторная инициализация RX common и чего она всё ещё не исправляет в хостовом пути приёма
blocks/block_11_integrated_sdr_project/python/lab_11_17_runtime_rx_common_reinit_start_offset_sweep.py развёртка start_offset после повторной инициализации RX common во время работы, пока стоковый хостовый TX передаёт общий пакет BPSK

Контракт регистров

Базовый адрес: 0x79040000

Смещение Смысл
0x000 регистр версии axi_gpreg
0x004 регистр ID axi_gpreg, ожидается 0x4250534B
0x404 выход GPREG0: управляющее слово; бит 0 это фронт старта, бит 1 это сброс залипающего done, биты 3:2 это режим решения RX (I, -I, Q, -Q)
0x408 вход GPREG0: слово статуса; бит 0: синхронизированный уровень старта, бит 1: busy, бит 2: залипающий done, бит 3: залипающий таймаут/прерывание RX, бит 4: режим QPSK (gp_ctrl[4]), биты 6:5: поворот созвездия, найденный счётчиком BER, в единицах 90 градусов, фиксируется по done (BPSK читает 0 или 2; добавлено в issue #64, поэтому битстримы, собранные раньше, читают 0), биты 15:8: SPS
0x444 выход GPREG1: FRAME_BIT_COUNT
0x448 вход GPREG1: RECEIVED_BITS
0x484 выход GPREG2: PREAMBLE_COUNT
0x488 вход GPREG2: TOTAL_ERRORS
0x4C4 выход GPREG3: START_OFFSET
0x4C8 вход GPREG3: PAYLOAD_ERRORS
0x508 вход GPREG4: подпись моста, ожидается 0x4250534B
0x548 вход GPREG5: упакованные TX_VALID_COUNT и отладка знака решений RX
0x588 вход GPREG6: RX_VALID_COUNT на стороне моста
0x5C8 вход GPREG7: упакованное слово CAPTURE_DEBUG сырого отвода RX

GPREG5 теперь упаковывает ещё одно свидетельство времени работы рядом с младшими 12 битами TX_VALID_COUNT:

  • биты 11:0: tx_valid_count_lsb12;
  • биты 19:12: младшие 8 бит счётчика восстановленных бит 1;
  • биты 27:20: младшие 8 бит счётчика валидных восстановленных бит;
  • бит 28: встречался ненулевой входной отсчёт жёсткого решения;
  • бит 29: встречался отрицательный входной отсчёт жёсткого решения;
  • бит 30: встречался восстановленный бит 1;
  • бит 31: встречался импульс валидности восстановленного бита.

CAPTURE_DEBUG упаковывает одно компактное слово-свидетельство времени работы:

  • бит 31: встречался сырой импульс capture_in_valid;
  • бит 30: встречался ненулевой сырой отсчёт RX1 I/Q;
  • бит 29: встречался сырой импульс capture_in_valid, пока ядро BER было активно;
  • бит 28: сырой отсчёт RX1 I на отводе моста бывал отрицательным;
  • бит 27: сырой отсчёт RX1 Q на отводе моста бывал отрицательным;
  • биты 26:14: младшие 13 бит счётчика сырых импульсов capture_in_valid;
  • биты 13:0: пиковый модуль сырого отсчёта RX1 в беззнаковых единицах Q14.

Предварительные условия сборки

Сначала сгенерируйте файлы памяти Блока 5:

python blocks/block_05_fpga_hdl_flow/python/generate_bpsk_rrc_tx_fir_vectors.py
python blocks/block_05_fpga_hdl_flow/python/generate_bpsk_framed_loopback_vectors.py

Затем создайте проект Vivado и экспортируйте handoff:

vivado -mode batch -source hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/system_project.tcl
vivado -mode batch -source hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/build_bitstream.tcl

Ожидаемые результаты успешной сборки:

  1. bitstream в hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/build/course_bpsk_fmcomms2_zc702.runs/impl_1/system_top.bit;
  2. XSA в hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/course_bpsk_fmcomms2_zc702.sdk/system_top.xsa;
  3. журналы тайминга в hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/timing_synth.log и timing_impl.log;
  4. подтвердите, что новый XSA содержит axi_gpreg_bpsk по адресу 0x79040000;
  5. используйте помощник ниже в Linux или по SSH.

Локальный прогон с имитацией

python blocks/block_11_integrated_sdr_project/python/lab_11_8_axi_gpreg_bpsk_bringup.py \
  --backend mock \
  --json-out docs/assets/lab118_axi_gpreg_bringup_mock.json

Ожидаемое локальное поведение:

  • и ID axi_gpreg, и подпись моста читаются как 0x4250534B;
  • busy_observed и done_observed оба равны true;
  • timed_out_observed равен false;
  • received_bits == frame_bit_count;
  • total_errors == 0;
  • payload_errors == 0.

Прогон в Linux или по SSH

Прямой доступ Linux /dev/mem на плате:

sudo python blocks/block_11_integrated_sdr_project/python/lab_11_8_axi_gpreg_bpsk_bringup.py \
  --backend mmap \
  --base-addr 0x79040000 \
  --frame-bit-count 281 \
  --preamble-count 25 \
  --start-offset 62 \
  --json-out reports/lab118_axi_gpreg_bringup.json

Удалённый доступ devmem с хоста по Ethernet:

python blocks/block_11_integrated_sdr_project/python/lab_11_8_axi_gpreg_bpsk_bringup.py \
  --backend ssh-devmem \
  --ssh-host 192.168.40.1 \
  --ssh-user root \
  --ssh-password analog \
  --base-addr 0x79040000

Текущие живые доказательства

Есть два слоя доказательств, и смешивать их нельзя.

Исторические доказательства overlay с включённым пакетом:

Ранний аппаратный overlay был пересобран, загружен через Linux fpga_manager и опрошен с хоста по Ethernet.

Пути исторических доказательств:

  • XSA: hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/course_bpsk_fmcomms2_zc702.sdk/system_top.xsa;
  • bitstream: hardware/7020_ad936x_sdr/hdl/course_bpsk_fmcomms2_zc702/build/course_bpsk_fmcomms2_zc702.runs/impl_1/system_top.bit;
  • живой отчёт помощника: docs/assets/lab118_axi_gpreg_bringup_live.json.

Наблюдённые исторические факты на плате:

  • devmem 0x79040000 32 -> 0x00040063;
  • devmem 0x79040004 32 -> 0x4250534B;
  • devmem 0x79040508 32 -> 0x4250534B;
  • результат помощника: final_status = 0x0000080C;
  • done_observed = true;
  • timed_out_observed = true;
  • received_bits = 0;
  • настройка RF во время разведочного прогона: ослабление TX -60 dB, ручное усиление RX 20 dB, AGC выключена.

Повторная проверка во время работы, 2026-06-23:

Исправленная полезная нагрузка bridge_txrx_mux с перестановкой слов снова была загружена через Linux fpga_manager из базовой линии стокового shell, на этот раз новым помощником времени работы:

  • помощник: blocks/block_11_integrated_sdr_project/python/lab_11_12_runtime_fpga_manager_reload.py;
  • отчёт о перезагрузке во время работы: docs/assets/lab118_runtime_fpga_manager_reload_live.json;
  • отчёт gpreg после перезагрузки: docs/assets/lab118_axi_gpreg_bringup_runtime_20260623.json;
  • отчёт о приёме пакета после перезагрузки: docs/assets/lab110_iio_burst_capture_runtime_20260623.json;
  • компактная RF-развёртка после перезагрузки: docs/assets/lab119_rf_discovery_sweep_runtime_20260623.json.

Наблюдённые факты времени работы на плате:

  • базовая линия стокового shell по-прежнему возвращала Bus error при чтении 0x79040004, то есть до горячей загрузки axi_gpreg отсутствовал;
  • fpga_manager принял bridge_txrx_mux.wordswap.bit.bin и остался в состоянии operating;
  • после перезагрузки снова devmem 0x79040004 32 -> 0x4250534B и devmem 0x79040508 32 -> 0x4250534B;
  • помощник пакета gpreg по-прежнему возвращал final_status = 0x0000080C, tx_valid_count = 2376, rx_valid_count = 0 и received_bits = 0;
  • в отличие от прежнего сломанного живого состояния, хостовый контекст IIO после перезагрузки во время работы по-прежнему перечислял ad9361-phy, cf-ad9361-dds-core-lpc и cf-ad9361-lpc;
  • однако короткий приём iio_readdev с ограничением по времени по-прежнему возвращал тайм-аут наполнения буфера Unknown error (110) и не давал ни одного отсчёта;
  • компактная RF-развёртка на безопасной мощности по START_OFFSET = 48, 62, 74, RX gain = 10/20 dB и TX attenuation = -80/-70 dB давала один и тот же результат на каждой попытке: received_bits = 0, tx_valid_count = 2376, rx_valid_count = 0.

Сравнение стокового и загруженного во время работы образа, 2026-06-23:

Затем отдельный помощник сравнения выполнил ещё одну, более строгую A/B-проверку на той же плате:

  • помощник: blocks/block_11_integrated_sdr_project/python/lab_11_13_stock_vs_runtime_rx_compare.py;
  • живой отчёт сравнения: docs/assets/lab113_stock_vs_runtime_rx_compare_live.json.

Наблюдённые факты сравнения на плате:

  • до любой горячей загрузки стоковый shell поддерживал и прямой хостовый приём через libiio Buffer.refill(), и короткий приём iio_readdev;
  • в живом сравнении стоковый libiio вернул 16384 комплексных отсчёта, а стоковый iio_readdev: 65536 байт с пустым stderr;
  • после исправленной горячей загрузки axi_gpreg оставался читаемым и снова сообщал final_status = 0x0000080C, tx_valid_count = 2376, rx_valid_count = 0 и received_bits = 0;
  • после той же перезагрузки прямой хостовый libiio завершался ошибкой OSError: [Errno 110] host unreachable, а iio_readdev снова: тайм-аутом наполнения Unknown error (110);
  • тот же A/B-отчёт показал, что у cf-ad9361-dds-core-lpc значение sync_start_enable меняется с arm в стоковом shell на disarm после перезагрузки во время работы.

Промежуточное свидетельство bridge_rx_only во время работы, 2026-06-23:

Следующий живой шаг перешёл от bridge_txrx_mux к более узкому промежуточному overlay bridge_rx_only, чтобы вендорский тракт TX оставался нетронутым, а мост подключался только к отводу отсчётов RX.

  • помощник: blocks/block_11_integrated_sdr_project/python/lab_11_15_runtime_bridge_rx_host_tx_probe.py;
  • ранний живой отчёт-свидетельство: docs/assets/lab115_runtime_bridge_rx_host_tx_probe_live_20260623_bridge_rx_only_b.json;
  • уточнённый живой отчёт-свидетельство: docs/assets/lab115_runtime_bridge_rx_host_tx_probe_live_20260623_bridge_rx_only_debug_a.json.

Наблюдённые факты bridge_rx_only на плате:

  • пересобранный сырой system_top.bit режима bridge_rx_only был преобразован в правильную полезную нагрузку времени работы с перестановкой слов и принят Linux fpga_manager;
  • после горячей загрузки плата по-прежнему предоставляла ad9361-phy, cf-ad9361-dds-core-lpc и cf-ad9361-lpc, а axi_gpreg снова читался по адресу 0x79040000;
  • первое свидетельство gpreg в покое по-прежнему возвращало tx_valid_count = 2376, rx_valid_count = 0 и received_bits = 0;
  • затем помощник перенастроил стоковые TX/RX AD9361 на общий детерминированный пакет BPSK: 915 MHz, 3.84 MS/s, 480 ksym/s, TX -50 dB, RX +35 dB;
  • даже при активном живом пакете стокового TX, управляемом с хоста, второе свидетельство по-прежнему возвращало tx_valid_count = 2376, rx_valid_count = 0 и received_bits = 0;
  • уточнённое свидетельство CAPTURE_DEBUG сделало голодание RX конкретнее: и опрос в покое, и опрос с хостовым TX прочитали capture_debug_word = 0, при capture_valid_seen_any = false, capture_nonzero_seen_any = false, capture_valid_count_lsb15 = 0 и capture_peak_abs_max_q14 = 0;
  • поэтому вывод уточнённого отчёта сильнее исходного свидетельства ...bridge_rx_only_b.json: после горячей загрузки мост не просто пропускает кадры BER, он вообще не видит активности на сыром отводе RX;
  • после этого помощник перезагрузил плату и подтвердил безопасный возврат к базовой линии стокового shell.

Прорыв с повторной инициализацией RX common во время работы, 2026-06-23:

Следующий живой шаг проверял, оставляет ли горячая загрузка блок RX common AD9361 в ином управляющем состоянии, чем стоковый shell, и оживит ли тракт приёма принудительное возвращение стоковых битов запроса.

  • помощник: blocks/block_11_integrated_sdr_project/python/lab_11_16_runtime_rx_common_reinit_probe.py;
  • помощник: blocks/block_11_integrated_sdr_project/python/lab_11_17_runtime_rx_common_reinit_start_offset_sweep.py;
  • помощник: blocks/block_11_integrated_sdr_project/python/lab_11_18_runtime_rx_common_reinit_fresh_session_sweep.py;
  • живой опрос повторной инициализации: docs/assets/lab116_runtime_rx_common_reinit_probe_live_20260623.json;
  • живое свидетельство с хостовым TX после повторной инициализации: docs/assets/lab116_runtime_rx_common_reinit_host_tx_probe_live_20260623.json;
  • живая развёртка start-offset после повторной инициализации: docs/assets/lab117_runtime_rx_common_reinit_start_offset_sweep_live_20260623.json;
  • живое доказательство отладки решений в одной точке в свежей сессии: docs/assets/lab119_runtime_rx_decision_debug_single_point_live_20260623.json;
  • частичная широкая развёртка start-offset в свежей сессии: docs/assets/lab118_runtime_rx_common_reinit_fresh_session_start_offset_wide_live_20260623.json.

Наблюдённые факты после повторной инициализации на плате:

  • сразу после горячей загрузки регистр запроса RX common откатывался к rx_common_ctrl_req = 0x00000000, а соответствующие чтения rx_common_clk_count / rx_common_status были нулевыми;
  • восстановление стокового слова запроса 0x79020040 <- 0x00000003 немедленно оживило ненулевую активность тактирования/статуса RX: rx_common_clk_count = 0x00013AE5 и rx_common_status = 0x00000005;
  • та же повторная инициализация сняла и свидетельство сброса на сырой входной стороне: adc_input_reset_asserted_current упал в false, а отладочные слова входной стороны и отвода RX снова стали ненулевыми;
  • несмотря на это восстановление на стороне fabric, отдельный A/B-помощник по-прежнему воспроизводил те же хостовые отказы после горячей загрузки: прямой libiio Buffer.refill() по-прежнему выбрасывал OSError: [Errno 110] host unreachable, а iio_readdev по-прежнему завершался Unable to refill buffer: Unknown error (110);
  • затем свидетельство с хостовым TX при повторной инициализации доказало, что overlay во время работы больше не голодает на отводе отсчётов: rx_valid_count стал ненулевым, сырое слово CAPTURE_DEBUG показало валидную/ненулевую активность, и мост снова видел поток RX во время стокового хостового TX;
  • первая закоммиченная развёртка start_offset после этой повторной инициализации нашла реальное окно приёма полного кадра на первой попытке после TX: start_offset = 32 завершил 281 принятый бит со 144 общими ошибками и 136 ошибками нагрузки, а следующие попытки в той же сессии TX откатывались к поведению, похожему на тайм-аут;
  • более широкая развёртка в свежей сессии затем исключила простую вину start_offset: смещения от 0 до 576 давали тот же результат 281 / 144 / 136 с одинаковыми rx_valid_count = 2982 и capture_peak_abs_max_q14 = 4095;
  • новое упакованное свидетельство знака решений наконец сделало вид отказа явным на приёме полного кадра: тракт восстановленных бит выдавал импульсы валидности, вход жёсткого решения был ненулевым, но никогда не становился отрицательным и никогда не давал восстановленной 1, так что живые счётчики BER фактически сравнивали ожидаемый кадр с полностью нулевым потоком восстановленных бит.

Первопричина, offset-binary, и перенастройка после исправления, 2026-06-23:

  • более строгое свидетельство знака сырых отсчётов docs/assets/lab120_runtime_capture_sign_single_point_live_20260623.json затем показало, что сам сырой отвод моста никогда не становился отрицательным, хотя capture_peak_abs_max_q14 = 4095; это исключило мёртвый тракт RX и указало на несовпадение формата отсчётов;
  • просмотр импортированного HDL ADI (ad_datafmt.v и up_adc_channel.v) объяснил причину: при оставленных по умолчанию нулевых настройках формата данных RX приёмный тракт axi_ad9361 выдаёт на отвод моста сырые 12-битные отсчёты в коде со смещением (offset-binary), а не знаковые отсчёты в дополнительном коде;
  • теперь мост локально исправляет эти младшие 12 бит перед подачей в bpsk_zynq_ber_top, а CAPTURE_DEBUG намеренно по-прежнему сообщает сырой неформатированный отвод, чтобы объяснение на уровне исходников оставалось проверяемым;
  • непосредственное живое доказательство после исправления docs/assets/lab121_runtime_offset_binary_fix_single_point_live_20260623.json показало, что прежний отказ с полностью нулевым потоком действительно ушёл: на железе теперь появляются decision_negative_seen_any = true и recovered_one_seen_any = true;
  • оставшийся BER всё ещё высок, но теперь поддаётся настройке, а не схлопнут: docs/assets/lab122_runtime_offset_binary_fix_phase_sweep_live_20260623.json улучшил лучшую точку до 281 / 129 / 120 при start_offset = 34, docs/assets/lab123_runtime_offset_binary_fix_tx_phase_sweep_live_20260623.json показал лишь скромный дополнительный выигрыш от фазы TX, а docs/assets/lab124_runtime_offset_binary_fix_gain_sweep_live_20260623.json достиг текущей лучшей живой точки 281 / 127 / 114 при start_offset = 34, tx_phase = 315 deg, rx_gain = 5 dB.

Продолжение с самотактируемым bridge_txrx_mux, 2026-06-23:

  • новый помощник времени работы blocks/block_11_integrated_sdr_project/python/lab_11_19_runtime_bridge_txrx_self_timed_bringup.py убирает зависимость от асинхронного хостового циклического TX: он горячо загружает bridge_txrx_mux, восстанавливает rx_common, настраивает AD9361 и запускает пакет со стороны PL тем же управляющим словом start;
  • первое доказательство самотактируемого пути в одной точке docs/assets/lab125_runtime_bridge_txrx_self_timed_single_point_live_20260623.json показало, что этот путь теперь завершает полный кадр из 281 бита без тайм-аута; это достаточно закрывает прежнее опасение «кадр пропадает, потому что TX асинхронный», чтобы продолжать отлаживать BER на самом детерминированном пути;
  • остаточный BER всё ещё не низкий, поэтому следующий лёгкий эксперимент добавил выбираемые из плоскости управления режимы решения RX через биты 3:2 GPREG0;
  • разведочная развёртка режимов docs/assets/lab126_runtime_bridge_txrx_self_timed_mode_sweep_live_20260623.json предполагает, что на самотактируемом пути neg-i лучше режима по умолчанию i, а последующий чистый повтор docs/assets/lab126_runtime_bridge_txrx_self_timed_neg_i_single_point_live_20260623.json показывает, что путь по-прежнему доходит до полного кадра, но остаётся чувствительным к сессии.

Текущая закоммиченная базовая линия безопасности:

  • стоково-безопасный путь восстановления по-прежнему hardware/7020_ad936x_sdr/stock_system_top_from_BOOT.bin; при старом запасном варианте uEnv.txt с loadb для .bit.bin он не доказывал произвольную внешнюю замену PL, но при новом ручном пути UART fpga load он теперь единственный продемонстрированный внешне загружаемый кандидат, безопасный для загрузки;
  • извлечённый стоковый раздел BOOT также единственная внешне загружаемая полезная нагрузка PL, которая сейчас проходит ручной UART fpga load с живым AD9361; см. docs/assets/lab112_clean_boot_pl_validation.json;
  • автономный вендорский эталон hardware/7020_ad936x_sdr/ps/ad936x_no_os_reference/platform/hw/system_top.bit остаётся соотнесённым с исходниками сырым контрольным кандидатом, но по-прежнему теряет AD9361 и как сырой fpga loadb, и как ручной .bit.bin fpga load;
  • hardware/7020_ad936x_sdr/boot/validate_clean_boot_overlay.py фиксирует решающее доказательство UART для сырого fpga loadb, а hardware/7020_ad936x_sdr/boot/validate_manual_uart_fpga_load.py теперь покрывает ручной путь .bit.bin fpga load;
  • пересобранный shell vendor_only теперь тоже проходит создание проекта Vivado, реализацию, генерацию bitstream и экспорт XSA, но по-прежнему не проходит чистую загрузку с тем же тайм-аутом калибровки AD9361;
  • новый режим bridge_rx_only теперь проходит создание проекта Vivado, реализацию, генерацию bitstream и экспорт XSA;
  • сохранённый снимок вендорского zc702.xpr, пересобранный через hardware/7020_ad936x_sdr/rebuild_vendor_xpr_snapshot_mio_patch.tcl, по-прежнему экспортирует XSA без расхождений модулей/диапазонов памяти/параметров с вендорским эталоном, но его прямая загрузка сырого system.bit по-прежнему не проходит чистую загрузку AD9361 с тем же тайм-аутом калибровки;
  • более новый кандидат чистой загрузки сырого bridge_txrx_mux теперь доказывает, что собственный overlay курса действительно доходит до PL и предоставляет axi_gpreg на плате после перезагрузки; см. docs/assets/lab118_axi_gpreg_bringup_cleanboot_raw.json;
  • ранний сгенерированный помощником кандидат bridge_txrx_mux.bit.bin был отвергнут U-Boot fpga load с zynq_validate_bitstream: Bitstream is not validated yet (diff 1700), поэтому последующее здоровое состояние AD9361 на этом пути было от нетронутого стокового shell PL;
  • после исправления преобразования .bit -> .bit.bin в правильную полезную нагрузку с перестановкой слов заново сгенерированный кандидат bridge_txrx_mux.bit.bin теперь принимается ручным UART fpga load, но Linux по-прежнему попадает в тот же тайм-аут калибровки AD9361 и предоставляет только iio:device0;
  • заново сгенерированные кандидаты для загрузки из AD936X_PL.zip и AD936X_only_PL.zip были отвергнуты и сведены в docs/assets/lab112_clean_boot_pl_validation.json.

Интерпретация:

  • плоскость управления gpreg от PS к PL была проверена на реальном железе хотя бы один раз в раннем overlay с включённым пакетом;
  • та же плоскость управления gpreg теперь читается и после прямой чистой загрузки сырого кандидата bridge_txrx_mux: ID и подпись равны 0x4250534B, tx_valid_count > 0, rx_valid_count == 0;
  • исправленная перезагрузка через fpga_manager во время работы теперь воспроизводит то же чтение gpreg из стокового shell Linux без потери базового перечисления устройств IIO, поэтому препятствие уже не в том, что «плата вообще не видит overlay»;
  • сравнение стокового и загруженного во время работы образа теперь доказывает, что стоковый shell Linux до любой перезагрузки поддерживает оба пути хостового приёма RX, а горячая загрузка ломает оба, хотя axi_gpreg остаётся видимым;
  • уточнённое свидетельство bridge_rx_only во время работы добавляет более сильный отрицательный результат: даже когда стоковый вендорский тракт TX успешно передаёт общий пакет BPSK, мост по-прежнему видит rx_valid_count = 0, а слово CAPTURE_DEBUG сырого отвода RX остаётся нулевым;
  • результат повторной инициализации RX common во время работы сильнее прежнего отрицательного свидетельства: тракт RX на стороне fabric теперь можно оживить после горячей загрузки, но хостовый путь приёма libiio/DMAC по-прежнему сломан;
  • первая развёртка start_offset после повторной инициализации показывает, что приёмный тракт BPSK во время работы теперь достаточно жив, чтобы завершить попытку приёма полного кадра из 281 бита, поэтому препятствие уже не в мёртвой проводке RX;
  • объяснение с offset-binary закрывает эту конкретную ошибку: приёмная цепочка больше не застревает на беззнаковых сырых отсчётах AD9361, и отрицательные решения / восстановленные биты 1 теперь появляются на железе;
  • новый результат с самотактируемым bridge_txrx_mux снимает прежнее объяснение «вся проблема в хостовом циклическом TX»: полные кадры теперь воспроизводятся без тайм-аута на тракте TX/RX, принадлежащем PL, но BER всё ещё зависит от полярности решения и дрейфует между сессиями;
  • поэтому следующее препятствие это более узкая проблема на стороне приёма: стабилизировать детерминированный самотактируемый путь, затем решить, нужен ли следующим шагом чуть более развитый каскад коррекции фазы/оси или настоящий детектор преамбулы/кадра в приёмном тракте FPGA;
  • нормализованный поток vendor_only на чистом Tcl теперь устраняет прежнее расхождение MIO14/15, но по-прежнему заблокирован четырьмя производными параметрами, доступными только для чтения или отключёнными: sys_ps7.PCW_S_AXI_HP0_FREQMHZ, axi_ad9361_adc_dma.DMA_AXI_PROTOCOL_SRC, axi_ad9361_dac_dma.DMA_AXI_PROTOCOL_DEST и axi_ad9361.SPEED_GRADE; см. docs/assets/vendor_reference_vs_vendor_only_handoff_diff.json;
  • сохранённый снимок вендорского zc702.xpr после пересборки через поток правки MIO14/15 по-прежнему предпочтительный редактируемый источник-свидетель, но ещё не безопасная для загрузки RF-базовая линия; см. docs/assets/vendor_reference_vs_vendor_xpr_mio14_15_patch_handoff_diff.json;
  • текущий закоммиченный HDL теперь также включает промежуточный режим повторной интеграции bridge_rx_only, проверенный в Vivado, но ещё не при чистой загрузке;
  • извлечённый из BOOT.bin стоковый раздел теперь единственная внешне загружаемая безопасная для загрузки опора повторной интеграции, но он ещё недостаточно редактируем и недостаточно соотнесён с исходниками для итогового overlay курса;
  • ближайшая задача: убрать оставшуюся неоднозначность асинхронного кадра из пути BER во время работы, затем продолжить перенастройку тайминга / фазы при уже закрытой ошибке формата отсчётов, параллельно продолжая исследование безопасного для загрузки shell для редактируемого пути чистой загрузки.

Следующий порядок повторного включения (по этапам)

  1. Убедиться, что кандидат пользовательского загрузочного образа PL принимается соответствующим валидатором: сырой .bit через validate_clean_boot_overlay.py либо .bit.bin через validate_manual_uart_fpga_load.py.
  2. Подтвердить IP платы, регистр ID axi_gpreg и подпись моста до записи параметров кадра.
  3. Снова включить мост домена отсчётов, сохраняя видимую для Linux оболочку DMA неизменной.
  4. Держать ослабление TX AD9361 на минимальной доступной мощности.
  5. Держать усиление RX низким и ручным. Не включать AGC для первого возобновлённого пакета.
  6. Запустить только один короткий пакет.
  7. Наблюдать busy, затем done либо done после таймаута.
  8. Прочитать RECEIVED_BITS, TOTAL_ERRORS и PAYLOAD_ERRORS.
  9. Только после этого возобновлять повторные развёртки или кампании BER.

Чек-лист отчёта

  • Приложить путь к заново сгенерированному XSA и подтвердить axi_gpreg_bpsk.
  • Приложить путь к заново сгенерированному bitstream.
  • Показать базовый адрес 0x79040000 в экспортированном handoff.
  • Записать одно успешное чтение ID и одно успешное чтение подписи.
  • Показать записанные FRAME_BIT_COUNT, PREAMBLE_COUNT и START_OFFSET.
  • Указать, наблюдались ли busy, done и timeout.
  • Записать RECEIVED_BITS, TOTAL_ERRORS и PAYLOAD_ERRORS.
  • Перечислить ослабление TX и усиление RX AD9361, использованные для первого возобновлённого пакета.

Шаблон инженерного вывода

Overlay AD9361 на основе gpreg готов / не готов как базовая линия чистой загрузки.
Экспортированный handoff содержит / не содержит ожидаемое окно управления.
Следующий шаг повторной интеграции — ______, критерий его успеха — ______.