Lab 11.45 — Дифференциальный QPSK + длинная преамбула: пол разворотов повержен¶
Цель¶
Устранить остаточные развороты всего бёрста, пережившие фикс lock-толеранса, и обойти абсолютный
образ tol=1 по BER — не потеряв чистоту двухплатного канала.
Предыстория: Lab 11.42 (фикс ложного захвата, оставивший
~1% пол разворотов) и Lab 11.43 — дифф-кодек lab_11_43_dqpsk_model.py — снимающий неоднозначность
поворота в корне.
Дуга¶
- Пол — это разворот всего бёрста на 90°, который frame-sync изредка разрешает неверно.
tol=1убрал скользящую компоненту; осталась карьер-маргинальная (~1%). - Дифференциальный QPSK снимает неоднозначность: информация — в разности фаз соседних символов, поэтому постоянный поворот сокращается. Кодек доказанно корректен — в когерентном fabric-loopback с Gardner декодирует при BER 0, инвариантен к повороту офлайн и в RTL.
- Но на двухплатном канале он ошибается на одном раннем символе payload (кластер на payload-индексе 5 = символ 14). Все изолирующие тесты отвергли очевидные причины — не кодек (loopback идеален), не данные кадра (офлайн идеален), не 180°-переход, не величина CFO.
- Причина — транзиенты адаптивных петель. Дифф-декодирование читает разность фаз соседних символов, поэтому любая петля 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 BER4,45×10⁻⁴.
Ещё длиннее — хуже: 32-символьная преамбула уронила lock rate (кадр вместе с RX_SAMPLE_MARGIN вышел
за окно сэмплера). 24 символа — рабочая точка.
О чём эта лаба на самом деле¶
На дифф-транзиент было два фикса. Заморозка адаптивных петель после преамбулы — учебниковый ответ, но архитектурно непрактичный: петли стоят до детекции кадра, двухплатный поток непрерывен (нет границы «сигнал появился»), а задержка кадра переменна — значит нет своевременного сигнала «преамбула пройдена», чтобы им его подать. Удлинение преамбулы достигает того же (payload стартует уже устоявшимся) — рантайм-параметром и без новой логики. Более дешёвый фикс оказался не меньшей идеей, а той, что легла в архитектуру.