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

Lab 11.45 — Дифференциальный QPSK + длинная преамбула: пол разворотов повержен

Цель

Устранить остаточные развороты всего бёрста, пережившие фикс lock-толеранса, и обойти абсолютный образ tol=1 по BER — не потеряв чистоту двухплатного канала.

Предыстория: Lab 11.42 (фикс ложного захвата, оставивший ~1% пол разворотов) и Lab 11.43 — дифф-кодек lab_11_43_dqpsk_model.py — снимающий неоднозначность поворота в корне.

Дуга

  1. Пол — это разворот всего бёрста на 90°, который frame-sync изредка разрешает неверно. tol=1 убрал скользящую компоненту; осталась карьер-маргинальная (~1%).
  2. Дифференциальный QPSK снимает неоднозначность: информация — в разности фаз соседних символов, поэтому постоянный поворот сокращается. Кодек доказанно корректен — в когерентном fabric-loopback с Gardner декодирует при BER 0, инвариантен к повороту офлайн и в RTL.
  3. Но на двухплатном канале он ошибается на одном раннем символе payload (кластер на payload-индексе 5 = символ 14). Все изолирующие тесты отвергли очевидные причины — не кодек (loopback идеален), не данные кадра (офлайн идеален), не 180°-переход, не величина CFO.
  4. Причина — транзиенты адаптивных петель. Дифф-декодирование читает разность фаз соседних символов, поэтому любая петля RX, ещё подстраивающаяся в раннем payload — Costas, схождение скользящего среднего DC-блокера, тайминг Gardner — портит его. Когерентный loopback чист именно потому, что эти петли выключены. Выключение DC-блокера на двухплатном канале уполовинивает кластер — это и был подтверждающий тест.

Почему рычагом оказалась преамбула

Петли захватываются в окне, которое длиннее 12-символьной преамбулы. По tb_qpsk_costas_acq_window: freeze-gate открывается ~за 16 символов до кадра, акквизиция идёт ACQ_SYMBOLS=32, а frame-sync лочится на символе 31 — то есть петли ещё слюят ~4 символа внутрь payload. В абсолютном QPSK это невидимо (после лока каждый символ верен); в дифференциальном — рушит ровно эти ранние символы payload.

Чистый фикс — не заморозка петель (архитектурно непрактично: они стоят до детекции кадра, поток непрерывен и задержка кадра переменна), а начать payload позже: длиннее преамбула. И поскольку длина кадра и смещение преамбулы — рантайм-параметры (symbol_count, preamble_count), а ROM хранит 512 бит, это не требует пересборки битстрима:

  • кадр = первые 304 бита ROM = 24-символьная преамбула + те же 256 бит payload;
  • запуск с symbol_count=152, preamble_bits=48;
  • коррелятор по-прежнему лочится на первых 24 битах (без ложных пиков); payload теперь начинается с символа 24, за транзиентом акквизиции.

make_long_preamble_frame() строит кадр; дифф-кадр по-прежнему замыкается чисто (сумма инкрементов 0 mod 4).

Результат (двухплатно, A TX1 → 30 дБ → B RX1)

absolute tol=1 (140/24) differential, 24-сим преамбула (152/48)
payload BER ~3×10⁻³ ~4×10⁻⁴ (≈7–13× лучше)
grubые (разворот бёрста) 0.75% 0
чистых кадров 98.9% 96.9–98.8%
инвариантность к повороту нет да

Пол разворотов исчез — grubые = 0 в каждом прогоне — и BER падает на порядок, потому что ни один бёрст больше не декодируется при ~46%. Чистых кадров сопоставимо: остаётся интермиттентный одиночный кластер (теперь около payload-индекса 19) — врождённый дифф-штраф ~3 дБ, а не разворот.

Машиночитаемые доказательства сохранены в два этапа:

  • docs/assets/lab1144_diff_qpsk_live.json — A/B на 400+400 кадров с absolute/differential режимами: грубые развороты исчезают, но проявляется ранний дифференциальный транзиент payload;
  • docs/assets/lab1145_diff_long_preamble_live.json — финальный прогон на 800 кадров с 24-символьной преамбулой, нулём грубых разворотов и payload BER 4,45×10⁻⁴.

Ещё длиннее — хуже: 32-символьная преамбула уронила lock rate (кадр вместе с RX_SAMPLE_MARGIN вышел за окно сэмплера). 24 символа — рабочая точка.

О чём эта лаба на самом деле

На дифф-транзиент было два фикса. Заморозка адаптивных петель после преамбулы — учебниковый ответ, но архитектурно непрактичный: петли стоят до детекции кадра, двухплатный поток непрерывен (нет границы «сигнал появился»), а задержка кадра переменна — значит нет своевременного сигнала «преамбула пройдена», чтобы им его подать. Удлинение преамбулы достигает того же (payload стартует уже устоявшимся) — рантайм-параметром и без новой логики. Более дешёвый фикс оказался не меньшей идеей, а той, что легла в архитектуру.