Примеры оформления больших проектов fpga. Технология проектирования цифровых устройств на плис fpga

ПЛИС (Программируемая Логическая Интегральная Схема) — это интегральная схема, предназначенная для построения цифровых цепей из описания на специальном языке программирования. Другими словами, ПЛИС представляет собой чип, как бы содержащий в себе кучу элементов наподобие 74HCxx . Какие именно это будут логические элементы, какие между ними будут связи, и какие связи будет иметь получившаяся схема с внешним миром, определяется на этапе программирования ПЛИС.

Примечание: Насколько я смог выяснить, в русском языке на сегодняшний день термины ПЛИС и FPGA (Field-Programmable Gate Array, Программируемая Пользователем Вентильная Матрица), принято считать взаимозаменяемыми, что будет использовано далее по тексту. Однако стоит знать о существовании и альтернативной точки зрения, согласно которой FPGA (ППВМ) является одной из разновидностей ПЛИС (PLD, Programmable Logic Device).

Основные сведения об FPGA

Для программирования FPGA используются языки описания аппаратуры (HDL, Hardware Description Language). Среди них наибольшей популярностью пользуются Verilog (и его диалекты, в частности SystemVerilog), а также VHDL . Языки во многом похожи, но имеют разный синтаксис и различаются в некоторых деталях. Если Verilog — это такой C мира описания аппаратуры, то VHDL — соответственно, Pascal. Насколько мне известно, VHDL несколько менее популярен, в частности, из-за его многословности по сравнению с Verilog. Из преимуществ VHDL (или недостатков, кому как) можно назвать строгую статическую типизацию. Verilog же иногда допускает неявное приведение типов. Если продолжать аналогию с C и Pascal, языки различаются не настолько сильно, чтобы не выучить их оба.

На данный момент лидирующими производителями FPGA являются компании Altera (сейчас принадлежит Intel) и Xilinx. По информации из разных источников, вместе они контролируют не менее 80% рынка. Из других игроков стоит отметить Actel (куплена Microsemi), Lattice Semiconductor, Quicklogic и SiliconBlue. С железом от Xilinx можно работать только из среды разработки от Xilinx (называется Vivado), а среда разработки от Altra (называетя Quartus) понимает только железо от Altera. То есть, полный вендор лок, и выбирая конкретную FPGA для своего проекта, вы автоматически выбираете и инструменты разработки соответствующего производителя, их техническую поддержку, документацию, условия лицензирования софта, политику касаемо прекращения поддержки железа, и так далее.

FPGA часто используются в задачах, где некие вычисления хочется существенно ускорить, реализовав их прямо в железе. Например, FPGA нашли широкое применение в области обработки сигналов, скажем, в осциллографах, анализаторах спектра , логических анализаторах , генераторах сигналов, Software Defined Radio и даже некоторых мониторах . В частности, в LimeSDR используется Altera Cyclone IV, а в осциллографе Rigol DS1054Z стоит Xilinx Spartan-6, а также ProASIC 3 от компании Actel. Еще из применений, о которых я слышал, могу назвать компьютерное зрение, распознавание речи и биоинформатику. Есть и другие проекты, в частности по разработке веб-серверов и СУБД, работающих на FPGA . Но, насколько мне известно, это направление все еще остается сильно экспериментальным.

Xilinx или Altera?

Как говорится, лучший Linux тот, который использует ваш знакомый гуру по Linux.

Мой знакомый гуру по FPGA в лице Дмитрия Олексюка посоветовал начать с девборды Arty Artix-7 от компании Digilent. Используемой в ней FPGA является Artix-7 от Xilinx. Сам Digilent не производит доставку в Россию, но устройство доступно и на AliExpress , хотя и с заметной наценкой (официальная цена составляет 99$). Также его продают на eBay. Это довольно мощная плата, которая, тем не менее, стоит вполне адекватных денег.

Fun fact! Если вам просто хочется попрограммировать на Verilog или VHDL, строго говоря, покупать какую-либо плату с FPGA не требуется. Первое время можно ограничиться симулятором, работа с которым будет рассмотрена далее.

Из интересных особенностей платы можно назвать расположение гнезд совместимым с Arduino-шилдами способом. Также в комплекте с платой идет вкладыш, по которому можно получить лицензию на Vivado, открывающую все его возможности. Лицензия действует один год с момента активации, а также привязана к одному компьютеру по типу ОС и MAC-адресу.

По доставке. Я слышал, что устройства с FPGA на борту имеют большие шансы не пройти таможню. Магазин на AliExpress, ссылку на который я привел выше, доставляет платы в Россию через курьерскую службу СПСР . Для прохождения таможни потребовалось заполнить онлайн-форму с паспортными данными (только данные, без фото) и контактным телефоном, как этого требует текущее российское законодательство. После этого плата была доставлена курьером прямо до двери без каких-либо вопросов.

Установка Vivado

Среда разработки Vivado доступна для скачивания на сайте Xilinx . Будьте морально готовы к тому, что перед скачиванием вам придется пройти регистрацию и заполнить довольно подробную форму о себе. Скачиваем архив под названием «Vivado HLx 2017.2: All OS installer Single-File Download». Не перепутайте случайно с каким-нибудь «Vivado Lab Solutions», это совершенно не то, что нужно. Архив весит более 20 Гб, поэтому запасаемся терпением.

Распаковываем архив, запускаем инсталлятор. Ставим Vivado HL System Edition. Полная его версия займет на диске 47 Гб. Лично я снял галочку напротив Software Development Kit и оставил поддержку только 7 Series устройств, что уменьшило размер до 12 Гб. Забегая немного вперед отмечу, что такой конфигурации оказалось вполне достаточно.

Перед запуском Vivado нужно добавить в него поддержку Arty Artix-7, так как из коробки он ничего об этой плате не знает. Делается это как-то так:

cd ~/ opt/ xilinx/ Vivado/ 2017.2 / data/ boards/ board_files
wget https:// github.com/ Digilent/ vivado-boards/ archive/ master.zip
unzip master.zip
mv vivado-boards-master/ new/ board_files/* ./
rm -r vivado-boards-master
rm master.zip

Также скачиваем и сохраняем куда-нибудь файл Arty_Master.xdc. Он понадобится нам далее. Файл содержит описание находящихся на плате светодиодов, переключателей и так далее. Без него поморгать светодиодами на Verilog будет непросто.

Первый проект на SystemVerilog

В Vivado говорим File → New Project… В качестве типа проекта выбираем RTL Project, ставим галочку Do not specify sources at this time. В диалоге выбора типа платы находим в списке Arty.

Первым делом добавляем к проекту скачанный ранее XDC файл. Копируем его в каталог с проектом. Затем говорим File → Add Sources… → Add or create constraints → Add Files, находим копию файла, жмем Finish. В дереве файлов проекта (Sources) в группе Constraints появится файл Arty_Master.xdc, или как вы там назвали копию. Открываем его и раскомментируем все строчки в группах Clock signal, Switches и LEDs.

Далее говорим File → Add Sources… → Add or create design sources → Create File. В типе файла выбираем SystemVerilog, в имени файла вводим что-нибудь вроде hello. Говорим Finish. Далее появится диалог Define Module, который предложит накликать интерфейс модуля. Диалог довольно бесполезный, потому что то же самое удобнее сделать прямо в коде, так что жмем Cancel.

В дереве исходников находим новый файл hello.sv, он будет в группе Design Sources. Открываем и пишем следующий код:

`timescale 1ns / 1ps

module hello(
input logic CLK100MHZ,
input logic [ 3 : 0 ] sw,
output logic [ 3 : 0 ] led
) ;

always @ (posedge CLK100MHZ)
begin
if (sw[ 0 ] == 0 )
begin
led <= 4"b0001 ;
end
else
begin
led <= 4"b0000 ;
end
end

endmodule

Если все было сделано правильно, на этом этапе Vivado у вас будет выглядеть как-то так (кликабельно, PNG, 71 Кб):

Компиляция программы осуществляется в два этапа — синтез (synthesis) и имплементация (implementation). На этапе синтеза программа транслируется в абстрактную цепь из логических вентилей и прочих элементов. На этапе имплементации принимается решение о том, как прошить эту цепь в конкретную железку.

Запустим синтез, сказав Flow → Run Synthesis, или просто нажав F11. В правом верхнем углу вы увидите индикацию того, что процесс идет. Он может занимать довольно много времени, в зависимости от вашего компьютера и сложности программы. На моем ноутбуке синтез приведенной выше программы выполнился где-то секунд за 10. Если теперь сказать Flow → Open Synthesized Design, то можно увидеть красивую картинку вроде такой:

Настало время прошить нашу плату. Говорим Flow → Run Imlementation, затем Flow → Generate Bitstream. Подключаем плату к компьютеру по USB, в Vivado говорим Flow → Open Hardware Manager → Open target → Auto Connect → Program device. Потребуется указать путь к bit-файлу. У меня он был следующим:

./first-project.runs/impl_1/hello.bit

Говорим Program. Теперь на плате горит светодиод LD4, если переключатель SW0 опущен (см приведенную выше фотографию платы). Если же переключатель поднят, светодиод не горит. Простенько, конечно, но это же «hello, world», чего вы ожидали? :)

Симуляция

Симуляция — это виртуальное выполнение кода на Verilog или VHDL прямо на вашем компьютере, безо всяких там ПЛИС’ов. Это одновременно и отладочный инструмент, и своего рода фреймворк для покрытия кода тестами.

При знакомстве с симуляцией первое, что я обнаружил, было то, что она у меня не работает. В логах было просто:

ERROR: Failed to compile generated C file [...]xsim_1.c.

Google по этой ошибке находил только всякую ерунду в стиле «попробуйте отключить антивирус». В итоге решить проблему помогло добавление флага -v 2 в скрипт ~/opt/xilinx/Vivado/2017.2/bin/xelab. С его помощью я выяснил, что Clang, бинарник которого Vivado таскает за собой, падает со следующей ошибкой:

/a/long/path/to/clang: error while loading shared libraries:
libncurses.so.5: cannot open shared object file: No such file or
directory

А эта ошибка и ее решение уже описаны на Arch Wiki . Лично я просто скопировал уже существующий файл из каталога Vivado_HLS:

cp ~/opt/xilinx/Vivado_HLS/2017.2/lnx64/tools/gdb_v7_2/libncurses.so.5\
~/opt/xilinx/Vivado/2017.2/lib/lnx64.o/libncurses.so.5

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

По аналогии с тем, как ранее мы создавали hello.sv, создаем новый файл hello_sim.sv в группе Simulation Sources. В файле пишем следующий код:

`timescale 1ns / 1ps

module hello_sim() ;
logic clck_t;
logic [ 3 : 0 ] sw_t;
logic [ 3 : 0 ] led_t;

Hello hello_t(clck_t, sw_t, led_t) ;

initial begin
clck_t <= 0 ;
sw_t <= 4"b0000 ; # 1 ; clck_t <= 1 ; # 1 ; clck_t <= 0 ; # 1 ;
assert (led_t === 4"b0001 ) ;

Sw_t <= 4"b0001 ; # 1 ; clck_t <= 1 ; # 1 ; clck_t <= 0 ; # 1 ;
assert (led_t === 4"b0000 ) ;
end

endmodule

В дереве исходников делаем правый клик по файлу, выбираем Source Node Properties. В секции Used In снимаем галочки Synthesis и Implementation. Мы же не хотим, чтобы какие-то там тесты засоряли нашу далеко не резиновую FPGA?

Теперь говорим Flow → Run Simulation → Run Behavioral Simulation. В итоге вы увидите что-то примерно такого плана:

Можно видеть, что когда sw равен нулю, led равен единице, и наоборот. При этом все изменения происходят по фронту тактового сигнала. Похоже, что программа работает корректно. Ну и на ассертах ничего не свалилось, что как бы намекает.

Заключение

Архив с описанным выше проектом можно скачать . В качестве дополнительных источников информации я бы рекомендовал следующие:

  • Если вас интересуют подробности по железу, обратите внимание на

Пока были праздники, сделал небольшой проект на Verilog, который давно хотел попробовать.

Суть проекта в следующем: к FPGA подключено быстродействующее (относительно, конечно) АЦП с двумя каналами и параллельным интерфейсом (14-16 бит на канал). FPGA читает данные с АЦП и складывает в буфер (свою внутреннюю память BRAM). Когда буфер заполнен, чтение останавливается, и внешнее устройство (микроконтроллер) может считать данные из буфера по интерфейсу SPI. Также можно по SPI конфигурировать некоторые параметры (об этом будет написано в следующем посте).

Тест проекта (картинка кликабельна).

Результат синтеза для Cyclone IVE

Результат я синтезировал в Quartus II, для FPGA семейства Cyclone IVE (EP4CE6E22A7). Это одна из самых простых и недорогих FPGA в корпусе QFP144 на 6272 логических элемента. Микросхема имеет память объёмом 30K * 9 бит. Пользовательских пинов - 92.

микросхема EP4CE6E22A7
логических элементов - 301 (5%)
пинов - 41 (45%)
память - 65536 бит (24%)
частота для наихудшего случая (125 С) - 151 МГц.

Память 8 Кб, это собственно буфер, куда происходит запись данных. При двух каналах по 16 бит получается 32 бита на отсчёт, и 2048 отсчётов. Я решил, что этого вполне хватит, хотя буфер можно расширить хоть на весь объём.

Частота вполне устраивает, я рассчитывал, что будет частота тактирования 50 МГц, и АЦП на 25 МГц. То есть получается трёхкратный запас по частоте.

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

Есть более новое семейство Cyclone 10.

Результат синтеза для Cyclone 10

Выбираем чип 10CL006YE144C8G. Он имеет столько же логических элементов (6272), что и вариант на Cyclone 4, и столько же памяти (30К х 9). Корпус такой же, QFP144, пользовательских пинов даже меньше - 89.

микросхема 10CL006YE144C8G
логических элементов - 289 (5%)
пинов - 41 (46%)
память - 65536 бит (24%)
частота для наихудшего случая (85 С) - 145,5 МГц.

Любопытно то, что проект стал компактнее по логическим элементам. То есть при той же ёмкости логики в Cyclone 10 влезет более сложный проект. Всё остальное примерно на том же уровне.

Возникает резонный вопрос: можно ли сэкономить, поставив другую FPGA или CPLD?

Давайте попробуем FPGA MAX10.

Результат синтеза для MAX 10

Здесь читатель (если он в теме) может воскликнуть: нет, всё не так! Семейство MAX - это CPLD, а не FPGA, а путать эти понятия - вопиющий непрофессионализм!

Однако стараниями маркетологов Intel (все ведь в курсе, что речь про чипы Intel?) семейство MAX10 превратилось в FPGA, хотя и имеет внутреннюю энергонезависимую память конфигурации, как любая CPLD.

Итак, выбираем чип, например, 10M02SCE144A7G (2304 LE, 101 GPIO, 12Kx9 BRAM), корпус QFP144.

микросхема 10M02SCE144A7G.
логических элементов - 298 (13%)
пинов - 41 (41%)
память - 65536 бит (59%)
частота для наихудшего случая (125 С) - 153 МГц.

Мы видим, что абсолютные показатели остались практически теми же, увеличилась только степень заполнения кристалла, что и понятно - 2304LE против 6272 LE.

Можно ли использовать MAX II?

Теперь вопрос: а можно ли использовать какую-либо совсем дешёвую CPLD, типа MAX II? Здесь всё сложнее. У них нет памяти BRAM, т.е. нужна будет ещё и внешняя быстрая SRAM.

Для подключения SRAM нужна будет дополнительная логика, конечно. Если мы используем память объёмом 4K x 16, то нам будет нужно дополнительно 16 пинов для данных, 12 для адреса и 3 для управления (/cs, /we, /oe), всего 31 дополнительный пин.

Логика также увеличится в размерах. На сколько точно, сложно сказать, но в CPLD на 240 LE она не влезет изначально, а в 570 LE может быть, и влезет.

Выбираем CPLD EPM570 в корпусе QFP100. Нам нужно всего 72 пина, корпус имеет 76 пинов для GPIO, т.е. должно хватить на всё, но для расширения уже совсем мало места.

Плюсы такого решения: возможно, более низкая цена (даже с учётом дополнительной микросхемы SRAM), минусы: бОльшая сложность схемы и площадь платы.

Цена вопроса

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

EP4CE6E22C8N - 456,55 Р (Промэлектроника, Екб, розн.)
10CL006YE144C - 754,71 (Пятый элемент, Спб, опт)
10M02SCE144C8G - 456 Р (Элитан, Екб, опт)
EPM570F100C5N - 368 Р (Хайтек, Спб) + память (CY7C1021DV33-10ZSXI, SRAM 1MBIT 10NS 44TSOP) - 92,51 Р (Промэлектроника, Екб, розн.)

Конечно, можно найти и дешевле, это просто розничные цены в магазине, но соотношение будет примерно тем же.

Видно, что вариант с CPLD никак не выигрывает по цене, при этом имея множество недостатков. Остальные варианты примерно равноценны, разве что Cyclone 10 пока немного дороже и мало у кого есть в наличии. Однако это совсем новое семейство, пока что все дистрибьюторы его не привезли.

Лично мне больше всего нравится вариант на MAX 10. Он имеет одно преимущество: не нужно загружать конфигурацию FPGA при старте. В варианте на Cyclone 4 нужно будет загружать конфигурацию FPGA, что можно сделать либо с помощью дополнительной микросхемы конфигурационной памяти, либо с помощью микроконтроллера. Есть ещё третий вариант: прошить через JTAG и никогда не снимать питание с чипа. Я слышал, что кто-то так делал, не знаю, шутка это или нет, но я так делать точно не буду.

Впрочем, у варианта с прошивкой Cyclone 4 через микроконтроллер есть преимущество: возможность обновлять прошивку FPGA через пользовательские интерфейсы: USB, Ethernet, etc.

Возможен ещё один нетривиальный вариант: вообще не ставить микроконтроллер, а прошить в FPGA какой-либо встраиваемый процессор. Но это не очень хороший вариант, возможно, т.к. при этом однозначно понадобится внешнее ПЗУ и ОЗУ, а также, как минимум, мост USB. Заведомо отказываться от этого варианта не нужно, конечно, но он мне кажется более сложным в реализации, чем с микроконтроллером.

Про то, какие функции выполняет эта прошивка, я напишу в следующем посте.

ИСПОЛЬЗОВАНИЕ ПЛИС В СОВРЕМЕННЫХ УСТРОЙСТВАХ

Тупиков Павел Андреевич

студент 5 курса, кафедра АРТ ОмГТУ, РФ, г. Омск

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

· Улучшаются временные характеристики изделия.

· Уменьшается цена изделия.

· Уменьшаются габариты изделия.

· Увеличивается надежность изделия (уменьшается количество дискретных микросхем)

· Повышается гибкость изделия (ПЛИС всегда можно перепрограммировать)

Архитектура ПЛИС имеет сложную структуру (Рис. 1)

Рисунок 1. Внутренняя структура ПЛИС

Как видно из рисунка 1 основная часть ПЛИС состоит из программируемых логических блоков и программируемых внутренних связей .

Сам процесс программирования (прошивки) ПЛИС состоит в формировании нужных связей между входами и выходами устройства.

На сегодняшний день в мире есть два мировых лидера в производстве ПЛИС. Это американские фирмы Xilinx и Altera.

Каждая фирма предлагает свой САПР для работы с ПЛИС. Фирма Xilinx предлагает Xilinx Software Development Kit (SDK). Фирма Altera предлагает Max+Plus II и Quartus II, а так же систему моделирования ModelSim.

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

· Verilog HDL.

Язык VHDL является наиболее сложным для обучения, но при этом обладает наибольшими возможностями на функциональных и поведенческих уровнях абстракции, однако имеет меньшие возможности на структурном уровне абстракции по сравнению с Verilog HDL, для расширения возможностей языка VHDL была разработана библиотека VITAL (Рис. 2) .


Рисунок 2. Уровни абстракции Verilog и VHDL

Примером работы языка Verilog HDL является программа, реализованная на ПЛИС CYCLONE III EP3C5E1444C8N стенда Mini-DiLab общий вид которого представлен на рис. 3.


Рисунок 3. Общий вид платы Mini - DiLab

Данная программа реализует последовательное переключение светодиодов led0-led7, с выбором набавления движения «огонька» при помощи кнопок pba и pbb, а так же управлением скоростью переключения при помощи переключателей sw0, sw1.

//Текст программы

module proect(output led, input clk_25mhz, input pba, input pbb,

input sw);

// Назначение внутренних соединений проекта

wire s1;

wire s2;

wire s3;

// Вызов других файлов (подпрограмм), подключаемых к проекту

Tr tr_1 (.out(s2), .set(pba), .res(pbb));

Counter counter_1 (.q(s1), .clk(clk_25mhz), .up(s2));

Mx mx_1 (.a(s3), .in(s1), .load(sw));

Dc3_8 dc3_8_1 (.out(led), .in(s3));

endmodule // конец программы

Подпрограмма tr

module tr (out, set, res); // Создание программы

// Назначение входов/выводов

output reg out;

input set;

input res;

// Инициализация

initial

begin

Out <= 1"d0;

// Основной код программы

always @(negedge set or negedge res)

begin

if (~(set))

Out <= 1"d1;

else

Out <= 1"d0;

endmodule // Конец программы

Подпрограмма counter

module counter (con, q, clk,up); // Начало программы

output reg con;

output q = con;

input up, clk;

// Основной код программы

always @(posedge clk)

begin

if (clk)

if (up)

Con <= con - 1"d1;

else

Con <= con + 1"d1;

endmodule //Конец программы

Подпрограмма mx(мультиплексор)

module mx (output reg a, input in, input load);

// Основной код программы

always @*

begin

case (load)

2"b00: a = in;

2"b01: a = in;

2"b10: a = in;

2"b11: a = in;

endcase

endmodule // Конец программы

Подпрограмма dc3_8 (мультиплексор)

module dc3_8 (out, in); // Начало программы

// Назначение входов/выходов

output reg out;

input wire in;

// Основной код программы

always @*

begin

case (in)

3"d0: out = 8"b11111110;

3"d1: out = 8"b11111101;

3"d2: out = 8"b11111011;

3"d3: out = 8"b11110111;

3"d4: out = 8"b11101111;

3"d5: out = 8"b11011111;

3"d6: out = 8"b10111111;

3"d7: out = 8"b01111111;

endcase

endmodule // Конец программы

Программа была реализована в САПР Quartus II.

После компиляции программы компилятор не выдал ошибки и замечания в программе, связанные с анализом и синтаксисом программы (рис. 4).


Рисунок 4. Окно сообщений проекта

Замечание, сделанные компилятором, говорят об отсутствии лицензии на Quartus II(была использована бесплатная версия программы, для обучения) и отсутствия файлов, необходимых для моделирования проекта.

RTL Структура данного проекта представлена на рис. 5.


Рисунок 5. Реализация проекта ( RTL структура)

Как показано на рис. 6 в данной программе испозльзуется лишь незначительная часть возможностей данной ПЛИС.

Рисунок 6. Часть ПЛИС, участвующая в работе проекта

Выводы: Программируемые логические интегральными схемы являются могут находить применение во многих устройствах. Для обучения работы с ними следует вводить в образовательную программу специальностей, связанных с проектированием и конструированием радиоэлектронной аппаратуры знакомство с языками описания аппаратуры(Verilog HDL и VHDL).

Список литературы:

1.Грушевицкий Р.И. Проектирование систем на микросхемах программной логики/ Р.И. Грушевицкий, A.X. Мурсаев, Е.П. Угрюмое. СПб.: БХВ Петербург, 2002. - 608 с.

2.Коломов Д.А. Системы автоматизированного проектирования фирмы Altra MAX+plus II и Quartus II. Краткое описание и самоучитель/ Д.А. Коломов, Р.А. Мяльк, А.А. Зобенко, А.С. Филиппов. М.: ИП РадиоСофт, 2002. - 126 с.

3.Максфилд К. Проектирование на ПЛИС. Курс молодого бойца./ К. Максфилд. М.: Издательский дом «Додэка-XXI», 2007. - 408 с. (перевод с английского).

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

Для начала необходимо немного разбираться в цифровой логике работы микросхем ASIC, но начинать с них очень сложно и дорого, и вместо этого лучше начать с FPGA.

Что такое FPGA?

FPGA расшифровывается как field-programmable gate array (программируемые пользователем вентильные матрицы, ППВМ). В более общем случае они называются ПЛИС - программируемые логические интегральные схемы.

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

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

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

Важная особенность FPGA - возможность перенастройки. Допустим сейчас нам нужен контроллер 100G Ethernet, а через неделю эта же плата может использоваться для реализации независимых четырех интерфейсов 25G Ethernet.

На рынке работают два лидера в производителя FPGA-чипов: всеми известный Intel и Xilinx. Они контролируют 58 и 42% рынка. Первый свой чип FPGA основатели Xilinx изобрели в далеком 1985 году. Intel пришла на рынок совсем недавно - в 2015 году, поглотив компанию Altera, которая была основана в то же время, что и Xilinx. Технологии Altera и Xilinx во многом схожи, как и среды разработки. Чаще я работал с продуктами компании Xilinx, поэтому не удивляйтесь ее постоянному упоминанию в статье.

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

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

Принцип работы FPGA

Микросхема FPGA - это та же заказная микросхема ASIC, состоящая из таких же транзисторов, из которых собираются триггеры, регистры, мультиплексоры и другие логические элементы для обычных схем. Изменить порядок соединения этих транзисторов, конечно, нельзя. Но архитектурно микросхема построена таким хитрым образом, что можно изменять коммутацию сигналов между более крупными блоками: их называют CLB - программируемые логические блоки.

Также можно изменять логическую функцию, которую выполняет CLB. Достигается это за счет того, что вся микросхема пронизана ячейками конфигурационной памяти Static RAM. Каждый бит этой памяти либо управляет каким-то ключом коммутации сигналов, либо является частью таблицы истинности логической функции, которую реализует CLB.

Так как конфигурационная память построена по технологии Static RAM, то, во-первых, при включении питания FPGA микросхему обязательно надо сконфигурировать, а во-вторых, микросхему можно реконфигурировать практически бесконечное количество раз.

Очень упрощенная 2D-структура микросхемы без конфигурационной памяти

Блоки CLB находятся в коммутационной матрице, которая задает соединения входов и выходов блоков CLB.

Схема коммутационной матрицы

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

CLB

CLB очень упрощенно состоит из блока, задающего булеву функцию от нескольких аргументов (она называется таблицей соответствия - Look Up Table, LUT) и триггера (flip-flop, FF). В современных FPGA LUT имеет шесть входов, но на рисунке для простоты показаны три. Выход LUT подается на выход CLB либо асинхронно (напрямую), либо синхронно (через триггер FF, работающий на системной тактовой частоте).

Принцип реализации LUT

Интересно посмотреть на принцип реализации LUT. Пусть у нас есть некоторая булева функция y = (a & b) | ~ c . Ее схемотехническое представление и таблица истинности показаны на рисунке. У функции три аргумента, поэтому она принимает 2^3 = 8 значений. Каждое из них соответствует своей комбинации входных сигналов. Эти значения вычисляются программой для разработки прошивки ПЛИС и записываются в специальные ячейки конфигурационной памяти.

Значение каждой из ячеек подается на свой вход выходного мультиплексора LUT, а входные аргументы булевой функции используются для выбора того или иного значения функции. CLB - важнейший аппаратный ресурс FPGA. Количество CLB в современных кристаллах FPGA может быть разным и зависит от типа и емкости кристалла. У Xilinx есть кристаллы с количеством CLB в пределах примерно от четырех тысяч до трех миллионов.

Помимо CLB, внутри FPGA есть еще ряд важных аппаратных ресурсов. Например, аппаратные блоки умножения с накоплением или блоки DSP. Каждый из них может делать операции умножения и сложения 18-битных чисел каждый такт. В топовых кристаллах количество блоков DSP может превышать 6000.

Другой ресурс - это блоки внутренней памяти (Block RAM, BRAM). Каждый блок может хранить 2 Кбайт. Полная емкость такой памяти в зависимости от кристалла может достигать от 20 Кбайт до 20 Мбайт. Как и CLB, BRAM и DSP-блоки связаны коммутационной матрицей и пронизывают весь кристалл. Связывая блоки CLB, DSP и BRAM, можно получать весьма эффективные схемы обработки данных.

Преимущества FPGA

Первый чип FPGA, созданный Xilinx в 1985 году, содержал всего 64 CLB. В то время интеграция транзисторов на микросхемах была намного ниже, чем сейчас, и в цифровых устройствах часто использовались микросхемы «рассыпной логики». Были отдельно микросхемы регистров, счетчиков, мультиплексоров, умножителей. Под конкретное устройство создавалась своя печатная плата, на которой устанавливались эти микросхемы низкой интеграции.

Использование FPGA позволило отказаться от такого подхода. Даже FPGA на 64 CLB значительно экономит место на печатной плате, а доступность реконфигурации добавила возможность обновлять функциональность устройств уже после изготовления во время эксплуатации, как говорят «in the field» (отсюда и название - field-programmable gate array).

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

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

Для разработки ASIC выпускают специальные платы , содержащие много FPGA, соединенных между собой. Прототип микросхемы работает на значительно меньших частотах (может быть, десятки мегагерц), но позволяет сэкономить на выявлении проблем и багов.

Однако, на мой взгляд, существуют более интересные применения ПЛИС. Гибкая структура FPGA позволяет реализовывать аппаратные схемы для высокоскоростной и параллельной обработки данных с возможностью изменить алгоритм.


Сравнение аппаратных платформ

Давайте подумаем, чем принципиально отличаются CPU, GPU, FPGA и ASIC. CPU универсален, на нем можно запустить любой алгоритм, он наиболее гибок, и использовать его легче всего благодаря огромному количеству языков программирования и сред разработки.

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

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

Справа от CPU находится GPU. Изначально эти микросхемы были разработаны для обработки графики, но сейчас используются и для майнинга вычислений общего назначения. Они состоят из тысяч небольших вычислительных ядер и выполняют параллельные операции над массивом данных.

Если алгоритм можно распараллелить, то на GPU получится добиться значительного ускорения по сравнению с CPU. С другой стороны, последовательные алгоритмы будут реализовываться хуже, поэтому платформа оказывается менее гибкой, чем CPU. Также для разработки под GPU надо иметь специальные навыки, знать OpenCL или CUDA.

Наконец, FPGA. Эта платформа сочетает эффективность ASIC с возможностью менять программу. ПЛИС не универсальны, но существует класс алгоритмов и задач, которые на них будут показывать лучшую производительность, чем на CPU и даже GPU. Сложность разработки под FPGA выше, однако новые средства разработки делают этот разрыв меньше.

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

Использование FPGA позволяет решать эту задачу мгновенно: байты пакета еще только начали поступать в микросхему из сетевого интерфейса, а его заголовок уже анализируется. Использование процессоров тут может существенно замедлить скорость обработки сетевого трафика. Ясно, что для маршрутизаторов можно сделать заказную микросхему ASIC, которая будет работать наиболее эффективно, но что, если правила обработки пакетов должны меняться? Достичь требуемой гибкости в сочетании с высокой производительностью поможет только FPGA.

Таким образом, FPGA используются там, где нужна высокая производительность обработки данных, наименьшее время реакции, а также низкое энергопотребление.

FPGA in the cloud

В облачных вычислениях FPGA применяются для быстрого счета, ускорения сетевого трафика и осуществления доступа к массивам данных. Сюда же можно отнести использование FPGA для высокочастотной торговли на биржах. В серверы вставляются платы FPGA с PCI Express и оптическим сетевым интерфейсом производства Intel (Altera) или Xilinx .

На FPGA отлично ложатся криптографические алгоритмы, сравнение последовательностей ДНК и научные задачи вроде молекулярной динамики. В Microsoft давно используют FPGA для ускорения поискового сервиса Bing, а также для организации Software Defined Networking внутри облака Azure.

Бум машинного обучения тоже не обошел стороной FPGA. Компании Xilinx и Intel предлагают средства на основе FPGA для работы с глубокими нейросетями. Они позволяют получать прошивки FPGA, которые реализуют ту или иную сеть напрямую из фреймворков вроде Caffe и TensorFlow.

Причем это все можно попробовать, не выходя из дома и используя облачные сервисы. Например, в Amazon можно арендовать виртуальную машину с доступом к плате FPGA и любым средствам разработки, в том числе и machine learning .

FPGA on the edge

Что еще интересное делают на FPGA? Да чего только не делают! Робототехника, беспилотные автомобили, дроны, научные приборы, медицинская техника, пользовательские мобильные устройства, умные камеры видеонаблюдения и так далее.

Традиционно FPGA применялись для цифровой обработки одномерных сигналов (и конкурировали с процессорами DSP) в устройствах радиолокации, приемопередатчиках радиосигналов. С ростом интеграции микросхем и увеличением производительности платформы FPGA стали все больше применяться для высокопроизводительных вычислений, например для обработки двумерных сигналов «на краю облака» (edge computing).

Эту концепцию легче всего понять на примере видеокамеры для анализа автомобильного трафика с функцией распознавания номеров машин. Можно взять камеру с возможностью передачи видео через Ethernet и обрабатывать поток на удаленном сервере. С ростом числа камер будет расти и нагрузка на сеть, что может привести к сбоям системы.

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

Что до робототехники и дронов, то в этой сфере как раз особенно важно выполнять два условия - высокая производительность и низкое энергопотребление. Платформа FPGA подходит как нельзя лучше и может использоваться, в частности, для создания полетных контроллеров для беспилотников . Уже сейчас делают БПЛА, которые могут принимать решения на лету.

Разработка проекта на FPGA

Существуют разные уровни проектирования: низкий, блочный и высокий. Низкий уровень предполагает использование языков типа Verilog или VHDL, на которых вы управляете разработкой на уровне регистровых передач (RTL - register transfer level). В этом случае вы формируете регистры, как в процессоре, и определяете логические функции, изменяющие данные между ними.

Схемы FPGA всегда работают на определенных тактовых частотах (обычно 100–300 МГц), и на уровне RTL вы определяете поведение схемы с точностью до такта системной частоты. Эта кропотливая работа приводит к созданию максимально эффективных схем с точки зрения производительности, потребления ресурсов кристалла FPGA и энергопотребления. Но тут требуются серьезные скиллы в схемотехнике, да и с ними процесс небыстрый.

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

На высоком уровне проектирования вы уже не будете контролировать данные на каждом такте, вместо этого сконцентрируешься на алгоритме. Существуют компиляторы или трансляторы с языков C и C++ на уровень RTL, например Vivado HLS. Он довольно умный и позволяет транслировать на аппаратный уровень широкий класс алгоритмов.

Главное преимущество такого подхода перед языками RTL - ускорение разработки и особенно тестирования алгоритма: код на C++ можно запустить и верифицировать на компьютере, и это будет намного быстрее, чем тестировать изменения алгоритма на уровне RTL. За удобство, конечно, придется заплатить - схема может получиться не такой быстрой и займет больше аппаратных ресурсов.

Часто мы готовы платить эту цену: если грамотно использовать транслятор, то эффективность не сильно пострадает, а ресурсов в современных FPGA достаточно. В нашем мире с критичным показателем time to market это оказывается оправданным.

Часто в одном дизайне нужно совместить все три стиля разработки. Допустим, нам нужно сделать устройство, которое мы могли бы встроить в робота и наделить его способностью распознавать объекты в видеопотоке - например, дорожные знаки. Возьмем микросхему видеосенсора и подключим ее напрямую к FPGA. Для отладки можем использовать монитор HDMI, тоже подключенный к FPGA.

Кадры с камеры будут передаваться в FPGA по интерфейсу, который заведомо определен производителем сенсора (USB тут не катит), обрабатываться и выводиться на монитор. Для обработки кадров понадобится фреймбуфер, который обычно находится во внешней памяти DDR, установленной на печатной плате рядом с микросхемой FPGA.


Типичная блок-схема проекта FPGA

Если производитель видеосенсора не предоставляет Interface IP для нашей микросхемы FPGA, то нам придется писать его самостоятельно на языке RTL, считая такты, биты и байты в соответствии со спецификацией протокола передачи данных. Блоки Preprocess, DDR Controller и HDMI IP мы, скорее всего, возьмем готовые и просто соединим их интерфейсы. А блок HLS, который выполняет поиск и обработку поступающих данных, мы можем написать на C++ и транслировать при помощи Vivado HLS.

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

Рассмотрим путь проектирования от написания кода RTL до получения конфигурационного файла для загрузки в FPGA.

Путь проектирования

Итак, вы пишете код RTL, который реализует нужную вам схему. Прежде чем его проверять на реальном железе, надо убедиться, что он верный и корректно решает требуемую задачу. Для этого используется RTL-моделирование в симуляторе на компьютере.

Вы берете свою схему, представленную пока только в коде RTL, и помещаете ее на виртуальный стенд, где подаете последовательности цифровых сигналов на входы схемы, регистрируете выходные диаграммы, зависимости от времени выходных сигналов и сравниваете с ожидаемыми результатами. Обычно вы находите ошибки и возвращаетесь к написанию RTL.

Далее логически верифицированный код подается на вход программе-синтезатору. Она преобразует текстовое описание схемы в связанный список цифровых элементов из библиотеки, доступной для данного кристалла FPGA. В этом списке будут отображены такие элементы, как LUT, триггеры, и связи между ними. На этой стадии элементы пока никак не привязаны к конкретным аппаратным ресурсам. Чтобы это сделать, требуется наложить на схему ограничения (Constraints) - в частности, указать, с какими физическими контактами ввода-вывода микросхемы FPGA связаны логические входы и выходы вашей схемы.

В этих ограничениях также требуется указать, на каких тактовых частотах должна работать схема. Выход синтезатора и файл ограничений отдаются процессору Implementation, который, помимо прочего, занимается размещением и трассировкой (Place and Route).

Процесс Place каждый пока еще обезличенный элемент из netlist привязывает к конкретному элементу внутри микросхемы FPGA. Далее начинает работу процесс Route, который пытается найти оптимальное соединение этих элементов для соответствующей конфигурации коммутационной матрицы ПЛИС.

Place и Route действуют, исходя из ограничений, наложенных нами на схему: контактами ввода-вывода и тактовой частотой. Период тактовой частоты очень сильно влияет на Implementation: он не должен быть меньше, чем временная задержка на логических элементах в критической цепи между двумя последовательными триггерами.

Часто сразу удовлетворить это требование не удается, и тогда надо вернуться на начальный этап и изменить код RTL: например, попытаться сократить логику в критической цепи. После успешного завершения Implementation нам известно, какие элементы где находятся и как они связаны.

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

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