Главная » Хабрахабр » [Из песочницы] Начинаем FPGA на Python

[Из песочницы] Начинаем FPGA на Python

Технология FPGA (ПЛИС) в настоящее время обретает большую популярность. Растёт количество сфер применения: помимо обработки цифровых сигналов, FPGA используются для ускорения машинного обучения, в blockchain технологиях, обработке видео и в IoT.

Это осложняет вхождение новичка в FPGA и для работодателя найти специалиста с этими специфичными знаниями на рынке труда трудно. Данная технология имеет один существенный минус: для программирования используются довольно старые и специфичные языки описания цифровой аппаратуры Verilog и VHDL. Тем более людей знающих Python на порядок больше специалистов владеющих Verilog/VHDL. С другой стороны популярный высокоуровневый язык программирования Python с фреймворком MyHDL делают программирование FPGA простым и приятным. 6 (здесь и далее все операции производятся в ОС Ubuntu 18. Серией статей я хочу показать как легко и просто войти в область FPGA зная Python и начать делать настоящие сложные FPGA проекты на этом языке.
Во первых нам понадобится сам python версии 3. 04).

Устанавливаем myhdl:

pip3 install myhdl

В качестве «Hello World!» Напишем простую программу, которая заставляет загораться светодиоды от нажатия на кнопку. В мире микропроцессоров «Hello World!» это программа, которая мигает одним светодиодом, в мире FPGA Hello World — это мигание тысячи светодиодов. На плате есть только четыре светодиода, так что мигать будем только ими в зависимости от нажатия кнопки. Важно отметить, что весь код в FPGA в отличие от микроконтроллеров выполняется одновременно, все диоды зажигаются и гаснут одновременно. А не последовательно в случае микроконтроллеров. В роли подопытного используется плата WaveShare OpenEPM1270 с плис Altera Max II EPM1270T144C5 на борту.

Создаём новый python файл:

from myhdl import *
from random import randrange
def led_blinker(input1, led1, led2, led3, led4): @always_comb def on_off_led(): if input1 == 1: led1.next = 1 led2.next = 1 led3.next = 0 led4.next = 0 else: led1.next = 0 led2.next = 0 led3.next = 1 led4.next = 1 return on_off_led

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

sudo apt-get install gtkwave

Далее в файле с прошивкой следует описать тестовое окружение. Это тоже питоновская функция:

def test(): input1, led1, led2, led3, led4 = [Signal(bool(0)) for i in range(5)] test = led_blinker(input1, led1, led2, led3, led4) @always(delay(10)) def gen(): input1.next = randrange(2)
return test, gen

Здесь тестовое окружение генерирует случайную последовательность из нулей и единиц (используется питоновский модуль random).

def simulate(timesteps): tb = traceSignals(test) sim = Simulation(tb) sim.run(timesteps)

И инициализируем симулятор, протаскивая туда функцию окружения test_inverter. Таким образом получается матрёшка inverter → test_inverter → simulate(время в условных единицах).

После запуска скрипта в рабочей папке создаться .vcd файл и его следует пропустить через gtkwave, в терминале: gtkwave test_invereter.vcd.

В итоге сгенерировалась случайная последовательность входных сигналов input1, и то как обработала эти сигналы функция led_blinker.

Я привык работать с микросхемами фирмы Intel (ранее Altera), данная последовательность действий аналогична и для микросхем других производителей с соответствующими САПР. После того как мы убедились, что логика отработал ровно так как мы хотели, далее следует эту функцию закинуть в FPGA. Компиляторы умеют работать только с кодом в VHDL/Verilog, поэтому питоновский код следует транслировать в любой из этих языков (не принципиально в какой). На микросхему ПЛИС заливается бинарный файл, который создаёт компилятор производителя микросхемы, для Intel это Quartus, для Xilinx Vivado.

def convert(): input1, led1, led2, led3, led4 = [Signal(bool(0)) for i in range(5)] toVerilog(led_blinker, input1, led1, led2, led3, led4)
convert()

В этом примере код транслируется в Verilog. Результат в файле led_blinker.v, его и надо будет дать Quartus для генерации прошивки FPGA.

Качаем базовую версию размер 9 GB. Скачать Quartus можно с сайта fpgasoftware.intel.com, нужна бесплатная версия Lite, её нам будет достаточно.

После установки необходимо задать некоторые параметры в системе, чтобы можно было пользоваться устройством для зашивки программы ПЛИС — программатором: Установка Quartus не должна вызвать сложностей для обычного пользователя Linux.

Для этого создаем новый файл /etc/udev/rules.d/51-altera-usb-blaster.rules со следующим с содержанием: 1. Создаем udev правило.


# USB-Blaster
SUBSYSTEM=="usb", ATTR=="09fb", ATTR{idProduct}=="6001", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6002", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6003", MODE="0666"
# USB-Blaster II
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6010", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="09fb", ATTR{idProduct}=="6810", MODE="0666"

Перезагружаем udev, используя udevadm:

sudo udevadm control --reload

2. Разрешаем non-root доступ к устройству USB-Blaster. Для этого создаем файл /etc/udev/rules.d/altera-usb-blaster.rules со строкой:

ATTR{idVendor}=="09fb", ATTR{idProduct}=="6001", MODE="666"

Это даёт rw-rw-rw- доступ к программатору.

Quartus использует для работы демона jtagd, который связывет софт с устройством программатора. 3. Конфигурируем jtagd. Копируем описание из вашей директории с Quartus:

sudo mkdir /etc/jtagd
sudo cp <Quartus install path>/quartus/linux64/pgm_parts.txt /etc/jtagd/jtagd.pgm_parts

Запускаем Quartus и создаём новый проект «File» — «New project wizard», набираем имя проекта.

И в меню Add Files подключаем сгенерированный verilog файл с расширением .v. Далее нажимаем Next. Проект создан. Таким образом, если verilog файл будет редактироваться из python файла то он автоматически будет подхватываться Quartus, Далее попадаем в меню выбора девайса, в нашем случае это MAX II EMP1270T144C5 и ещё пару раз next.

В Project Navigator заходим в меню файлов и правой кнопкой мыши задаем наш verilog файл «Set as top-level entity».

Теперь в меню «Assignments-Pin Planner» конфигурируем пины на микросхеме: Компилируем проект.

Теперь всё готово к программированию: Tools-Programmer. Ещё раз компилируем. Подключаем программатор и питание к плате, в Hardware Setup выбираем свой USB-Blaster, задаём галочки как изображено на рисунке и Start.

Можно посмотреть результат на плате: После того как Programmer отрапортовал Successful.

Заключение

В этом уроке рассмотрено как создавать рабочее окружение и первый простой проект на ПЛИС на языке программирования Python.

Рассмотрено:

  • как устанавливать:
    • myHDL;
    • GTKWave;
    • Quartus;
  • Произведена настройка программатора USB Blaster в Ubuntu;
  • Разработан проект на ПЛИС на python;
  • Произведено тестирование и верификация проекта;
  • Скомпилирован проект под ПЛИС;
  • Загружен проект на ПЛИС.

Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Android-приложение в памяти. Доклад об оптимизации для Яндекс.Лончера

В облегченной системе Android Go действуют повышенные требования к предустановленным приложениям — размеру и используемой памяти. Перед нами встала задача в эти требования уложиться. Мы провели ряд оптимизаций и решили серьезно поменять архитектуру нашей графической оболочки — Яндекс.Лончера. Руководитель группы ...

[Перевод] Использование JavaScript-консоли в браузерах

Сегодня мы публикуем заметку, посвящённую особенностям использования JavaScript-консоли в браузерах, лежащим за пределами широко известной команды console.log(). Собственно говоря, эта команда представляет собой простейший инструмент для отладки программ, который позволяет выводить что-либо в консоль. Однако знание некоторых особенностей этого инструмента ...