Комментарии 29
Я сегодня сладкого больше не ем. Мне достался огромный кусок торта в этой отличной статье!
Спасибо автору!
Наконец-то хоть что-то интересное, а не корпоративная копирайтерская вода (но зато написанная без отвлечения внимания разработчиков: https://habr.com/ru/articles/858258/)
Давно хочется этот PCIe пощупать, и даже KC705 есть, времени только нехватает.
Но после этой статьи мотивации прибавилось.
Хм. То есть в этой железяке квадратурные компоненты для отладки можно писать в файл почти неограниченно. Круто. Интересно как организована демодуляция на artix
Да, это вполне рабочая схема — можно стримить I/Q через PCIe, USB или Ethernet и обрабатывать всё на CPU/GPU (например, в GNU Radio , Python или C). Но если важна минимальная задержка или требуется real-time, лучше выполнять обработку прямо в FPGA: NCO, микшер, фильтрация, демодуляция — всё это реализуемо как в виде одного пайплайна, так и через набор сопроцессорных ядер.
У меня оба подхода реализованы в разных проектах:
Один — SDR с обработкой на хосте.
Второй — полноценный трансивер с OFDM и MIMO, где все расчёты идут внутри FPGA.
Для передачи данных используются каналы C2H и H2C через XDMA:
Потоки разделяются по направлениям: RX → C2H, TX ← H2C
Пример скорости передачи данных:
В одну сторону (2 канала, 61.44 MSps, 16-бит I/Q): ~3.93 Гбит/с
В обе стороны: ~7.86 Гбит/с
PCIe Gen1 x4 (4 × 2.0 Гбит/с) справляется с такой нагрузкой, но на практике узким местом чаще становится RAM или CPU хоста, особенно при непрерывной high-rate передаче.
Странно использовать dma для uart 9600, имхо. Fifo есть, прерывание и блокирующее чтение/запись, нагрузки на cpu сравнимы с 0. Да даже пулинг по таймеру несильно загрузит систему, имхо.
Да нет тут ни DMA ни прерываний, ими только пугают. По сути всё взаимодействие с железом тут в 3 строчках:
ioread32(priv->base + UARTLITE_STATUS);
iowrite32(val, priv->base + UARTLITE_TX_FIFO);
ioread32(priv->base + UARTLITE_RX_FIFO);
Т.е. просто побайтово пишут/читают через регистр, предварительно проверяя статус - самый примитивный метод. А остальное нужно чтобы оно виделось и работало в системе как COM порт.
Только непонятно, что можно сделать с SDR на скорости 9600 - просто какая-то настройка, а основной поток данных идет по другому каналу?
У меня немного другой случай — UART IP реализован в FPGA и доступен (его адресное пространство, регистры) через PCIe как AXI memory-mapped устройство. Использую AXI Lite, подключённый к PCIe BAR. На хосте доступ идёт через XDMA IP от Xilinx (или свой драйвер), но только memory-mapped интерфейс — DMA здесь не используется, он просто не нужен для UART.
UART используется для получения сообщений от GPS приемника. Поэтому достаточно обычного доступа к регистрам через mmap
, как к памяти. Основной поток данных (например, для SDR) передаётся через другие интерфейсы с DMA.
Торт так торт, спасибо вам!
Ещё бы вот о разработке железа почитать, но тогда совсем слипнется 😁
Моя SDR-плата
А что за плата?
Это моя собственная SDR-плата, полностью разработанная мной с нуля.
Использую её вместе с LattePanda Sigma (x86) и Nano PC T6 (ARM) — основная идея: компактный, полностью автономный SDR-модуль с 2×RX и 2×TX до 6 ГГц, на котором можно поднять полноценную связь, включая собственный проприетарный baseband.
Что на борту:
FPGA Xilinx Artix-7 (опции: 35T / 75T / 100T / 200T)
RF-трансивер: AD9361 / AD9364 / AD9363
DDR3-память
GPS-модуль SIM68
MPU9250 (акселерометр, гироскоп, магнитометр)
Датчик давления
Плата подключается через PCIe x4 (формат M.2 2280).
Я так понимаю в заголовке в скобочках заключено основное время работы, а про вечер упомянуто, как раз про тот, в который статья на публикацию ушла)
Проект весь на модульном дизайне построен? Я как-то от текстовых модулей топ-уровня отвыкнуть так и не смог.
Формфактор sdr приёмника под м2 слот тупо топ.
Тот момент когда ощущаешь себя героем мема "Ничего не понятно, но жутко интересно", но по окончанию чтения понимаешь что статья, это торт в кубе!
Круто, но без огонька. :)
Какое-то крупно-панельное домостроение получается - потыкали мышью в разные окошечки и кнопочки, выбрали опции и вуоля - гигантский кусок проприетарного кода на Verilog, об устройстве котрого мы ничего не знаем и даже не имеем шанса узнать. Но зато работает, байтики пересылаются, через DMA. Только зачем тут DMA ?
Автор в любом случае молодец, что смог разобраться. PCIe это самая сложная цифровая технология на сегодняшний день.
PS: Хотелось бы теперь увидеть аппаратную сторону. Та, что со стороны ПЛИС.
Так он же не писал ядро PCIe с нуля - оно готовое от производителя, воткнул в проект, назначил пины и готово. И никакого DMA тут нет, по крайней мере UART работает через примитивное PIO. DMA если и используется, то для чего-то, не описанного в статье.
Как справедливо было замечено — зачем изобретать велосипед зачем писать PCIe с нуля, когда есть отличные ядра от вендоров и целый набор достойных open-source решений, в которые уже кто-то выложился по полной.
Моя цель была не в том, чтобы изобрести новое ядро, а чтобы поднять всю систему целиком — от SDR-модуля до работающего baseband-процессора со связью, навигацией, сенсорами, и, конечно, общением с хостом через PCIe. Дел — непочатый край: HDL, драйверы, пламенные костыли, память, DMA, управление потоками.
🔥 Огонёк — есть. В сердце, в душе, ну и иногда на плате — там с этим строго: светодиодов достаточно 😄
Аппаратную часть обязательно покажу — layout, трассировка, разводка, схемотехника. Будет жарко (и аккуратно).
зачем писать PCIe с нуля, когда есть отличные ядра от вендоров
Совершенно незачем - вполне логично использовать готовое и отлаженное. Тем более в ПЛИС оно скорее всего хардварное, т.к. на плисовой логике просто нереально добиться нужного быстродействия. Комментарий был в ответ на фразу:
PCIe это самая сложная цифровая технология на сегодняшний день.
Очевидно, что сроектировать своё или использовать готовое - отличаются по сложности на несколько порядков. В случае использования готового ничего сверхсложного нет.
Кстати неплохо бы описать общими словами что за устройство проектируете и с какиой целью. А то вообще непонятно - толи это самодельный GPS модуль, который с внешним миром общается только через NMEA, толи комбайн всё в одном, но пока что описали только UART для GPSa.
Статья супер. Расскажите, как передаете квадратуры через PCIe? Лучше в виде статьи )
Интересно, рассматривали ли вы возможность использования UIO-драйвера вместо написания полноценного TTY-драйвера? Это могло бы упростить доступ к регистрам из пользовательского пространства без необходимости внедрения в ядро. Также, как насчет использования более высоких скоростей передачи данных через UARTLite? 9600 бод может быть узким местом в некоторых приложениях. В целом, статья вдохновляет на эксперименты с FPGA и Linux.
Да, идея с UIO действительно хорошая — особенно когда нужен простой и быстрый доступ к регистрам через AXI Lite (BAR).
Но в моём случае я использую DMA-каналы (H2C / C2H), так что UIO не подойдёт. Для потоковых данных нужно полноценное взаимодействие с буферами, прерываниями и адресным пространством — поэтому задействован драйвер xdma от Xilinx и свой.
Параллельно собираю "свой танк" — с полным контролем над PCIe, SDR-цепочкой и всей архитектурой.
UART у меня подключён только к GPS-модулю, и никаких ограничений по скорости нет — при желании вы легко можете менять параметры (скорость, формат, режим работы) под свои задачи.
Блин, я за вечер (почти) даже прочитать статью не осилил :)
Затолкаем, братцы!!! UART Lite через PCIe прямиком в Linux: драйвер за вечер (почти)