Автоматизируйте разработку FPGA с помощью Jenkins, Vivado и GitHub на Linux VPS
* Эта статья содержит ссылку на рекламу UpCloud VPS
Непрерывная доставка и непрерывная интеграция — это гибкие методологии разработки программного обеспечения, которые сокращают время цикла между изменением кода и его развертыванием. Используя автоматизацию для проверки изменений кода и создания файлов релизов, команды могут стать более продуктивными и эффективными.
Компании-разработчики программного обеспечения уже давно практикуют непрерывную разработку, но вы с таким же успехом можете использовать эти методы для своих проектов FPGA. В этом руководстве вы узнаете, как настроить сервер автоматизации на виртуальном частном сервере (VPS) с использованием Jenkins, Xilinx Vivado и системы управления исходным кодом (SCM) Git/GitHub.
Что такое Дженкинс?
Сервер автоматизации Jenkins — это бесплатная программа с открытым исходным кодом, написанная на Java. Он работает на Windows или Linux. В этой статье мы будем использовать Linux, поскольку это наиболее распространенная платформа для автономных серверов.
Jenkins работает как процесс-демон в Linux или как служба в Windows. Встроенный веб-сервер, который Jenkins запускает при запуске, обеспечивает пользовательский интерфейс. Большинство пользователей будут взаимодействовать с Jenkins с помощью веб-интерфейса. Вы можете добавлять новые проекты автоматизации и управлять существующими через веб-интерфейс.
На изображении выше показана главная страница сервера Jenkins, который мы настроим сегодня. По умолчанию только вошедшие в систему пользователи могут получить доступ к Jenkins, но для этой статьи я включил публичный доступ к частям моего *демо-сервера.
* Обновление:я отключил демонстрационный сервер 13 мая 2020 г.
На главной странице вы видите список вакансий. Эти задания могут содержать любые задачи, и их можно запускать вручную из веб-интерфейса. Или они могут запускаться автоматически с помощью сценариев, веб-перехватчиков или в результате выполнения других заданий. Отсюда и термин сервер автоматизации. .
В нашем примере каждое задание соответствует модулю VHDL, хранящемуся в отдельном репозитории GitHub. Мы заставим Дженкинса запускать симуляцию и собирать проект каждый раз, когда разработчик отправляет код в один из отслеживаемых репозиториев Git. Если тестовый стенд завершится неудачей или сборка прервется, Дженкинс пометит задание как неудавшееся в веб-интерфейсе и автоматически отправит электронное письмо тому, кто записал ошибочный код.
Пример проекта
Серверы автоматизации наиболее полезны для команд, работающих над более крупными проектами. Поэтому я создал пример проекта FPGA, состоящий из восьми репозиториев Git. Проект представляет собой 7-сегментный счетчик из курса Fast-Track, портированный на Xilinx ZedBoard.
Ссылки на восемь репозиториев на GitHub:
- пакеты (пакеты VHDL)
- bcd_encoder (Модуль)
- счетчик (Модуль)
- digit_selector (Модуль)
- output_mux (Модуль)
- сбросить (Модуль)
- seg7_encoder (Модуль)
- сегмент7 (Верхний модуль)
Каждый репозиторий содержит модуль VHDL и его тестовый стенд. Исключением являются пакеты. репо, которое содержит только три пакета VHDL, определяющие константы и типы. Кроме того, seg7 верхний модуль содержит файл ограничений, который определяет тактовую частоту и назначения контактов физической реализации.
Большинство крупномасштабных проектов VHDL используют модули из более чем одного репозитория. Компании обычно имеют библиотеку пакетов и модулей, которые они повторно используют во многих проектах. Именно это я имитирую, разбивая эту довольно простую конструкцию на такое же количество модулей.
В нашем примере все модули зависят от репозитория пакетов, а верхний модуль также зависит от всех подмодулей. Я решил эту проблему, импортировав их по мере необходимости, используя стандартные подмодули Git. На графике выше показано содержимое и зависимости всех репозиториев этого проекта.
Репозитории Git также содержат несколько файлов, не связанных с проектированием, таких как конфигурация Jenkins и сценарии сборки. Мы поговорим о них в следующих разделах этой статьи.
Виртуальный частный сервер (VPS)
Хотя Jenkins может работать на любом компьютере с Windows или Linux, для всех практических целей вам желательно запускать его на выделенном сервере. Сервер автоматизации должен быть постоянно включен и доступен всем членам вашей команды. Если у вас есть физический сервер достаточной емкости, это здорово. Но для большинства из нас более быстрым и дешевым решением является использование виртуального частного сервера (VPS).
VPS — это виртуальный компьютер, который вы арендуете у хостинговой компании через Интернет. Он выглядит как настоящий компьютер под управлением Windows или Linux, с которым вы можете взаимодействовать и устанавливать любое программное обеспечение, какое захотите. Мы собираемся использовать компьютер с Linux, потому что это наиболее целесообразно для нашего варианта использования.
Сайт VHDLwhiz работает на VPS, как и последние два года. Я уже столкнулся с проблемой поиска самого быстрого и лучшего провайдера VPS — UpCloud. Естественно, мы собираемся использовать UpCloud для настройки VPS для нашего сервера автоматизации.
Получите бонус UpCloud в размере 25 долларов США
Если вы хотите попробовать UpCloud, у меня есть реферальный код, который предоставит вам кредит на сумму 25 долларов США. при регистрации.
>> Нажмите здесь, чтобы получить бонус UpCloud в размере 25 долларов <<
Или используйте мой промокод при оформлении заказа:NV78V6
Используя код, вы одновременно получите бонус и поддержите VHDLwhiz. Я могу получить некоторые средства на свой счет UpCloud за каждого клиента, который его использует.
Ладно, хватит разговоров о продажах. Приступим к настройке сервера.
Развертывание UpCloud VPS
После того, как вы вошли в свою новую учетную запись UpCloud, вы можете начать процесс создания нового экземпляра VPS, перейдя в Серверы → Развернуть сервер. .
UpCloud имеет множество дата-центров по всему миру. Выберите ближайшее к вам место для размещения нового сервера. Затем вам нужно выбрать план, сколько ресурсов предоставить вашей виртуальной машине. Дженкинс не использует много ресурсов, но Xilinx Vivado — настоящий пожиратель оперативной памяти. Поэтому вам следует выбрать как минимум план с 4 ГБ ОЗУ, как показано на изображении ниже.
Я рекомендую взглянуть на страницу рекомендаций Xilinx по памяти, поскольку использование памяти тесно связано со сложностью целевой FPGA. На странице указано, что пиковое использование памяти для FPGA Zynq-7000 XC7Z045, которое я использую, составляет 1,9 ГБ. Я обнаружил, что плана в 2 ГБ слишком мало для трассировки проекта. В Vivado произошел сбой, и в dmesg появилось следующее сообщение:журнал:
[807816.678940] Недостаточно памяти:завершен процесс 22605 (vivado) total-vm:2046684КБ, anon-rss:782916КБ, file-rss:308КБ, shmem-rss:0КБ
Обратите внимание, что вы всегда можете легко обновить ресурсы ОЗУ и ЦП вашего сервера из своей учетной записи UpCloud. Вы не получите автоматически дополнительное пространство на жестком диске, которое поставляется с более дорогими пакетами, без перераспределения файловой системы VPS, но оно будет работать. Для справки:я начал с плана с 50 ГБ хранилища и использовал 61% этого объема после завершения всего сервера автоматизации. Только Vivado занимает 24 ГБ места.
Я рекомендую вам выбрать в качестве операционной системы последний дистрибутив CentOS Linux, как показано на изображении ниже. Xilinx Vivado официально поддерживает только Red Hat Linux, который не является бесплатным. Но CentOS – это бесплатный, поддерживаемый сообществом дистрибутив Linux, который очень похож на Red Hat.
Кроме того, есть несколько параметров сети, которые вы можете оставить по умолчанию. На веб-странице также есть раздел, где вы можете загрузить свои SSH-ключи для входа в систему без пароля. Вы всегда можете настроить эти параметры позже, используя обычный метод Linux для загрузки ключей SSH.
Наконец, вам нужно указать имя хоста и имя сервера, как показано на изображении ниже. Имя хоста — это общедоступный домен, который пользователи вводят в браузер для доступа к серверу Jenkins. Если у вас нет готового домена или поддомена, вы всегда можете получить доступ к серверу, используя его IP-адрес. Когда вы будете довольны настройками, нажмите кнопку Развернуть. кнопка для создания сервера.
После создания сервера автоматически сгенерированный пароль будет отображаться в виде уведомления. Вы можете изменить это позже, используя passwd Linux. команда. Если вы предоставили ключ SSH до развертывания сервера, пароль вам вообще не понадобится. Если вы когда-нибудь потеряете доступ к своему серверу, вы всегда можете войти в систему из своей учетной записи UpCloud, нажав Открыть консольное соединение , как показано на изображении ниже.
Настройки DNS-зоны
Новому серверу будут назначены постоянные адреса IPv4 и IPv6, которые можно найти в вашей учетной записи UpCloud в разделе Серверы->Сеть. . Вы можете получить доступ к серверу, подключившись по SSH к корневой учетной записи общедоступного IPv4-адреса.
Используя пример IP-адреса с изображения ниже, подходящей командой для ввода на домашнем компьютере Linux будет:
Если вы делаете это просто в качестве эксперимента, можно использовать только IP-адрес. Но более практичное решение — назначить серверу постоянное доменное имя. Для этого вам необходимо приобрести домен у одного из множества регистраторов, доступных в Интернете.
Поскольку у меня уже есть домен vhdlwhiz.com, я решил создать субдомен для сервера Jenkins с именем jenkins.vhdlwhiz.com . Мы правильно настроили доменное имя на сервере UpCloud при его развертывании. Следующее, что нам нужно сделать, это указать поддомену общедоступный IPv4-адрес.
На изображении ниже показаны настройки, которые я ввожу в файл зоны DNS моего регистратора доменных имен. Если бы я хотел, чтобы сервер находился в верхнем домене (vhdlwhiz.com), я бы оставил поле имени хоста пустым. Но я хочу, чтобы он находился в поддомене «jenkins» vhdlwhiz.com. Поэтому я ввожу имя поддомена.
После изменения настроек DNS пройдет некоторое время, прежде чем вы сможете использовать доменное имя для доступа к своему веб-сайту. Обычно это занимает не более 20 минут, но в крайних случаях распространение изменений во все уголки Интернета может занять до 48 часов.
Когда изменения вступили в силу, вы сможете использовать доменное имя вместо IP-адреса при входе на сервер по SSH:
ssh root@yoursub.yourdomain.com
Установка Дженкинса
Первое, что вам следует сделать после входа в учетную запись root на новом сервере Linux, — это обновить все установленные пакеты. В CentOS Linux ням является менеджером пакетов по умолчанию. Мы собираемся использовать ням команда для установки большей части программного обеспечения.
Введите следующую команду, чтобы обновить все установленные пакеты до последних версий:
Теперь, когда мы знаем, что наша система обновлена, мы можем продолжить установку. Но прежде чем выдать ням команду для установки Jenkins, мы собираемся установить Java версии 11 явно. Это избавит нас от некоторых проблем позже, когда мы установим Xilinx Vivado.
В настоящее время на нашем сервере нет интерпретатора Java, и если мы скажем ням для установки Jenkins будет установлена Java версии 8. Это хорошо работает для Jenkins, но позже создаст проблемы для нас, поскольку Vivado зависит от Java версии 11.
Установите Java 11 с помощью этой команды перед установкой Jenkins:
yum -y install java-11-openjdk-devel
Jenkins недоступен в репозитории программного обеспечения по умолчанию, поставляемом с CentOS. К счастью, мы можем импортировать репозиторий Jenkins из Red Hat, используя следующие команды:
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat/jenkins.repo rpm --import https://pkg.jenkins.io/redhat/jenkins.io.key
Наконец, мы можем продолжить и установить Jenkins:
Сервер Jenkins запустится автоматически после следующей загрузки, но вы можете запустить сервер без перезагрузки следующим образом:
Вы всегда можете проверить состояние сервера Jenkins, используя systemctl команда:
Он распечатает статус сервера вместе со всеми сообщениями об ошибках:
Дженкинс из-за небезопасного HTTP
На данный момент Jenkins работает на порту 8080 на VPS, но у вас нет возможности подключиться к нему через веб-браузер. Это связано с тем, что брандмауэр CentOS по умолчанию блокирует порт 8080 и порт 80 (HTTP). Что мы можем сделать, чтобы это исправить, так это открыть порт 80 в брандмауэре и перенаправить его на порт 8080 с помощью iptables. .
Но прежде чем сделать это, вам нужно решить, хотите ли вы защитить свой сайт с помощью HTTPS. Проблема с использованием только HTTP и порта 80 заключается в том, что ваш сайт будет небезопасным. Если вы получаете доступ к нему через общедоступный Wi-Fi, злоумышленник, подключенный к тому же Wi-Fi, что и ноутбук и легкодоступное программное обеспечение для взлома, может подслушать ваше соединение и украсть ваши учетные данные для входа в Jenkins.
Если вы хотите избежать риска безопасности, связанного с незашифрованным HTTP, перейдите к следующему разделу, посвященному настройке HTTPS для Jenkins. В противном случае продолжайте читать.
Включить небезопасный HTTP-доступ к Jenkins так же просто, как ввести следующие команды:
firewall-cmd --permanent --zone=public --add-port=80/tcp firewall-cmd --reload iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
Затем вы можете ввести свое доменное имя в своем любимом браузере и просмотреть страницу Jenkins Начало работы. страница должна появиться. По крайней мере, в Google Chrome в адресной строке будет отображаться предупреждение «Небезопасно», как показано на изображении ниже.
Перейдите к Настройке Jenkins. раздел, если вас это устраивает.
Дженкинс через безопасный HTTPS
Наличие незащищенного веб-сайта, доступного для общественности, представляет собой огромный риск для безопасности. Дженкинс может получить доступ к вашему исходному коду, как и любой хакер, успешно взломавший сервер. К счастью, обеспечить безопасность веб-сайта можно всего лишь с помощью нескольких скопированных команд.
Дженкинс не может обрабатывать HTTPS самостоятельно. Поэтому нам необходимо установить универсальный веб-сервер для перенаправления запросов, поступающих по защищенному каналу, на незащищенный сервер Jenkins. Я буду использовать Nginx, один из самых популярных сегодня бесплатных веб-серверов с открытым исходным кодом.
Введите следующую команду, чтобы установить и запустить Nginx:
yum -y install nginx systemctl start nginx
Затем нам нужно открыть порты HTTP и HTTPS в брандмауэре. Мы будем обслуживать только запросы HTTPS, но нам также необходимо держать порт HTTP открытым, поскольку мы настроим Nginx для перенаправления всех небезопасных запросов на безопасный порт.
Эти команды откроют брандмауэр для веб-трафика:
firewall-cmd --permanent --zone=public --add-port=80/tcp firewall-cmd --permanent --zone=public --add-port=443/tcp firewall-cmd --reload
Следующим шагом является установка сертификата, который веб-браузеры смогут использовать для подтверждения того, что они взаимодействуют с вашим веб-сайтом, а не с мошенником. Мы собираемся использовать бесплатный центр сертификации Let’s Encrypt для защиты нашего сайта. Отдельные шаги сложны, но, к счастью, certbot предоставляет сценарий, который может сделать это автоматически.
Загрузите и подготовьте скрипт с помощью следующих команд:
apt update apt install snapd snap install core; snap refresh core snap install --classic certbot
Далее запустите скрипт, который установит сертификат и внесет необходимые изменения в файл конфигурации Nginx:
По мере выполнения скрипта он будет запрашивать у вас информацию. Отвечайте утвердительно (Да, Принимаю) на все вопросы, пока вас не попросят выбрать, перенаправлять HTTP-трафик на HTTPS или нет. В листинге ниже показаны вопросы и предложенный мной ответ (2). Разрешение Nginx перенаправлять небезопасные запросы гарантирует, что никто не сможет явно ввести http://. вашсайт.com и доберёмся до небезопасной версии Дженкинса. Nginx перенаправит их на безопасную версию.
... Deploying Certificate to VirtualHost /etc/nginx/nginx.conf Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Наконец, вам следует включить задание cron для периодического обновления сертификата. В противном случае срок его действия истечет, и браузеры вообще откажутся открывать ваш сайт.
Введите следующую однострочную команду, чтобы добавить ежедневное задание cron:
echo "0 0 * * * /snap/bin/certbot renew --quiet" | crontab -
Демон cron будет запускать сценарий обновления ежедневно в полночь. Вы можете просмотреть задания cron с помощью crontab -l команду и отредактируйте их с помощью crontab -e команда. Если вы посетите свой веб-сайт сейчас, вы увидите тестовую страницу Nginx, а не Jenkins. Мы исправим это в ближайшее время, но убедитесь, что предупреждение «Небезопасно» исчезло из адресной строки Chrome, как показано на изображении ниже.
Чтобы Nginx обслуживал Jenkins, вам необходимо внести некоторые изменения в файл /etc/nginx/nginx.conf. файл. Благодарность за этот фрагмент кода принадлежит блогу Керрена на Medium. Использование редактора nano, вероятно, является самым простым способом редактирования файла конфигурации:
nano /etc/nginx/nginx.conf
Найдите блок сервера, в котором указано ваше доменное имя, и добавьте выделенные строки из списка ниже в файл nginx.conf. Обратите внимание, что первая из трех новых строк идет над блоком сервера, а остальные — в блоке корневого местоположения.
После обновления файла конфигурации вам необходимо перезагрузить Nginx, чтобы изменения вступили в силу. При желании вы можете протестировать файл конфигурации перед перезагрузкой с помощью команды:
Nginx выдаст сообщение «ОК» или сообщит вам, в какой строке nginx.conf файл, ошибка. Если вас устраивают изменения, вы можете перезагрузить веб-сервер, введя следующую команду:
Когда вы теперь посетите сайт Jenkins в своем браузере, вы должны увидеть страницу «Начало работы» Jenkins, как показано на изображении ниже. На этот раз оно обслуживается через безопасное соединение, и мы можем безопасно продолжить настройку Jenkins из веб-интерфейса.
Настройка Дженкинса
При первом посещении веб-сайта Jenkins вам будет предложено ввести пароль, найденный в файле в файловой системе Linux. Войдя в систему через SSH, используйте команду ниже, чтобы показать пароль. Скопируйте и вставьте его в браузер, чтобы получить доступ к веб-интерфейсу:
cat /var/lib/jenkins/secrets/initialAdminPassword
На следующем экране Дженкинс спросит, хотите ли вы установить предложенные плагины или хотите указать, какие из них следует установить. Просто выберите Установить предлагаемые плагины. вариант на данный момент. Вы всегда сможете добавить или удалить плагины позже.
На следующей странице вы должны создать пользователя-администратора. Заполните свои данные и создайте надежный пароль для использования с вашей новой учетной записью. По умолчанию только авторизованные пользователи могут получить доступ к серверу Jenkins. Анонимные пользователи увидят диалоговое окно входа только в том случае, если зайдут на ваш сайт. Единственная причина, по которой вы можете получить доступ к моему *демо-сайту jenkins.vhdlwhiz.com в том, что я внес изменения на сервер. Я использовал плагин Matrix Authorization Strategy, чтобы предоставить анонимный доступ к некоторым представлениям.
* Обновление:я закрыл демонстрационный сайт 13 мая 2020 г.
Когда Дженкинс завершит установку плагинов, вы увидите сообщение «Дженкинс готов!» сообщение, как показано на изображении выше. Нажмите кнопку, которая приведет вас на пустую страницу обзора вашей новой установки Jenkins.
Установка плагинов Jenkins
Первое, что вам нужно сделать, это установить кучу плагинов. Jenkins имеет встроенный менеджер плагинов, который вы можете использовать для установки, обновления и удаления расширений. Вы найдете плагины, которые могут удовлетворить большинство ваших потребностей. Просто используйте функцию поиска в менеджере плагинов, когда вам нужно добавить функциональность Jenkins.
Перейдем к установке плагинов, которые я использовал при настройке примера сервера Jenkins. На боковой панели выберите Управление Jenkins->Управление плагинами->Доступные. . Обратите внимание, что плагины не отображаются, если вы не введете что-либо в поле поиска. После ввода они появятся.
Голубой океан
Первый плагин, который я рекомендую установить, называется Blue Ocean. Этот плагин представляет собой модернизацию рабочего процесса Jenkins, а также пользовательского интерфейса. Он также включает в себя множество других полезных плагинов, поэтому вам не придется устанавливать их по отдельности. Найдите «голубой океан» в менеджере плагинов и выберите его для установки, как показано на изображении ниже.
На странице хода установки, которая появляется после нажатия кнопки «Установить», вы можете выбрать Перезапустить Jenkins, когда установка завершена и задания не выполняются . Если вы установите флажок рядом с ним, Jenkins перезагрузится после завершения установки плагина. Другой способ перезапустить Jenkins — войти на сервер через SSH и выполнить следующую команду:
systemctl restart jenkins
Если не считать длинного списка других плагинов, установленных Blue Ocean, на первый взгляд заметных изменений нет. Но на боковой панели появится новый пункт меню, как показано на изображении ниже. При нажатии вы попадете в графический интерфейс Blue Ocean, который сильно отличается от обычного интерфейса Jenkins. Попробуйте!
Зеленые шарики
Следующий плагин, который я всегда устанавливаю, предназначен исключительно для эстетики. Плагин Green Balls не требует никакой настройки. Просто найдите «зеленый шарик» в менеджере плагинов и установите его, как показано на изображении ниже.
По умолчанию Jenkins использует синие цветные шарики на странице обзора, чтобы указать, что статус задания успешен. Причина как-то связана с тем, что изобретатель Дженкинса — японец. Интересно, что в Японии синий цвет взаимозаменяем с зеленым, когда речь идет о статусе «ОК». Подробнее об этом в этой статье, где автор объясняет причину из первых рук.
Пользователи из большинства других частей мира, вероятно, предпочли бы зеленые шарики статуса. Это легко исправить с помощью плагина Green Balls, как показано на изображении ниже.
Плагин локали
Следующий плагин, который я установил, называется Locale. Найдите «локаль» в разделе Доступно. вкладка в менеджере плагинов. Установите плагин, как показано на изображении ниже.
Плагин позволяет заставить Дженкинса использовать один и тот же язык в графическом интерфейсе для всех пользователей. По умолчанию Jenkins переводит пользовательский интерфейс на язык, который использует ваш веб-браузер. Я норвежец, но я бы предпочел, чтобы Дженкинс говорил по-английски. Перевод был немного неадекватным. Кроме того, гораздо проще поискать в Google ответы на английском языке, если вам нужно узнать, как что-то сделать в Jenkins.
Конечно, выбор за вами, нужен ли вам этот плагин. Если вы его установили, вам нужно перейти в раздел Управление Jenkins->Настройка системы. и найдите раздел с именем Locale. . Затем вам нужно ввести «en_US» (или любой другой язык, который вы хотите) и установить флажок ниже, чтобы установить этот язык для всех пользователей, как показано на изображении ниже. Не забудьте прокрутить страницу вниз и нажать Сохранить. .
Последний плагин, который вам понадобится для клонирования моей установки, — это плагин Sidebar Link. Он позволяет добавлять пользовательские ссылки на боковую панель Jenkins. Мы воспользуемся им позже, чтобы добавить ссылку на релизы FPGA (битовые файлы). Найдите «сайдбар» в менеджере плагинов и установите плагин, как показано на изображении ниже.
Подключение Jenkins к GitHub
Независимо от того, является ли ваш репозиторий общедоступным или частным, вам необходимо предоставить Дженкинсу некоторые разрешения для вашей учетной записи GitHub. По крайней мере, если вы хотите сделать это максимально простым способом, вам следует позволить плагину Jenkins GitHub управлять интерфейсом GitHub за вас. Blue Ocean уже установил плагин GitHub. Вот шаги по его настройке.
Сначала вам следует установить Git в вашей системе. Плагин GitHub в нем не нуждается, но когда вы начнете работать с заданиями Jenkins, он вам понадобится. Введите эту команду, чтобы установить Git в CentOS Linux:
Токен личного доступа в GitHub
Войдите в GitHub, щелкните изображение своего профиля в правом верхнем углу, выберите настройки и перейдите в Настройки разработчика. . Затем выберите Токены личного доступа. в меню левой боковой панели или нажмите эту ссылку, которая приведет вас прямо туда.
Здесь вам нужно нажать Создать новый токен , как показано на изображении ниже. GitHub еще раз запросит у вас пароль. Сейчас вы, по сути, создаете новый пароль для конкретного приложения. Это лучше, чем сообщать свой действительный пароль, поскольку вы можете отозвать его и ограничить разрешения, предоставленные токену. Именно это мы и сделаем на открывшейся странице.
После ввода пароля вам необходимо дать токену имя. Имя специально для вас. Это может быть что угодно, например «Дженкинс». Затем вам необходимо включить хотя бы admin:org_hook. , admin:repo_hook и репозиторий разрешения, как показано на изображении ниже. Все остальные поля можно оставить снятыми.
Наконец, когда вы нажмете Создать токен , появится код доступа. Вам необходимо скопировать его, прежде чем покинуть эту страницу, потому что увидеть его снова невозможно. Если вы его забудете, удалите токен и создайте его заново.
Ввод учетных данных GitHub в Jenkins
Скопировав токен, перейдите в Jenkins, выберите Управление Jenkins->Настроить систему и найдите раздел с именем GitHub , как показано на изображении ниже. В раскрывающемся меню выберите «Добавить GitHub Server->GitHub Server». .
В появившемся новом разделе «Сервер GitHub» установите флажок Управление перехватчиками. . Когда вы это сделаете, Дженкинс установит веб-перехватчики на GitHub для репозиториев, которые вы отслеживаете. Позже мы увидим, что это особенно полезно, поскольку мы будем использовать их для запуска моделирования или сборки в Jenkins, когда пользователь отправляет код в соответствующий репозиторий GitHub.
Выберите Учетные данные (Добавить)->Jenkins. после того, как вы установите флажок, как показано на рисунке ниже.
В открывшемся окне измените Вид. раскрывающийся список Секретный текст . Затем вставьте токен личного доступа, который вы ранее сгенерировали в GitHub, в поле Secret. поле. Напишите «GitHub» в поле идентификатора и нажмите Добавить. .
Наконец, когда вы вернетесь в главное меню конфигурации, после добавления секретного текста выберите новый GitHub. ключ из Учетные данные меню. Затем нажмите Проверить соединение. чтобы убедиться, что Дженкинс может общаться с GitHub, используя токен доступа. Если все прошло хорошо, вы должны увидеть сообщение, подобное показанному на изображении ниже.
Обязательно прокрутите страницу до конца и нажмите Сохранить прежде чем покинуть страницу конфигурации.
Если у вас возникнут проблемы и вам придется добавить несколько учетных данных, вы можете удалить их, перейдя в раздел «Управление Jenkins->Управление пользователями». и щелкните свое имя пользователя. Теперь на левой боковой панели появится пункт меню с названием Учетные данные. . Отсюда вы можете просматривать и редактировать все ключи, сохраненные Дженкинсом.
Отправка электронной почты от Дженкинса
Мы собираемся настроить Jenkins для автоматической отправки электронных писем, когда что-то ломается в вашем коде. Чтобы это произошло, нам нужно внести некоторые изменения в Управление Jenkins->Настройка системы. меню.
Первое, что вам нужно сделать, это ввести адрес отправителя, который Дженкинс будет использовать при отправке автоматических писем. Найдите адрес электронной почты системного администратора. поле на странице конфигурации и введите адрес, с которого Дженкинс должен отправлять сообщения.
Небольшое примечание:лучше всего вводить адрес, который заканчивается именем домена Jenkins. Это сводит к минимуму вероятность попадания письма в папку «Спам». Сервер Jenkins не имеет разрешения на отправку электронных писем от имени других доменов, но большинство почтовых служб принимают адреса отправителя с того же домена, что и отправляющий сервер. Подробнее об этом читайте в этой статье в Википедии. На изображении ниже я ввел адрес отправителя, заканчивающийся тем же доменом, что и сервер Jenkins.
Далее нам нужно предоставить Дженкинсу возможность отправлять электронные письма. Самый простой способ сделать это — установить SMTP (почтовый) сервер на VPS. Вы можете сделать это, войдя в систему и выполнив следующие команды:
yum -y install sendmail systemctl enable sendmail systemctl restart sendmail
После установки sendmail , вернитесь к конфигурации системы Jenkins и введите «localhost» на SMTP-сервере. поле, как показано на изображении ниже.
На этом этапе вы также можете установить флажок, чтобы разрешить отправку незарегистрированным пользователям. Это означает, что пользователи не имеют учетной записи пользователя Jenkins. Позже мы настроим Jenkins на отправку электронного письма любому человеку, который отправит ошибочный код на GitHub. Дженкинс получит адрес электронной почты преступника от GitHub, но это будет работать только в том случае, если у этого человека есть соответствующая учетная запись Jenkins или если мы установим этот флажок.
Наконец, вы можете протестировать конфигурацию, как показано на изображении выше. После нажатия Проверить конфигурацию , должно появиться сообщение «Электронное письмо было успешно отправлено», и письмо должно попасть в ваш почтовый ящик. Проверьте папку со спамом, если не получите письмо в течение пяти минут.
Установка Xilinx Vivado в пакетном режиме
Я использую Xilinx Vivado для моделирования, компиляции и реализации кода в этом примере проекта. Целевым устройством является FPGA Xilinx Zynq-7000 на плате разработки ZebBoard. В этом разделе я покажу вам, как установить Vivado на VPS, используя бесплатную лицензию WebPACK.
Первым шагом является загрузка унифицированного установщика Xilinx:самораспаковывающийся веб-установщик Linux, показанный на изображении ниже. Вам нужно будет войти в систему или создать новую учетную запись Xilinx, чтобы загрузить установщик.
Когда загрузка завершится, вы должны скопировать ее со своего настольного компьютера на сервер Jenkins. Если у вас есть доступ к оболочке Linux на рабочем столе, я предлагаю использовать безопасное копирование файлов, как показано в следующей команде:
Прежде чем вы сможете запустить установщик, вам необходимо установить несколько пакетов, удовлетворяющих зависимостям Vivado. Для этого выполните следующие команды:
yum -y install tar yum -y install java-11-openjdk-devel yum -y install ncurses-compat-libs yum -y install gcc
Затем запустите установщик Xilinx Unified следующим образом:
./Xilinx_Unified_2019.2_1106_2127_Lin64.bin --keep --noexec --target Xil_installer
Файл .bin распакует установочные файлы в новый каталог с именем Xil_installer. . Если вместо этого вы получите ошибку, указанную ниже, это значит, что вы не установили tar .
Verifying archive integrity... All good. Uncompressing Xilinx InstallerExtraction failed. Terminated
Унифицированный установщик Xilinx может установить в вашу систему множество различных инструментов Xilinx. Поэтому нам необходимо запустить xsetup файл в Xil_installer каталог, чтобы указать, какое программное обеспечение нас интересует:
cd Xil_installer/ ./xsetup -b ConfigGen
xsetup сценарий подскажет вам, какие инструменты вы хотели бы иметь. Введите «2» для Vivado , а затем «1» для Vivado HL WebPACK , как показано в листинге ниже.
Select a Product from the list: 1. Vitis 2. Vivado 3. On-Premises Install for Cloud Deployments 4. BootGen 5. Lab Edition 6. Hardware Server 7. Documentation Navigator (Standalone) Please choose: 2 Select an Edition from the list: 1. Vivado HL WebPACK 2. Vivado HL Design Edition 3. Vivado HL System Edition Please choose: 1
Чтобы установить версию Xilinx WebPACK, вы должны войти в свою учетную запись Xilinx во время установки. На настольном компьютере графический интерфейс установщика проведет вас через этот процесс, но на сервере графический интерфейс отсутствует, поэтому нам приходится проходить аутентификацию с помощью xsetup сценарий. Выполните следующую команду, чтобы сгенерировать токен аутентификации:
Мне пришлось запустить команду несколько раз, прежде чем она сработала. Сначала скрипт остановился с ошибкой «Подключение к Интернету подтверждено, возможно подключение к Интернету». Однако после нескольких попыток мне удалось войти в систему. Скрипт запросит ваш идентификатор пользователя и пароль. Это адрес электронной почты и пароль, которые вы использовали для загрузки установщика с xilinx.com.
Наконец, вы готовы установить Vivado в пакетном режиме. При вызове сценария установки необходимо указать файл конфигурации установки, чтобы xsetup знает, какие инструменты загрузить. Файл конфигурации находится в .Xilinx. папка в домашнем каталоге пользователя root. Выполните следующую команду, чтобы начать установку с использованием файла конфигурации:
./xsetup -a XilinxEULA,3rdPartyEULA,WebTalkTerms \ -b Install -c ~/.Xilinx/install_config.txt
Процесс установки займет много времени. Установка Vivado использует 24 ГБ места. Все это теперь загружается с относительно медленного сервера Xilinx. У меня загрузка заняла чуть больше двух часов.
После завершения установки вам следует проверить, что Vivado успешно запускается в пакетном режиме. Xilinx предоставляет сценарий оболочки, который настраивает для вас среду. Before you can run Vivado, you need to use the source command to load the content of the script into your active shell:
source /tools/Xilinx/Vivado/2019.2/settings64.sh
Then, you are ready to run Vivado. But there’s no GUI environment installed on your server, so we have to start it in batch mode by using this command:
If Vivado starts and exists immediately without printing any errors, it’s an indication that Vivado has everything it needs, and you are ready to go. Note that if you are getting the error listed below, it’s because you haven’t installed the ncurses-compat-libs package, as we talked about at the start of this section.
application-specific initialization failed: couldn't load file "librdi_commontasks.so": libtinfo.so.5: cannot open shared object file: No such file or directory
Integrating Vivado in Jenkins
To prepare Jenkins for Vivado, we need to make some changes to the general settings. Head to Manage Jenkins->Configure System and check that all the default settings make sense for you.
As I mentioned earlier, Vivado uses a lot of RAM. The resource usage depends on your target FPGA, and you can get an indication of how much you need from the Xilinx Memory Recommendations page. Therefore, I recommend that you change the default number of parallel jobs that can run from 2 to 1. Unless you allocated vast RAM resources on your VPS, you probably want to set # of executors to 1, as shown in the image below.
Instead of defining the environment variables in every Jenkins job, we will specify the PATH globally for all jobs. That makes it easier for you to swap to a newer version of Vivado in the future. Then you can refer to the ‘vivado’ executable in your scripts, and it will always point to the latest version, or whichever you decide.
Scroll to the Global properties section and check Environment variables . Click Add to get a new entry. Make sure to include the standard Linux PATH также. I used “PATH=/tools/Xilinx/Vivado/2019.2/bin:/sbin:/usr/sbin:/bin:/usr/bin”, as shown in the image below.
Don’t forget to scroll to the bottom of the page and click Save .
Vivado GUI projects in batch mode
I chose to manage the Vivado projects in GUI mode. For each repository, I created a new project from within the regular Vivado GUI, adding source files, setting libraries, and all of that. However, the .xpr project files are binary and depend on a lot of other temporary files in the project directory.
Binary files are not suitable for SCMs like Git. Fortunately, Xilinx has thought of this and written a guideline (XAPP1165) for how to use Vivado with version control systems. What we do is to use the write_project_tcl command in Vivado to export the entire project into a Tcl script. The script contains human-readable Tcl code suitable for Git.
I’ve organized all of the Git repos so that all files that belong to the Vivado projects are in a subfolder named “vivado”, while the VHDL source files are in the parent directory. Check out the demo packages project on my GitHub to see what I mean. For each repo, we will put the Vivado Tcl scripts in the vivado folder. You will also find the create_vivado_proj.tcl file, which is the human-readable version of the Vivado project.
To create the create_vivado_proj.tcl file, start by setting up the Vivado project as you wish in the Vivado GUI. Make sure that the Vivado project resides within a vivado subfolder. When you’re happy with the project, export it by entering the following commands in the Vivado Tcl console:
cd [get_property DIRECTORY [current_project]] write_project_tcl -force -target_proj_dir . create_vivado_proj
Add the create_vivado_proj.tcl file to Git, and set up the gitignore to ignore the rest of the Vivado project. Here’s the content of my .gitignore file which ignores everything but Tcl scripts in the vivado folder:
Opening the Vivado project in batch mode
It’s a good idea to test the Vivado project manually on the VPS before you start creating Jenkins jobs. By default, the daemon runs from a user account named jenkins on the Linux server. Therefore, you should test the Vivado project using the jenkins user.
Make sure that you have Git installed on the Linux server before you start this experiment. Run this command to install Git after logging in as root:
You can’t log in to the jenkins user directly, but you can change to it from the root user like this:
If you now run a pwd command, you will see that you are at /var/lib/jenkins :
[jenkins@jenkins ~]$ pwd /var/lib/jenkins
That’s because this isn’t a regular user account that has the home directory under /home , as is the norm on Linux systems. It’s only for running the Jenkins daemon, but we can log in to perform a manual walkthrough of the build process in the Jenkins environment.
The home folder is full of all the dynamic data like logs, user settings, and plugins that you have downloaded. When we later start running jobs in the Jenkins GUI, they will appear in the jobs folder.
Let’s go to the jobs folder to perform our experiment:
cd /var/lib/jenkins/jobs/
You can clone your Git repository directly into the jobs folder. Your Git repo has to be accessible without using a password. Either because it’s public, or because you have set up passwordless login as described on the GitHub help pages.
If you don’t have a Git repository with the Vivado project ready, feel free to clone one of my repos like this:
git clone https://github.com/jonasjj/Jenkins-demo-packages
Then, cd into the new directory of the Git repository, and further into the vivado folder:
cd Jenkins-demo-packages/vivado/
If you downloaded my example, you would find two Tcl files:create_vivado_proj.tcl and check_syntax.tcl . The first one is the Vivado project converted to a Tcl file, and the second one is a script that we haven’t talked about yet. It’s for checking the syntax of VHDL files in the Vivado project.
Before we can run any Vivado command, we need to set the PATH environment variable in the current shell. In Jenkins, we solved this by using Global properties , but now we are not coming through Jenkins, so we have to source the setup script from Xilinx like this:
source /tools/Xilinx/Vivado/2019.2/settings64.sh
Now that the vivado executable is in our path, let’s start by recreating the project. This is the command for doing that when running Vivado in batch mode:
vivado -mode batch -source create_vivado_proj.tcl
After you hit Enter, you should see a whole lot of Tcl code echoed to the console. It’s the code for recreating the Vivado project that’s executing. If you didn’t see any obvious errors, type the command “echo $?” in the terminal before you do anything else. The output should be 0 if everything went well, as we can see from the listing below.
INFO: [Common 17-206] Exiting Vivado at Sun Apr 19 18:32:48 2020... [jenkins@jenkins vivado]$ echo $? 0
The “echo $?” command shows you the exit status from the previous command that you executed in Linux. An exit status of 0 means that everything is OK, no error. Any other exit status than 0 is an indication of error. Those are old Unix conventions that you can read more about here. Anyway, the exit status is important for Jenkins because that’s how it decides if a job stage is a success or a failure.
If you now do a directory listing, you will see that Vivado has recreated the project’s binary files:
[jenkins@jenkins vivado]# ls -la total 72 drwxrwxr-x. 6 jenkins jenkins 4096 Apr 19 18:32 . drwxrwxr-x. 4 jenkins jenkins 4096 Apr 19 18:18 .. -rw-rw-r--. 1 jenkins jenkins 217 Apr 19 18:18 check_syntax.tcl -rw-rw-r--. 1 jenkins jenkins 23375 Apr 19 18:18 create_vivado_proj.tcl drwxrwxr-x. 3 jenkins jenkins 16 Apr 19 18:32 packages.cache drwxrwxr-x. 2 jenkins jenkins 26 Apr 19 18:32 packages.hw drwxrwxr-x. 2 jenkins jenkins 6 Apr 19 18:32 packages.ip_user_files -rw-rw-r--. 1 jenkins jenkins 9314 Apr 19 18:32 packages.xpr -rw-rw-r--. 1 jenkins jenkins 638 Apr 19 18:32 vivado.jou -rw-rw-r--. 1 jenkins jenkins 20153 Apr 19 18:32 vivado.log drwxrwxr-x. 2 jenkins jenkins 6 Apr 19 18:32 .Xil
Let’s try another experiment with running Tcl scripts in Vivado batch mode. Create a one-liner Tcl script by using the following command:
Now, run the script in Vivado batch mode:
vivado -mode batch -source test.tcl
After Vivado closes, check the exit code once more using the “echo $?” command:
[jenkins@jenkins vivado]# echo $? 1
It’s 1, which means exit failure in Unix. If you change the content of the test.tcl script to “exit 0”, and run Vivado once again, you will see that the exit status is now 0, indicating success. Try it!
The exit keyword is standard Tcl. We are going to use it as the interface between Vivado and Jenkins. Jenkins runs whatever Tcl script we create in Vivado, and looks at the exit status to determine if it shall mark the job stage as success or failure.
Remember to delete our little test project from the jobs folder when you are happy with the experiment:
cd /var/lib/jenkins/jobs/ [jenkins@jenkins jobs]# rm -rf Jenkins-demo-packages
Tcl script for checking code syntax in Vivado
This Tcl script runs a syntax check of the VHDL files in the project. If you are going to simulate or implement the code, you won’t need this script because any syntax errors will break the compilation. But for my packages project, it doesn’t make any sense to create a testbench for it. The files just contain constant and types declarations. I still want to catch any coding errors pushed to this repo, and that’s where the syntax check comes in handy.
In the script that is listed below, we start by opening the project file. Then, we call the Vivado check_syntax command while telling it to save the output to a variable called msg . After the check has completed, we look at the output message to see if there were any errors reported. If check_syntax reported anything at all, we set the exit status to 1 (failure). If there were no errors, we exit 0 (success).
check_syntax.tcl:
# Check for syntax errors
# Return exit code 1 on error, else 0
open_proj packages.xpr
set msg [check_syntax -fileset sim_1 -return_string]
set ret_val 0
if {$msg != ""} {
set ret_val 1
}
puts $msg
exit $ret_val
Vivado supports all of the standard Tcl keywords, and there are also a lot of built-in commands like check_syntax. I recommend taking a look at these two Xilinx documents that cover the Tcl scripting capabilities in great detail:
Vivado Design Suite Tcl Command Reference Guide (UG835)
Vivado Design Suite User Guide Using Tcl Scripting (UG894)
Tcl script for simulating in Vivado
The next script that I created is for running the testbench in batch mode. For this to work, you have to configure the simulation sets in the Vivado GUI before you export the project to Tcl. Go ahead and recreate one of the simulation projects on your desktop computer using the create_vivado_proj.tcl script to see how I set it up beforehand. You can open the reconstructed projects in the Vivado GUI.
As you can see from the listing below, I start by opening the project. Then, I set the name of the simulation fileset to a variable (usually sim_1 ). After we launch the simulation, we also have to close it. Otherwise, the status of the simulation won’t get written to the log files.
run_simulation.tcl:
open_proj seg7.xpr set sim_fileset sim_1 launch_simulation -simset [get_filesets $sim_fileset] close_sim # Look for assertion failures in the simulation log set log_file [glob *sim/$sim_fileset/behav/xsim/simulate.log] set fp [open $log_file] set file_data [read $fp] exit [regex "Failure:" $file_data]
Now, I struggled to find a good way of getting the simulation status. My VHDL testbenches terminate on a VHDL finish keyword on success. Errors will result in a VHDL assertion failure. There’s no obvious way to find out why the simulator stopped by using Tcl commands in Vivado.
Fortunately, Tcl is a powerful scripting language. My workaround is to open the simulation log and look for the string “Failure:”, which indicates a VHDL assertion failure. Finally, we exit 1 if the word is in the log, or 0 if it isn’t.
Tcl script for synthesizing in Vivado
In the Tcl script for synthesizing in Vivado batch mode, we start by opening the project file. Then, We assign the run name to a variable. You must have added the design files to the Vivado project before you exported it to Tcl. If you didn’t change the name of the synthesis run in the GUI, it’s will probably be “synth_1”.
You should set the CPU count variable to the number of logical processors that your server has. This number controls the degree of multithreading that Vivado uses. I opted for the VPS with 4 CPUs on UpCloud, and therefore set the CPU count to 4.
run_synthesis.tcl :
open_proj seg7.xpr
set run_name synth_1
set cpu_count 4
reset_runs $run_name
launch_runs $run_name -jobs $cpu_count
wait_on_run $run_name
set status [get_property STATUS [get_runs $run_name]]
if {$status != "synth_design Complete!"} {
exit 1
}
exit 0
The launch_runs command is non-blocking, meaning that it will complete before the actual synthesis. If we try to read the status right after calling launch_run , it will be “Running”. To pause the script until the synthesis completes, we call the wait_on_run command.
Finally, we get the run status and exit 0 or 1, depending on the status message.
Tcl script for running the implementation in Vivado
The script for running Place and Route (PAR) in Vivado batch mode is similar to the synthesis script. The difference is that the run name is now “impl_1”, and that we are looking for another success message.
run_implementation.tcl :
open_proj seg7.xpr
set run_name impl_1
set cpu_count 4
reset_runs $run_name
launch_runs $run_name -jobs $cpu_count
wait_on_run $run_name
set status [get_property STATUS [get_runs $run_name]]
if {$status != "route_design Complete!"} {
exit 1
}
exit 0
Tcl script for generating the bitstream in Vivado
Finally, after if the implementation completes successfully, we can generate a bitstream for programming the FPGA. The script is similar to the previous one, but the launch_runs command is slightly different. And of course, we are looking or a different status in the end.
generate_bitstream.tcl :
open_proj seg7.xpr
set run_name impl_1
set cpu_count 4
launch_runs $run_name -to_step write_bitstream -jobs $cpu_count
wait_on_run $run_name
set status [get_property STATUS [get_runs $run_name]]
if {$status != "write_bitstream Complete!"} {
exit 1
}
exit 0
Setting up the Jenkins jobs
A job in Jenkins refers to a set of grouped software tasks. Jenkins displays jobs and their current status as items listed on the overview page. You can start jobs manually from the web interface, or they can be triggered automatically, for example, when someone pushes code to a repo, or as a result of another job completing. We will do both.
Jenkins offers several ways of managing jobs. The traditional method is the Freestyle project , where you specify every action from within the Jenkins web GUI. The more modern way of managing Jenkins jobs is to use a pipeline script that stores all of the information about the execution flow. The pipeline scripts have the benefit that you can add them to your SCM.
To create a new pipeline script, select New item from the Jenkins sidebar. In the dialog that opens, select the Pipeline option and click OK, as shown in the image below.
The first thing we have to do in the job configuration is to add the GitHub repository that contains the source code. In this example, I am using the packages repo, but the procedure is the same for all the other jobs and repos. Check the GitHub project box and enter the address in the Project url field that appears, as shown in the image below.
After that, we can set up the build triggers for this job. I want this job to start when someone pushes code to the GitHub repo. To do that, we check the box that says GitHub hook trigger for GITScm polling , as shown in the image below. Note that this will only work if you have checked the Manage hooks box in the global settings, as we did earlier.
At the bottom of the job configuration page is the Pipeline section. Here, you have to option to enter the pipeline script directly into the config page. But we want to version control the pipeline script. Therefore, we chose the Pipeline script from SCM option. Make sure that Git is selected, as shown in the image below.
Paste in the URL of your GitHub repository, and select your credentials if it’s a private repo. Ours is public, so we will leave the credentials blank. We will also go with the default master branch selection.
Finally, we have to select the path to the Jenkins script within the Git repository. I have created a file named Jenkinsfile at the root of each repo. Don’t forget to click Save before you leave the page.
Jenkins pipeline scripts
Pipeline scripts follow the same syntax rules as the Apache Groovy programming language, which I must admit I had never heard of before. Nevertheless, you won’t have a hard time understanding pipeline scripts if you’ve done any kind of modern programming. At first glance, it looks like a JSON schema without the commas separating the data items.
The scripts are quite versatile, and there are many options for things like executing stages in parallel or running tasks on multiple Jenkins servers. I suggest that you take a look at the official Jenkins pipeline documentation if you want to dig deeper into the matter.
Fortunately, you don’t need to know everything about them to benefit from pipeline scripts. We will use the format below as a template for all of your scripts. We will add as many stages as we need to split the job into logical steps.
pipeline {
agent any
stages {
stage('Stage name 1') {
steps {
// Command 1
// Command 2
// Etc.
}
}
stage('Stage name 2') {
steps {
// Command 1
// Command 2
// Etc.
}
}
}
post {
failure {
emailext attachLog: true,
body: '''Project name: $PROJECT_NAME
Build number: $BUILD_NUMBER
Build Status: $BUILD_STATUS
Build URL: $BUILD_URL''',
recipientProviders: [culprits()],
subject: 'Project \'$PROJECT_NAME\' is broken'
}
}
}
If somebody pushes faulty code to the repo, we want the culprit to receive an automated email with information about the failed job. To do that, we use a failure section within a post section. This part of the script will only execute if any of the stages fail. Then, the job will stop. Jenkins won’t go to the next stage if one fails. Instead, it will jump into the failur e section. Jenkins then lifts the email addresses from the latest Git commits and sends them an email with a link to the broken build.
VHDL syntax checking job
The only repo in our design that doesn’t have a testbench is the packages repo—instead, we user our check_syntax.tcl script to verify that the code is at least valid VHDL.
In the first step of our pipeline script, we call deleteDir() . That’s one of the basic commands available in Jenkins pipeline scripts. It cleans the working directory by removing any leftover from previous builds.
On the next line, we call git . Note that this is not the git Linux command, but a command referencing the git Jenkins plugin. We tell it to clone the repository into the workspace.
Finally, on the third line of the Create project stage, we use the sh keyword to call a Linux shell command. Here, we change to the vivado directory and run the create_vivado_proj.tcl script in Vivado batch mode to recreate the Vivado project.
Jenkinsfile:
pipeline {
agent any
stages {
stage('Create project') {
steps {
deleteDir() // clean up workspace
git 'https://github.com/jonasjj/Jenkins-demo-packages'
sh 'cd vivado && vivado -mode batch -source create_vivado_proj.tcl'
}
}
stage('Check VHDL syntax') {
steps {
sh 'cd vivado && vivado -mode batch -source check_syntax.tcl'
}
}
}
post {
failure {
emailext attachLog: true,
body: '''Project name: $PROJECT_NAME
Build number: $BUILD_NUMBER
Build Status: $BUILD_STATUS
Build URL: $BUILD_URL''',
recipientProviders: [culprits()],
subject: 'Project \'$PROJECT_NAME\' is broken'
}
}
}
In the second stage, the one named Check VHDL syntax , the Vivado project already exists, so we can jump to running our Tcl script. We use the shell command again to run the check_syntax.tcl file, which will exit 0 on success, or 1 on error, causing Jenkins to mark the build as a failure.
VHDL simulation jobs
For all other jobs than the packages repo, the git one-liner command won’t work for checking out the code from GitHub. The problem is that these repos have dependencies in the form of submodules. The submodules reference other Git repositories, which the simple git command doesn’t pull by default. But that’s OK; we can fix the issue by using the more versatile checkout call, also well-documented on the Git plugin page.
Jenkinsfile;
pipeline {
agent any
stages {
stage('Create project') {
steps {
deleteDir() // clean up workspace
checkout([$class: 'GitSCM', branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: false,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: true]],
submoduleCfg: [],
userRemoteConfigs: [[
url: 'https://github.com/jonasjj/Jenkins-demo-bcd_encoder']]])
sh 'cd vivado && vivado -mode batch -source create_vivado_proj.tcl'
}
}
stage('Run simulation') {
steps {
sh 'cd vivado && vivado -mode batch -source run_simulation.tcl'
}
}
}
post {
failure {
emailext attachLog: true,
body: '''Project name: $PROJECT_NAME
Build number: $BUILD_NUMBER
Build Status: $BUILD_STATUS
Build URL: $BUILD_URL''',
recipientProviders: [culprits()],
subject: 'Project \'$PROJECT_NAME\' is broken'
}
}
}
Finally, we run the run_simulation.tcl script in Vivado in the next stage.
The above listing shows the script used in the bcd_encoder repo. Identical scripts, only with different repo URLs, are used for the counter, digit_selector, output_mux, reset, and seg7_encoder repos as well.
FPGA implementation job
The seg7 repo contains the top module for our FPGA project. It pulls in all of the other repos as submodules. The pipeline script is similar to the one used for the simulation-only jobs, but with four added stages:Run simulation , Run implementation , Generate bitstream , and Release bitfile .
The first two stages create the project and run the simulation. I have already covered how they work in the previous sections of this article. The next three stages work the same way as the simulation stage, but with the Tcl script replaced with the ones that are relevant for the task.
Jenkinsfile:
pipeline {
agent any
stages {
stage('Create project') {
steps {
deleteDir() // clean up workspace
checkout([$class: 'GitSCM', branches: [[name: '*/master']],
doGenerateSubmoduleConfigurations: false,
extensions: [[$class: 'SubmoduleOption',
disableSubmodules: false,
parentCredentials: false,
recursiveSubmodules: true,
reference: '',
trackingSubmodules: true]],
submoduleCfg: [],
userRemoteConfigs: [[
url: 'https://github.com/jonasjj/Jenkins-demo-seg7']]])
sh 'cd vivado && vivado -mode batch -source create_vivado_proj.tcl'
}
}
stage('Run simulation') {
steps {
sh 'cd vivado && vivado -mode batch -source run_simulation.tcl'
}
}
stage('Run synthesis') {
steps {
sh 'cd vivado && vivado -mode batch -source run_synthesis.tcl'
}
}
stage('Run implementation') {
steps {
sh 'cd vivado && vivado -mode batch -source run_implementation.tcl'
}
}
stage('Generate bitstream') {
steps {
sh 'cd vivado && vivado -mode batch -source generate_bitstream.tcl'
}
}
stage('Release bitfile') {
steps {
sh '''
PROJ_NAME=seg7
RELEASE_DIR=/usr/share/nginx/html/releases/
BASE_NAME=$PROJ_NAME-`date +"%Y-%m-%d-%H-%H:%M"`
BITFILE=$BASE_NAME.bit
INFOFILE=$BASE_NAME.txt
git log -n 1 --pretty=format:"%H" >> $INFOFILE
echo -n " $PROJ_NAME " >> $INFOFILE
git describe --all >> $INFOFILE
echo "" >> $INFOFILE
echo "Submodules:" >> $INFOFILE
git submodule status >> $INFOFILE
cp $INFOFILE $RELEASE_DIR
cp vivado/seg7.runs/impl_1/top.bit $RELEASE_DIR/$BITFILE
'''
}
}
}
post {
failure {
emailext attachLog: true,
body: '''Project name: $PROJECT_NAME
Build number: $BUILD_NUMBER
Build Status: $BUILD_STATUS
Build URL: $BUILD_URL''',
recipientProviders: [culprits()],
subject: 'Project \'$PROJECT_NAME\' is broken'
}
}
}
The final stage of the implementation job is named Release bitfile . It contains a shell script that copies the newly generated FPGA programming file to a release folder. The shell command renames the file to include the name of the project and a timestamp.
To maintain traceability, we also generate a text file that contains the Git hash of the main repo (seg7 ) and all of the submodules. When working with Git submodules, it’s not enough to store the hash of the main repo. To generate a hash for the main repo that includes changes in all submodules, we would have to commit the main repo after pulling and updating all submodules. We don’t want to do that automatically from Jenkins.
Note that implementing the FPGA for every single push, like I am doing in the example, is probably not what you want for a real-life Jenkins project. It can take hours to build a large-scale FPGA project, and that wouldn’t work when you have a team of developers pushing multiple times per day. Instead of building after each push to the repo, you can configure Jenkins to route the FPGA only once a day. For example, at midnight, as shown by the screenshot below from the job configuration page.
Triggering builds after other jobs complete
Our example project consists of several Git repositories, but they are all tied together as Git submodules. Except for packages, all the other repos depend on at least one other repository. Most depend on the packages repository. Have a look at the dependency graph that I presented earlier in this article to see how it all fits together.
Therefore, we should trigger jobs not only by pushes to the repo in question but also after any of the submodules are touched. We can achieve this in Jenkins by visiting every job and setting the Build after other projects are built option accordingly.
The image below shows the trigger for the bcd_encoder project. It will start after the packages repo, which it depends on, completes a build successfully.
The top module depends on all other repos. I have added them as watch projects in a comma-separated list, as shown in the image below. Note that you may not want to do this for the FPGA implementation job if it takes a long time to route, as I mentioned in the previous section.
Serving the bitfiles using Nginx
Since we already have a web server running, we can use if for serving the release files over HTTP. I want all new bitfiles to appear on the URL jenkins.vhdlwhiz.com/releases . Let’s see how we can use Nginx for this.
Our implementation job already copies new bitfiles to a directory on the Nginx HTML root, but we haven’t created it yet. Create the release dir and give the Jenkins user write permissions by issuing the following commands:
mkdir /usr/share/nginx/html/releases/ chown jenkins.root /usr/share/nginx/html/releases/
Then we have to make a change to the /etc/nginx/nginx.conf file. Find the server section in the config file with a name equal to your domain. Add the following location section inside of it, directly below the root (‘/’) location section:
location ^~ /releases {
alias /usr/share/nginx/html/releases/;
autoindex on;
}
Finally, after you have saved the file, test the configuration file, and reload the Nginx server:
nginx -t systemctl reload nginx
If everything worked, you should be able to list the content of the release directory, as shown in the screenshot below from Google Chrome.
To tie the Jenkins web interface to the release dir, I want to create a link to if from the Jenkins sidebar. We have already installed the Sidebar Link plugin that enables custom links in the sidebar.
The next step is to go to Manage Jenkins->Configure System and scroll down to the Additional Sidebar Links section. Here, we can specify the name and URL of the new link, as shown in the image below. The link icon field is optional. I reused one of the icons that came with the Jenkins server.
After completing the previous step, you should now have a custom link to the bitfile releases in the sidebar, complete with a nice-looking folder icon, as you can see from the image below.
Сводка
Jenkins can be a valuable tool also for FPGA teams. Automating tasks can save your company time and improve the quality of your code. By using automatic build triggers and automated job pipelines, fewer coding errors will go unnoticed.
As we have seen from the example project presented in this article, Jenkins can implement a complete suite of regression tests for your VHDL code. It shows the current health of your project in a pleasant graphical web interface, suitable for even the most VHDL-illiterate project manager.
If you wish to try out Jenkins for FPGA development, I recommend following the steps in this article on an UpCloud VPS instance. I thoroughly researched all VPS providers a few years ago before moving VHDLwhiz to a VPS. I found that UpCloud was the fastest and best alternative. I’m still 100% pleased with the service.
If you decide to open an account on UpCloud, I kindly ask that you use my referral link or code:NV78V6 . Not only do you support VHDLwhiz, but you also get $25 of credit on UpCloud when using the promo code.
VHDL
- Базовая викторина VHDL — часть 1
- Как создать таймер в VHDL
- Формальная проверка в VHDL с использованием PSL
- Как просмотреть переменные VHDL в Modelsim во время моделирования
- Примеры преобразования VHDL
- Базовая викторина VHDL — часть 3
- Как генерировать случайные числа в VHDL
- Как создать конечный автомат на VHDL
- Что такое VHDL?
- Как создать самопроверяющийся тестовый стенд