OFDM IP-ядра
Модуляция и демодуляция OFDM на IP ядрах в Engee
В примере рассмотрим передачу BPSK- и QPSK-сигналов через модулятор и демодулятор OFDM на IP-ядрах Engee. Проверим восстановление данных, оценим EVM и посмотрим созвездия. Модель работает без шума, поэтому результат показывает погрешность вычислений с фиксированной точкой.
OFDM распределяет данные по ортогональным поднесущим. Передатчик формирует символ с помощью IFFT и добавляет циклический префикс; приёмник удаляет префикс и выполняет FFT. В нашей модели из 2048 поднесущих для данных используются
Остальные отведены под защитные полосы и нулевую поднесущую.

Генератор на C выдаёт комплексные отсчёты BPSK или QPSK в формате Q14. После преобразования в Fixed-point сигнал проходит через OFDM Modulator и OFDM Demodulator.
Размер FFT — 2048, циклический префикс — 64 отсчёта, окно — 32. Защитные полосы содержат 128 и 127 поднесущих, DC-поднесущая отключена. Коэффициент 0.5 на входе создаёт запас по амплитуде, а коэффициент 2 на выходе восстанавливает масштаб. StartupReset сбрасывает ядра в первые четыре такта.
Параметры и подготовка
Частота дискретизации — 30.72 МГц, время моделирования — 1 мс. Один символ с префиксом занимает 2112 тактов. Для начала загрузим функции запуска и анализа модели.
using Main: engee, plot, plot!, histogram, hline!, savefig, Animation, frame, gif
using JSON
if !isdefined(Main, :OFDMIPDemo)
Base.include(Main, joinpath(@__DIR__, "ofdm_demo.jl"))
end
using Main: OFDMIPDemo
ofdm_dir = @__DIR__
ofdm_output = mktempdir(; prefix="ofdm_ip_results_")
println("Результаты: ", ofdm_output)
println("FFT = ", OFDMIPDemo.NFFT, "; полезных поднесущих = ", OFDMIPDemo.ND)
Модель, вспомогательный скрипт и исходники генератора находятся рядом с этим скриптом. Пути определяются относительно его папки.
Проверка BPSK
Запустим модель с BPSK. Сравним переданные и восстановленные символы и проверим количество битовых ошибок.
bpsk_result = OFDMIPDemo.run_case(ofdm_dir; modulation=0)
println(JSON.json(bpsk_result.metrics))
write(joinpath(ofdm_output, "bpsk_metrics.json"), JSON.json(bpsk_result.metrics))
Получено семь полных OFDM-символов: 12544 комплексных отсчёта. EVM составляет около 0.46 %, битовых ошибок нет. Начальный нулевой отсчёт не участвует в проверке битов.
EVM рассчитываем по полным блокам с активным сигналом valid, без подгонки фазы и масштаба:
Анализ BPSK
Построим созвездия, ошибку восстановления и сигналы valid.
bpsk_figure = OFDMIPDemo.result_plot(bpsk_result)
savefig(bpsk_figure, joinpath(ofdm_output, "bpsk_results.png"))
display(bpsk_figure)
Восстановленные точки расположены рядом с исходными. График ошибки показывает погрешность вычислений, а сигналы valid — интервалы выдачи данных ядрами.
Проверка QPSK
Повторим запуск для QPSK. Биты определяются по знакам действительной и мнимой частей восстановленного сигнала.
qpsk_result = OFDMIPDemo.run_case(ofdm_dir; modulation=1)
println(JSON.json(qpsk_result.metrics))
qpsk_figure = OFDMIPDemo.result_plot(qpsk_result)
savefig(qpsk_figure, joinpath(ofdm_output, "qpsk_results.png"))
display(qpsk_figure)
Для QPSK получаем четыре группы точек, EVM около 0.47 % и ни одной ошибки среди 25086 проверенных битов.
Повторяемость и сохранение результатов
Ещё раз запустим BPSK и сравним результаты. Сохраним данные трёх запусков для дальнейшего анализа.
bpsk_repeat = OFDMIPDemo.run_case(ofdm_dir; modulation=0)
@assert bpsk_repeat.metrics["evm_percent"] == bpsk_result.metrics["evm_percent"]
@assert bpsk_repeat.metrics["bit_errors"] == 0
ofdm_report = Dict("status"=>"passed", "notebook_executed"=>true, "channel"=>"direct noiseless IP-core loopback", "runs"=>[bpsk_result.metrics, qpsk_result.metrics, bpsk_repeat.metrics])
write(joinpath(ofdm_output, "verification.json"), JSON.json(ofdm_report))
string("OFDM IP demo passed; BPSK EVM=", round(bpsk_result.metrics["evm_percent"];digits=4), "%; QPSK EVM=", round(qpsk_result.metrics["evm_percent"];digits=4), "%; bit errors=0")
Повторный запуск даёт те же данные и метрики. Это подтверждает воспроизводимость модели при одинаковых параметрах и сбросе ядер.
Вывод
Модель демонстрирует OFDM-передачу с модуляцией поднесущих BPSK и QPSK на IP-ядрах Engee. В канале без шума данные восстанавливаются без битовых ошибок, а EVM составляет около 0,46–0,47%. Небольшое отклонение принятых символов связано с вычислениями в фиксированной точке.