джуниор
14
0
26 мая 2026
джуниор

Как FPGA-разработчики превращают идеи в железо

Изображение создано
с помощью нейросети
Изображение создано с помощью нейросети
14
0
26 мая 2026

В учебных программах инженерных вузов разработка под FPGA освещается довольно мало, но в этой теме много интересно. Именно FPGA-разработка позволяет превратить алгоритм в «железо», которое будет работать ровно так, как вы его описали.

Как устроен переход от идеи к работающей системе? Чем FPGA-разработка отличается от классического программирования и зачем вообще нужны FPGA, если есть универсальные процессоры? Объясняет Кирилл Алексеев, ведущий инженер отдела интеграции систем на кристалле радиочастотного центра YADRO. В статье он подробно описывает процесс FPGA-разработки и рассматривает стек используемых технологий.

Из статьи вы узнаете
  • как распределяются роли в производстве цифровой аппаратуры
  • как выглядит процесс FPGA-разработки
  • какие нюансы есть в верификации RTL
  • кому подойдет FPGA-разработка и как проверить свои силы

Почему персональных компьютеров недостаточно

Зачем вообще нужны FPGA? Почему нельзя использовать обычный ПК с процессором от Intel для решения прикладных задач? Ответ простой: не хватает скорости.

Универсальные процессоры, на базе которых построены персональные компьютеры, отлично подходят для работы с документами, но они не способны обрабатывать большой объем информации в режиме реального времени. А специализированные вычислители очень даже способны (на то они и специализированные).

Отличный пример такого «железа» — видеокарты (GPU, графические ускорители). Когда вы играете в видеоигры, центральный процессор компьютера (CPU) не успевает в реальном времени изменять значение пикселей на экране: повороты сцен, изменение освещенности, эмуляцию физических процессов — например, движение травы или блики фонарей в лужах. Поскольку каждое изображение представляет собой трехмерную матрицу пикселей, то практически любая операция с графикой предполагает сложение или умножение матриц. Это требует огромного объема вычислений.

Внутри CPU реализованы универсальные вычислительные ядра, каждое из которых может выполнять множество различных операций: арифметических (сложение, умножение), логических (сравнение, битовые операции), последовательных операций над массивами и не только. Но из-за универсальности ядер CPU, их число невелико и обычно измеряется двузначными числами.

В отличие от CPU, графические ускорители состоят из тысяч небольших по размеру ядер, в которых реализованы только сумматоры и умножители: всё, что нужно для эффективной работы с матрицами. Именно за счет большого числа специализированных ядер, GPU могут «быстро перемолоть» всю векторную графику.

Структура CPU процессора (слева) и графического ускорителя GPU (справа)

Кроме графики есть множество других задач, с которыми CPU за приемлемое время не справляется. К примеру, физические модели, предсказывающие погоду с максимальной точностью, анализируют сотни взаимосвязанных параметров. Соответственно, при попытке запуска моделирования на обычном ПК результат предсказания погоды на час вперед может быть получен через день — а это, естественно, уже никому не нужно. Другой пример: цикл моделирования земной коры для поиска нефти и газа может занимать несколько месяцев даже на многопроцессорной вычислительной системе (МВС). Далеко не всегда бизнес готов ждать так долго.

Давайте зафиксируем, с какими задачами эффективно справляются специализированные вычислители:

  1. Обучение и инференс нейросетей. Работа с большими моделями в дата-центрах, где их обучают и запускают для обработки огромного потока запросов.
  2. Цифровая обработка сигналов (ЦОС) — обработка аудио-, видео- и радиосигналов в реальном времени. Например, в телеком-оборудовании и системах связи.
  3. Криптография — шифрование и защита данных в банковских системах, мессенджерах и других сервисах, где важна безопасность.
  4. L2-коммутация и маршрутизация пакетов — работа сетевого оборудования и дата-центров, которые обеспечивают быстрый доступ к сайтам и онлайн-сервисам.

Практически все описанные задачи можно эффективно решить при помощи ASIC. Но разработка и изготовление ASIC — сложный и дорогостоящий процесс, который обычно выгоден только при массовом производстве. Функциональность таких чипов нельзя изменить после их изготовления. Если в алгоритме будет ошибка, они окажутся непригодными для использования, а компанию ждут крупные расходы: перевыпускать придется всю партию микросхем.

Альтернатива заказным кристаллам — FPGA. Они проигрывают ASIC-микросхемам в эффективности, зато процесс FPGA-разработки проще — а значит, можно быстрее выйти на рынок с MVP, а потом дорабатывать решение без необходимости изменения «железа».

Роли в производстве цифровой аппаратуры

Теперь, когда мы разобрались, зачем нужны FPGA, попробуем разобраться, как они появляются. Превратить алгоритм в работающее «железо» — это не задача одного человека, а процесс, в котором участвует целая команда специалистов.

В идеальном мире производство аппаратуры организовано по принципу «разделяй и властвуй»: каждая отдельная функция реализуется отдельными специалистами. Если сильно упростить, путь от идеи к FPGA-системе выглядит так:

  • Алгоритмисты-математики начинают процесс. Они определяют, как решается задача: выбирают математический подход, оценивают точность и ограничения, задают основу будущего решения.
  • Программисты (функциональное моделирование) берут эту основу и проверяют ее в виде программной модели. Убеждаются, что идея работает до перехода в «железо».
  • Архитекторы системы превращают проверенную математику в структуру будущего FPGA: решают, как разложить алгоритмы на блоки и уложить их в ресурсы кристалла.
  • Разработчики IP-ядер на основе построенной архитектуры описывают конкретную цифровую схему на HDL-языке.
  • Разработчики битовых моделей уточняют поведение системы с учетом аппаратных ограничений — чтобы программная модель совпадала с тем, что получится на FPGA.
  • Верификаторы проверяют, что всё работает как задумано: сравнивают поведение схемы с эталонной битовой моделью и находят расхождения еще до стадии реализации в «железе».
  • Системные программисты добавляют вокруг FPGA программную среду: настраивают встроенные процессоры, операционные системы и драйверы управления.
  • Интеграторы собирают всё вместе: соединяют IP-ядра, процессорную часть и получают финальную рабочую систему и конфигурационные файлы FPGA.
  • Тестировщики проверяют результат уже на реальном железе и ловят ошибки, которые не проявились в симуляции.

Если посмотреть шире, вокруг этой цепочки есть и другие команды. Например, разработчики софта пишут управляющее ПО, которое отвечает за общую логику работы «железа», и делают пользовательский интерфейс. Еще в цикле разработки устройства участвуют конструкторы, разработчики печатных плат, наладчики, технические писатели, без которых конечное устройство не собрать и не запустить.

Где в этом списке FPGA-разработчики? Обычно они объединяют в себе сразу несколько ролей. В радиочастотном центре YADRO мы разрабатываем IP-ядра, верифицируем их, внедряем в конечную систему и отлаживаем на «железе».

Как выглядит процесс FPGA-разработки

Разберем, как описанная выше система работает на практике — на примере разработки FPGA-части одного устройства. Наша команда разрабатывает радиомодули сотовой связи (RU, Radio Unit), которые отвечают за преобразование информации в цифровой сигнал (модуляция) и обратное преобразование (демодуляция). Эти специализированные устройства состоят из множества блоков цифровой обработки сигналов, а использование FPGA позволяет им работать в реальном времени.

Разработка таких систем требует от алгоритмистов и архитекторов глубокого понимания алгоритмов ЦОС, принципов функционирования сотовых сетей и систем связи в общем. В радиочастотном центре YADRO эти специалисты не занимаются непосредственно разработкой, а формируют пул требований и конструкторскую документацию для FPGA-разработчиков и программистов, что обусловлено сложностью и мультикомпонентностью разрабатываемых систем. Но в других компаниях роль архитекторов могут выполнять иные люди. Например, это могут быть программисты, которые прислали тебе код и просят выполнить данные вычисления на ПЛИС. Иногда — заказчики, которые хорошо оформили ТЗ (это бывает реже), или непосредственный начальник. Конечно, идеально, когда FPGA-разработчик тоже может выполнять функцию архитектора, что облегчает и ускоряет процесс разработки, но это тема уже для другой статьи.

Если рассматривать в общем, в нашей команде процесс разработки выглядит так:

  1. Всё начинается с алгоритмов и требований, которые приходят от алгоритмистов и архитекторов. На их основе формируется микроархитектура IP-ядра — детальная проработка цифровой схемы, в том числе ее оптимизация под архитектуру выбранной ПЛИС. Здесь нужно учитывать число встроенных арифметических блоков DSP и блоков памяти, число и размер логических ячеек LUT, число встроенных процессорных ядер, контроллеров цифровых интерфейсов и памяти и так далее. Еще на этом этапе обычно формируется заготовка документации на IP-ядро.
  2. Следующий шаг — разработка программной «битовой» модели, в которой порядок и формат выполняемых операций в точности соответствует микроархитектуре IP-ядра. В зависимости от назначения разрабатываемого блока, функциональная модель может использоваться как эталон относительно точности вычислений. Сравнивая точность функциональной и «битовой» моделей можно подобрать оптимальную разрядность арифметических операций при переходе от float point арифметики к fixed point.
  3. Дальше переходим к разработке IP-ядер — это итеративный процесс описания схемы на HDL языке SystemVerilog по его архитектурной спецификации и в соответствии с разработанной микроархитектурой. Тут отдельно можно выделить разработку вычислительной части IP-ядра, подсистемы управления и регистрового пространства.
  4. После разработки, IP-ядра верифицируются с использованием эталонных данных «битовой» модели.
  5. Затем происходит интеграция IP-ядра в тестовый или боевой проект. На этом этапе мы упаковываем IP-ядро для его последующего использования в Block Design, с помощью которого собираем верхний уровень проекта. Тут же зачастую выполняется установка и настройка внутрисхемного анализатора, который позволяет выгружать состояние схемы прямо из работающей ПЛИС. Дальше нужно получить конфигурационный файл ПЛИС, в котором реализуемая схема будет работать на целевой тактовой частоте. Также на этапе интеграции выполняется сборка Petalinux с необходимым набором вспомогательных приложений, а также разработанным bash-скриптом для инициализации IP-ядра.
  6. Финальный шаг — тестирование проекта на реальном «железе»: отладочной плате, макете или же на «боевом» устройстве.

Часть задач может быть вынесена в отдельные роли — например, моделирование или подготовка эталонных данных. Но FPGA-разработчик закрывает заметную часть процесса сам: от описания логики до проверки ее работы в системе и отладки уже на реальном «железе», включая интеграцию с другими частями схемы. Это происходит потому, что этапы FPGA-разработки тесно связаны между собой и редко существуют по отдельности.

Разработка IP-ядра: HDL-кодирование

Архитектура и модель уже определены. Теперь начинается этап, где алгоритм превращается в описание схемы, конкретное под FPGA.

Схема (слева) и ее описание на HDL-языке SystemVerilog (справа)

FPGA-разработчик описывает цифровую схему IP-ядра на известном ему (и используемом в компании) HDL-языке. Я приверженец именно схемотехнического подхода: считаю его самым простым и понятным. Поэтому, если схемы нет, сначала стоит ее нарисовать, а уже потом приступать к кодированию. Обычно на схемах отражают вычислительное ядро, памяти и fifo, а также основные элементы схемы управления — мультиплексоры, приоритетные шифраторы и так далее. Если реализуется процедурная схема, в ней обязательно будет присутствовать подсистема управления, которую часто рационально описывать в виде управляющего автомата (FSM, Finite State Machine).

О том, что такое цифровые схемы IP-ядра как их описывать, можно почитать в тематических изданиях — составили для вас подборку «Лучшие книги по разработке цифровых микросхем».

Когда HDL-код IP-ядра готов, нам необходимо с помощью САПР получить конфигурационный файл ПЛИС. Для этого САПР выполняет три операции: синтез, размещение и трассировку. На этапе синтеза описанная схема IP-ядра отображается на примитивы используемой ПЛИС: LUT, триггеры, блоки памяти и арифметические DSP-блоки. На этапе размещения выполняется расстановка элементов синтезированной схемы на координатной плоскости кристалла, а на этапе трассировки выполняется прокладка связей между ними, для чего конфигурируется коммутационная матрица ПЛИС. После выполнения этих этапов САПР предоставляет отчеты об используемых ресурсах FPGA и максимальной тактовой частоте.

Компиляция схемы, синтез, размещение и трассировка

Чтобы удовлетворить требования тактовой частоты, на этапе трассировки САПР выполняет статический анализ временных характеристик схемы (STA, Static Timing Analysis). Важно, чтобы результаты STA не содержали ошибок по времени установки и удержания сигнала (Setup & Hold timing errors).

Так выглядит типичный Vivado Design Timing Report, в котором всё хорошо

Если полученные результаты устраивают, можно переходить к следующему этапу. Если же после STA-анализа есть ошибки, нужно изменять реализуемую схему. Как это сделать, советую почитать в FPGA-Systems Magazine на стр. 75, а также в статьях «Управление процессом синтеза вычислительной структуры при решении вычислительно-трудоемких задач на плис» и «Методика создания топологических ограничений при высокой утилизации ресурсов ПЛИС». Другой вариант — использовать иные стратегии синтеза, размещения и трассировки.

Что нужно понимать о верификации RTL

На практике этот этап идет параллельно с разработкой HDL-кода, поскольку разработчику важно понимать, работает ли то, что он написал, или нет. Отладка «в железе» намного сложнее верификации в симуляторе, поэтому не стоит пренебрегать выполнением этого этапа. Если мы живем в идеальном мире, здесь за нас все делают инженеры-верификаторы. Но даже в этом случае FPGA-разработчик обычно моделирует собственный блок хотя бы на нескольких базовых тестовых сценариях, перед его передачей для полного и всестороннего тестирования инженером-верификатором.

Разрабатываемое IP-ядро (DUT, Design Under Test) и верификационное окружение

Нужно учитывать, что этап верификации самый длительный. Предположу даже, что верификация подчиняется закону Парето (правило 80/20). То есть 20% времени ведется непосредственное написание 80% HDL-кода IP-ядра, тогда как остальные 20% кода — это правки на этапе верификации (и немного отладки), которая требует 80% времени.

В первую очередь верификатор разрабатывает тестовый план — по сути, список тестов, полнота которых согласуется с разработчиком, алгоритмистом и архитекторами блока. Только после их выполнения мы сможем однозначно утверждать, что блок работает корректно. С четко формализованным списком легче верифицировать блок. К тому же так меньше шансов, что вы упустили что-то важное.

Дальше собираем тестовое окружение. Для этого есть достаточно много техник от совсем простых до продвинутых — например, UVM. При этом сам подход к верификации остается неизменным: на вход тестируемого блока (DUT, Design Under Test) подается массив входных данных, после чего результат вычислений сравниваем с эталоном. Если результат совпал, все работает корректно. Если нет, ищем причину ошибки и устраняем ее путем изменения HDL-кода.

Где взять данные для сравнения? Обычно их предоставляют программисты, получая после запуска «битовой» модели. Но есть и другие варианты — например, написать модель вычислений прямо в тестовом файле на HDL-языке или использовать сторонние IP-ядра в качестве генератора эталонных данных. Суть от этого не меняется: эталон необходим, без него мы не поймем, работает наш блок или нет.

Интеграция IP в проект: работа с системной шиной и периферией

Интеграция разрабатываемого IP-ядра в систему

Итак, блок отлажен, занимает аппаратного ресурса не больше требуемого и работает на целевой тактовой частоте. Самое время проверить его на реальном железе!

Но перед этим мы сначала интегрируем блок в проект, у которого есть системный интерфейс для конфигурации регистрового пространства, а также имеется возможность подать входные данные и снять результат. Если нет реального проекта, мы используем минимальный рабочий с дополнительным тестовым окружением: памятью на входе блока, играющей роль входного генератора данных и внутрисхемного анализатора на выходе (ChipScope, ILA, SignalTAP). Для отладки также можно использовать виртуальные сигналы (Vivado — VIO ILA, Quartus — Virtual Jtag), управлять которыми можно напрямую из САПР.

Если в финальном проекте планируется использовать процессор для управления вычислениями, то рационально интегрировать все необходимые системные элементы и сразу подключить IP-ядро к системной шине. Это даст не только максимальную гибкость при отладке, но и позволит программистам начать работу над драйвером и управляющим приложением.

Часто для управления вычислениями в FPGA используется обычный ПК. В этом случае на этапе интеграции будут задействованы контроллеры высокоскоростных интерфейсов сопряжения FPGA с системной шиной, таких как PCIe. Для сопряжения нескольких ПЛИС может использоваться, например, стандарт LVDS (Low-Voltage Differential Signaling). При этом все эти контроллеры будут использовать встроенные высокоскоростные последовательные приемо-передатчики Transievers. FPGA-инженер обязан уметь настроить все указанные блоки (или знать, у кого спросить, как они настраиваются).

Другой вариант — использование SoC AMD (Xilinx) Zynq или Intel (Altera) Cyclone — FPGA. Кроме логики, у них «на борту» есть аппаратно-реализованные процессорные ядра (hard cores). Если в итоговом, «боевом» проекте будет использован встроенный процессор, то стоит сразу интегрировать в минимальный тестовый проект ядро процессора с реальными настройками (или близкими к реальным). Если предполагается, что на этом ядре будет запущен Petalinux или аналогичная операционная система, стоит сразу ее сконфигурировать и работать с ней. Например, при использовании Zynq процессорного ядра нужно экспортировать файл конфигурации в формат, который можно подгрузить в Petalinux. После этого выполнить компиляцию Petalinux и получить linux image, который содержит и конфигурационный файл FPGA, и информацию об адресном пространстве IP-ядер, подключенных к процессорной системе.

Отладка на железе: разбираемся, почему схема работает не как надо

Работа схемы при симуляции (слева) и «в железе» (справа)

Получив linux image или конфигурационный файл FPGA, мы переходим к работе с отладочной платой или другим специализированным железом, под которое ведется разработка. На этом этапе для начала стоит убедиться, что ваш модуль действительно отрабатывает как задумано. Обычно для этого используют внутрисхемные логические анализаторы, но также можно программно выгружать и анализировать результаты промежуточных вычислений.

На практике бывало, что «в железе» работа схемы отличалась от результатов верификации при одних и тех же входных данных. Так, некорректно описанный триггер или мультиплексор может синтезироваться в защелку (latch), использование которой нарушает STA-анализ. Из-за этого САПР перестает анализировать часть связей между элементами и не выводит их на требуемую тактовую частоту. Причем в этой ситуации Vivado не выдает ошибок и может даже не выдать критических предупреждений. Но обычные предупреждения о подобном поведении все-таки будут. Их анализ и расширенный анализ отчетов STA помогают отловить данную проблему.

Часто для выведения схемы на целевую тактовую частоту используют так называемые timing constraints — это дополнительные ограничения, позволяющие упростить выполнение STA-анализа в тех местах, где это возможно по логике работы схемы. Примером могут служить регистры, значения в которых используются схемой только через некоторое время после их загрузки по системной шине. Для облегчения STA-анализа, можно указать САПР не выводить на целевую тактовую частоту связи от данных регистров к схеме.

На этапе отладки важно отсматривать все пути, на которые накладываются timing constraints set_multicycle_path, set_max_delay и set_false_path. При неверно описанных ограничениях, схема может или некорректно работать, или не работать вообще. Иногда при установке внутрисхемного логического анализатора, ошибки в работе схемы перестают возникать. Это верный признак проблем с timing constraints (а иногда — с асинхронными элементами в схеме).

Сопряжение нескольких сложных IP-ядер тоже может привести к проблемам. Тест одного IP-ядра может занимать сутки, так что верификацию нескольких объединенных блоков проводят редко. Из-за этого один блок может, например, передавать данные в момент, когда другой блок занят. Или будет не совпадать формат передачи. Причин может быть множество, но результат один: схема не работает. Хорошая новость: детектировать такие ошибки легко с помощью внутрисхемного логического анализатора. Не жалейте места для внутрисхемного логического анализатора!

Отдельно хочу сказать о самом неочевидном типе ошибок — «плавающем». Такие ошибки не повторяются от запуска к запуску, а возникают один раз за долгое время работы. Бывало, что они были связаны со сбоями в работе оперативной памяти DDR и FLASH памяти. Иногда к сбою приводил перегрев ПЛИС или, наоборот, просадка напряжения питания. А бывало, даже находили некорректности в работе Vivado и получали подтверждение о существующей проблеме от техподдержки Xilinx. Но, несмотря на это, чаще всего ошибки возникали из-за проблем в архитектуре реализуемой схемы и некоторых неучтенных состояниях логики управления или передачи данных.

Для отлова любых ошибок советую задавать себе вопрос: «Как такая ситуация вообще могла произойти?». Дальше стройте предположения и проверяйте их корректность либо с помощью внутрисхемного логического анализатора, либо воссоздавая причины ошибок при симуляции схемы. Так вы сможете сравнительно быстро купировать проблему. Еще полезно разматывать «клубок» ошибок с конца: «Почему данные не сошлись? В предыдущем блоке проблем быть не может, а вот в блоке перед ним могла возникнуть ситуация, которая и вызвала проблему».

Отдельно хочется отметить, что на этапе отладки мы часто используем дополнительное контрольно-измерительное оборудование. Когда тестируют системы связи, специализированный генератор входного сигнала генерирует пакеты трафика, которые через специализированное ПО загружается в ПЛИС. Пройдя все стадии обработки, данные на выходе ПЛИС (макетного стенда) анализируются осциллографами или же векторными анализаторами, которые отражают мощность сигнала в большом диапазоне частот уже после его преобразования из «цифры» в «аналог». Запуск оборудования, трафика и снятие контрольных показаний в разных режимах работы может отнимать довольно много времени при тестировании вручную. Поэтому при использовании контрольно-измерительного оборудования мы по возможности стараемся автоматизировать тестирование, так как программный доступ к функциям оборудования позволяет выполнить те же задачи за минуты.

Кому подойдет FPGA-разработка и как проверить свои силы

FPGA-разработка не похожа на классическое программирование. В чем основные отличия:

  • HDL код представляет собой не последовательность инструкций, а описание цифровой схемы: арифметико-логических элементов и связей между ними. Примерно так же веб-разработчики описывают разметку страницы на HTML.
  • В FPGA-разработке больше вариантов реализации одного и того же алгоритма в виде схемы: процедурная, конвейерная, структурная и так далее.
  • Этапы верификации, отладки и тестирования в FPGA-разработке более трудоемкие и длительные.

В команде радиочастотного центра YADRO есть деление на программистов всех мастей, верификаторов, разработчиков, интеграторов, тестировщиков. Конечно, это не значит, что тут тот или иной специалист не занимается всем этим понемногу, но он точно может концентрировать свое внимание на главной задаче, а не распылять его на несколько высокоприоритетных. Тут всегда будет выигрыш, если не в качестве решения, то в качестве жизни из-за отсутствия стресса.

В команде радиочастотного центра YADRO есть деление на программистов всех мастей, верификаторов, разработчиков, интеграторов, тестировщиков. Конечно, это не значит, что тут тот или иной специалист не занимается всем этим понемногу, но он точно может концентрировать свое внимание на главной задаче, а не распылять его на несколько высокоприоритетных. Тут всегда будет выигрыш, если не в качестве решения, то в качестве жизни из-за отсутствия стресса.

В качестве итога позволю себе совет. Если вы всегда мечтали работать с холодным и жужжащим железом, смотреть на его немигающие или, наоборот, мигающие светодиоды и радоваться, когда понимаете, как избавиться от очередной «плавающей» ошибки, то FPGA-разработка вам понравится.

Для более полного погружения в тему рекомендую изучить статьи моих коллег:

— «ПЛИС для начинающих: что нужно знать FPGA-инженеру». Мы с вами посмотрели на процесс FPGA-разработки и распределение ролей, а в статье Виктории Ващенко подробно разбирается, чем разработка на ПЛИС отличается от привычного программирования, из чего состоит ПЛИС, выбор платформы, языки для проектирования на ПЛИС, модуль, принципы синхронного дизайна и проверка устройства.

— Типичные ошибки новичков в FPGA: от выбора платы до неинтуитивных кнопок. Автор этой статьи — Артём Аверченко, старший преподаватель ОмГТУ, который уже более 10 лет ведет связанные с FPGA дисциплины. В своем тексте он разобрал основные препятствия, с которыми сталкиваются начинающие плисоводы в своих первых проектах.

Наверх
Будь первым, кто оставит комментарий