Лабораторная 5.6 — RTL FIR формирующего RRC-фильтра BPSK TX¶
Цель¶
Продвинуть исполняемый HDL-маршрут BPSK за пределы маппера символов и реализовать настоящий 65-коэффициентный FIR формирования импульса в Q1.15, используемый общим эталонным пакетом Блока 11.
Эта работа это первый настоящий мост от fixed-point модели Simulink к переиспользуемому RTL-блоку модема:
handoff BPSK Блока 11 -> маппер символов -> RRC TX FIR -> будущие TX gain / ЦАП / интеграция Zynq
Исполняемый HDL-пакет¶
| Файл | Назначение |
|---|---|
blocks/block_05_fpga_hdl_flow/rtl/bpsk_rrc_tx_fir.v |
65-коэффициентный FIR формирования импульса Q1.15 для потоков I/Q |
blocks/block_05_fpga_hdl_flow/rtl/bpsk_rrc_tx_fir_taps.mem |
сгенерированный образ ROM коэффициентов из rrc_taps_q15.txt |
blocks/block_05_fpga_hdl_flow/python/generate_bpsk_rrc_tx_fir_vectors.py |
пересоздаёт память коэффициентов и детерминированные тестовые векторы |
blocks/block_05_fpga_hdl_flow/tb/tb_bpsk_rrc_tx_fir.v |
самопроверяющийся Verilog-testbench |
blocks/block_05_fpga_hdl_flow/tb/bpsk_rrc_tx_fir_input_vectors.txt |
сгенерированный выход маппера в Q1.15 после повышения частоты |
blocks/block_05_fpga_hdl_flow/tb/bpsk_rrc_tx_fir_expected_vectors.txt |
сгенерированный эталонный выход FIR в Q1.15 |
Запуск из корня репозитория:
python blocks/block_05_fpga_hdl_flow/python/generate_bpsk_rrc_tx_fir_vectors.py
iverilog -g2012 \
-o blocks/block_05_fpga_hdl_flow/tb/tb_bpsk_rrc_tx_fir.out \
blocks/block_05_fpga_hdl_flow/rtl/bpsk_rrc_tx_fir.v \
blocks/block_05_fpga_hdl_flow/tb/tb_bpsk_rrc_tx_fir.v
vvp blocks/block_05_fpga_hdl_flow/tb/tb_bpsk_rrc_tx_fir.out
Ожидаемый результат:
PASS: bpsk_rrc_tx_fir test completed without errors
Общие входные данные¶
Работа намеренно использует тот же общий пакет, что и Блок 4.4:
| Общий файл | Роль на этом шаге RTL |
|---|---|
tx_symbols_q15.txt |
детерминированный поток символов после BPSK-маппинга |
rrc_taps_q15.txt |
точные 65 коэффициентов формирующего фильтра |
config.json |
задаёт samples_per_symbol = 8 для вставки нулей |
Python-генератор повышает частоту символов, добавляет хвост для очистки фильтра, вычисляет fixed-point отклик FIR и записывает и тестовые векторы, и файл памяти ROM.
Тракт данных¶
flowchart LR
MAP[Символы BPSK Q1.15] --> UPS[Вставка нулей 8x]
UPS --> SR[Сдвиговый регистр на 65 отсчётов]
SR --> MUL[Знаковые умножители 16x16]
TAPS[ROM коэффициентов RRC] --> MUL
MUL --> ACC[40-битный аккумулятор]
ACC --> ROUND[Округление Q2.30 до Q1.15]
ROUND --> SAT[Насыщение до 16 бит]
SAT --> OUT[Отсчёты Q1.15 после формирования импульса]
Контракт fixed-point¶
| Параметр | Значение |
|---|---|
| Формат входного отсчёта | знаковый Q1.15 |
| Формат коэффициентов | знаковый Q1.15 |
| Формат произведения | знаковый Q2.30 |
| Число коэффициентов | 65 |
| Минимум защитных бит | ceil(log2(65)) = 7 |
| Ширина аккумулятора в RTL | 40 бит |
| Формат выхода | знаковый Q1.15 с насыщением |
Связь с Simulink¶
Блок 4.4 уже проверяет тот же тракт формирования импульса в Simulink с общими коэффициентами rrc_taps_q15.
Эта работа использует те же коэффициенты и тот же поток символов, поэтому на следующем шаге интеграции можно сравнить:
- выход MATLAB/Simulink;
- выход RTL-симуляции;
- итоговый захват отсчётов TX на Zynq.
Чего ожидать¶
PASS: bpsk_rrc_tx_fir test completed without errors (2312 vectors, latency 9 cycles)
2312 = 281 символ x 8 отсчётов + 64 отсчёта дочистки (NTAPS - 1), так что проверяется весь хвост фильтра. Задержка 9 тактов это конвейер: симметричное предсложение (1), умножение (1), 6-ступенчатое дерево сумматоров, сводящее 33 произведения (33 -> 17 -> 9 -> 5 -> 3 -> 2 -> 1), и регистр округления/насыщения (1).
Раннер курса генерирует векторы, компилирует, запускает симуляцию и считает ошибкой любую строку FAIL или ненулевой код выхода симулятора:
python tools/run_block5_hdl_smoke.py --test tb_bpsk_rrc_tx_fir
В Vivado 2021.1 фильтр размещается и разводится на кристалле курса xc7z020clg400-2 на 100 МГц
с запасом +3,038 нс и занимает 96 DSP48E1, 2266 триггеров и 148 LUT
(отчёт). Журнал синтеза показывает, куда уходят 96 блоков: 66 выполняют
умножения (по 33 на канал, симметричное предсложение каждого это внутри блока), а 30 используются
только как 40-битные сумматоры дерева. Сравните это со своим ответом на упражнение 3: полностью
параллельный фильтр дёшев по таймингу и дорог по площади.
Упражнения¶
Каждое упражнение ниже: намеренная мутация RTL в одну строку. Внесите её, запустите testbench, прочитайте сообщения и верните файл (git checkout -- <file>). Приведённые выводы получены на Icarus Verilog 12.0.
- Замените округление усечением:
round_q15 = value >>> SHIFT;. Testbench сообщаетFAIL: bpsk_rrc_tx_fir test completed with 1084 errors, каждая на 1 LSB меньше, напримерout=(23,0) expected=(24,0). Почему это близко к половине из 2312 выходов? - По RTL подтвердите задержку 9 тактов поступенчато и скажите, какое число изменится, если
NTAPSвырастет с 65 до 129. - Фильтр симметричный, поэтому ему нужно 33 умножителя вместо 65. Сколько DSP48 займут I и Q вместе на Zynq-7020 и сколько понадобится версии с разделением по времени (folded) при 8 тактах на отсчёт?
Ответы (сверены с RTL и стендом)
- Усечение ошибается ровно тогда, когда отброшенная дробная часть не меньше половины МЗР. Дробные части произведений распределены почти равномерно, поэтому ошибается около половины выходов (1084 из 2312, 47 %); остальные либо имели дробную часть меньше половины, либо были точными.
- Входной регистр симметричных пар отводов (1), умножители (2), шесть уровней дерева сумматоров для 33 произведений (3–8,
⌈log2 33⌉ = 6) и выходной регистр с округлением и насыщением (9). ПриNTAPS = 129произведений 65, и дереву нужно⌈log2 65⌉ = 7уровней: латентность становится 10. - Арифметика даёт 33 умножителя на канал, 66 на I и Q. Out-of-context прогон Vivado для этого RTL показывает 96 DSP48E1 (отчёт Vivado блока 5): синтез не всегда раскладывает проект так, как считаешь на бумаге, поэтому курс приводит измеренные числа. При свёртке на 8 тактов на отсчёт:
⌈33/8⌉ = 5умножителей на канал, около 10 на оба. Ещё лучше: большинство входов это вставленные нули, и полифазная версия из Лабораторной 5.7 использует 14 DSP48E1 на повышающий дискретизатор и фильтр вместе.
Чек-лист отчёта¶
- Показано, что один и тот же
rrc_taps_q15.txtпитает и Simulink, и RTL. - Указаны ширина аккумулятора и правило округления.
- Объяснено, почему
NTAPS = 65требует больше, чем учебная 4-коэффициентная архитектура. - Приложен лог
PASSсамопроверяющегося testbench. - Указано, какой блок следующий: TX gain / кадрирование или согласованный фильтр RX.
Шаблон инженерного вывода¶
RTL BPSK TX FIR принимает общие символы Q1.15 Блока 11 и 65 коэффициентов RRC.
Проект использует 40-битный аккумулятор и округляет обратно в Q1.15 с насыщением.
Теперь этот блок — опорная точка формирования импульса между маппером символов и будущим передающим трактом Zynq.