Jenkins、Vivado、GitHubを用いたLinux VPS上でのFPGA開発自動化
継続的インテグレーション/デリバリーをFPGA開発に適用
継続的インテグレーション(CI)と継続的デリバリー(CD)は、コード変更からデプロイまでのサイクルタイムを短縮するアジャイルソフトウェア開発手法です。自動化によってコード変更を検証し、リリースファイルをビルドすることで、チームはより生産的かつ効率的になれます。ソフトウェア企業は長年継続的開発を実践してきましたが、同じ手法をFPGAプロジェクトにも適用できます。このチュートリアルでは、Jenkins、Xilinx Vivado、Git/GitHub SCM(ソースコード管理)システムを用いて、仮想プライベートサーバ(VPS)上に自動化サーバを構築する方法を解説します。
Jenkinsとは
Jenkins自動化サーバは、Javaで書かれた無料のオープンソースプログラムで、WindowsやLinuxで動作します。ヘッドレスサーバで最も一般的なLinuxを使用します。JenkinsはLinuxではデーモンプロセス、Windowsではサービスとして動作し、起動時に組み込みWebサーバを起動してUIを提供します。ほとんどのユーザーはWebインターフェースでJenkinsとやり取りし、新しい自動化プロジェクトの追加や既存プロジェクトの管理を行います。
メインページにはジョブの一覧が表示されます。ジョブには任意のタスクを含められ、Web GUIから手動でトリガーしたり、スクリプト、Webhook、他のジョブ完了の結果として自動的にトリガーしたりできます。これが「自動化サーバ」と呼ばれる所以です。この例では、各ジョブが個別のGitHubリポジトリに保管されたVHDLモジュールに対応します。開発者が監視対象のGitリポジトリにコードをプッシュするたびに、Jenkinsがシミュレーションとビルドを実行。テストベンチ失敗やビルドエラーがあれば、ジョブを失敗としてマークし、問題のあるコードをコミットした担当者に自動的にメール通知します。
サンプルプロジェクト:8リポジトリ構成のFPGA設計
自動化サーバは大規模プロジェクトに取り組むチームで最も有用です。ここでは、Fast-Trackコースの7セグメントディスプレイカウンタをXilinx ZedBoardに移植した例として、8つのGitリポジトリで構成されるFPGAプロジェクトを構築しました。
- packages(VHDLパッケージ)
- bcd_encoder(モジュール)
- counter(モジュール)
- digit_selector(モジュール)
- output_mux(モジュール)
- reset(モジュール)
- seg7_encoder(モジュール)
- seg7(トップモジュール)
各リポジトリにはVHDLモジュールとテストベンチが含まれます(packagesリポジトリは定数と型を定義する3つのVHDLパッケージのみ)。seg7トップモジュールにはクロック速度とピン割り当てを定義する制約ファイルも含まれます。大規模VHDLプロジェクトでは複数リポジトリのモジュールを使用するのが一般的で、企業はパッケージとモジュールのライブラリを多くの設計で再利用します。この例では、すべてのモジュールがpackagesリポジトリに依存し、トップモジュールはすべてのサブモジュールにも依存します。これをGit Submodulesでインポートすることで解決しています。
仮想プライベートサーバ(VPS)の選定と導入
JenkinsはあらゆるWindows/Linuxコンピュータで動作しますが、実用的には専用サーバでの運用が必要です。自動化サーバは常時稼働し、チーム全員からアクセス可能でなければなりません。物理サーバがあれば理想的ですが、多くの場合VPSがより迅速かつ安価です。VPSはホスティング会社からインターネット経由で借りる仮想コンピュータで、実機と同様に操作・ソフトウェアインストールが可能。Linuxを使用します。
筆者はVHDLwhizサイトを2年間VPSで運用し、最速・最良のプロバイダとしてUpCloudを特定しました。今回もUpCloudを使用します。紹介コード「NV78V6」使用で25ドル分のクレジットが得られます。
UpCloud VPSのデプロイ
- UpCloudアカウントで「Servers → Deploy server」へ
- 最寄りのデータセンターを選択
- プラン選択:Jenkins自体は軽量だが、Xilinx Vivadoは大量のRAMを消費するため、最低4GB RAMプランを推奨(2GBではルーティング時にOOMでクラッシュした実績あり)
- OSは最新CentOSを推奨(Xilinx Vivado公式サポートはRed Hat Linuxだが、CentOSは無料でRed Hatに準拠)
- ネットワーク設定はデフォルトでOK。SSH鍵をアップロード可能
- ホスト名とサーバ名を指定し「Deploy」
DNSゾーン設定
サーバには固定IPv4/IPv6アドレスが割り当てられます。SSHでroot@IPアドレスへ接続可能。実用的にはドメイン名を割り当てるのが望ましいです。筆者はvhdlwhiz.comのサブドメインjenkins.vhdlwhiz.comを作成し、DNSゾーンファイルでAレコードを設定。伝播には通常20分程度、最大48時間かかる場合があります。
Jenkinsのインストールと設定
前提パッケージのインストール
yum -y update yum -y install java-11-openjdk-devel # VivadoはJava 11必須。JenkinsデフォルトのJava 8では後で問題になるため先に入れる 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 yum -y install jenkins systemctl start jenkins systemctl enable jenkins
HTTPS化(推奨)
デフォルトではポート8080でHTTPのみ。公共Wi-Fi等での認証情報盗聴リスクがあるため、Nginx + Let's EncryptでHTTPS化することを強く推奨します。
yum -y install nginx
systemctl start 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
certbot --nginx # 対話的に設定。HTTP→HTTPSリダイレクトを選択(オプション2)
# 自動更新cron設定
echo "0 0 * * * /snap/bin/certbot renew --quiet" | crontab -
# Nginx設定でJenkinsへプロキシ
# /etc/nginx/nginx.conf のserverブロック内に以下を追加
location / {
proxy_pass https://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
systemctl reload nginx
Jenkins初期設定
- ブラウザでアクセス → 初回パスワード入力(
cat /var/lib/jenkins/secrets/initialAdminPassword) - 「Install suggested plugins」を選択
- 管理者ユーザー作成
- 「Jenkins is ready!」でダッシュボードへ
推奨プラグイン
- Blue Ocean:モダンなUIとワークフロー、関連プラグインを一括導入
- Green Balls:成功ジョブを青ボールから緑ボールに変更(視認性向上)
- Locale:UI言語を強制指定(英語推奨)
- Sidebar Link:サイドバーにカスタムリンク追加(リリースファイル用)
GitHub連携設定
- GitHubでPersonal Access Token生成(権限:admin:org_hook, admin:repo_hook, repo)
- Jenkins「Manage Jenkins → Configure System → GitHub」で「GitHub Server」追加、「Manage hooks」チェック
- Credentialsに「Secret text」としてトークン登録、ID「GitHub」
- 「Test connection」で確認、Save
メール通知設定
- 「System Admin e-mail address」に送信元アドレス設定(Jenkinsドメインと同一推奨)
- SMTPサーバとしてsendmailインストール・設定
- SMTPサーバを「localhost」に設定、「Test configuration」で確認
yum -y install sendmail systemctl enable sendmail systemctl restart sendmail
Xilinx Vivadoのバッチモードインストール
- Xilinx Unified Installer(Linux Self Extracting Web Installer)をダウンロード
- SCP等でサーバへ転送
- 依存パッケージインストール
- インストーラ展開
- ツール選択してインストール
yum -y install tar java-11-openjdk-devel ncurses-compat-libs gcc
./Xilinx_Unified_2019.2_1106_2127_Lin64.bin --keep --noexec --target Xil_installer
cd Xil_installer/ ./xsetup -b ConfigGen # 対話式で「2: Vivado」→「1: Vivado HL WebPACK」を選択 ./xsetup -a XilinxEULA,3rdPartyEULA,WebTalkTerms -b Install -c ~/.Xilinx/install_config.txt
インストールには数時間かかります(24GB、Xilinxサーバからのダウンロードがボトルネック)。完了後、バッチモード起動テスト:
source /tools/Xilinx/Vivado/2019.2/settings64.sh vivado -mode batch -version
VivadoをJenkinsに統合
- 「Manage Jenkins → Configure System」で「# of executors」を1に設定(Vivadoの大量RAM消費対策)
- 「Global properties → Environment variables」でPATHをグローバル設定
PATH=/tools/Xilinx/Vivado/2019.2/bin:/sbin:/usr/sbin:/bin:/usr/bin
Vivado GUIプロジェクトをバッチモードで扱う
Vivadoプロジェクト(.xpr)はバイナリでGitに不向き。Xilinxガイドライン(XAPP1165)に従い、write_project_tclコマンドでTclスクリプト(create_vivado_proj.tcl)としてエクスポートし、これをGit管理します。リポジトリ構成は、VHDLソースを親ディレクトリ、Vivado関連ファイルをvivado/サブフォルダに配置。.gitignoreでvivado/以下のTcl以外を無視します。
Tclスクリプト群
- check_syntax.tcl:VHDL構文チェック(packagesリポジトリ用)
- run_simulation.tcl:シミュレーション実行、ログから「Failure:」検出で成否判定
- run_synthesis.tcl:論理合成実行(synth_1)、CPUコア数指定で並列化
- run_implementation.tcl:配置配線実行(impl_1)
- generate_bitstream.tcl:ビットストリーム生成(write_bitstreamステップまで実行)
各スクリプトはTclのexit 0(成功)/ exit 1(失敗)で終了し、Jenkinsが成否を判定します。
Jenkinsジョブ(パイプライン)設定
「New Item → Pipeline」で作成。GitHubリポジトリURL設定、ビルドトリガーで「GitHub hook trigger for GITScm polling」有効化。「Pipeline script from SCM」でリポジトリルートのJenkinsfileを指定。
パイプラインスクリプトテンプレート
pipeline {
agent any
stages {
stage('Stage name 1') { steps { /* commands */ } }
stage('Stage name 2') { steps { /* commands */ } }
}
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'
}
}
}
失敗時、最新Gitコミットのメールアドレスへ自動通知(culprits())。
ジョブタイプ別設定
- VHDL構文チェックジョブ(packages):
git clone→create_vivado_proj.tcl→check_syntax.tcl - シミュレーションジョブ(bcd_encoder等):サブモジュール込みで
checkoutステップ使用 →create_vivado_proj.tcl→run_simulation.tcl - FPGA実装ジョブ(seg7トップ):上記に加え、
run_synthesis.tcl→run_implementation.tcl→generate_bitstream.tcl→ Release bitfileステージでビットファイルとトレーサビリティ情報(Gitハッシュ、サブモジュールステータス)をNginx公開ディレクトリへコピー
※ 実装は時間がかかるため、実運用では毎プッシュではなく日次ビルド等に制限推奨。
ジョブ間トリガー連携
依存関係に基づき「Build after other projects are built」設定。packages完了後にbcd_encoder等をトリガー、トップモジュールは全サブモジュール完了後にトリガー。
Nginxでビットファイル公開
mkdir /usr/share/nginx/html/releases/
chown jenkins.root /usr/share/nginx/html/releases/
# /etc/nginx/nginx.conf に追加
location ^~ /releases {
alias /usr/share/nginx/html/releases/;
autoindex on;
}
nginx -t && systemctl reload nginx
Jenkinsサイドバーに「Sidebar Link」プラグインで/releasesへのリンク追加。
まとめ
JenkinsはFPGAチームにとっても価値あるツールです。自動ビルドトリガーとパイプラインにより、コーディングエラーを見逃さず、コード品質向上と時間節約を実現します。本記事の例では、VHDLコードの完全なリグレッションテストスイートを実装し、プロジェクトマネージャでも理解しやすいグラフィカルWebインターフェースでプロジェクト健全性を可視化しています。UpCloud VPSで本手順を試すことを推奨します。紹介コード NV78V6 で25ドルクレジット獲得可能です。
VHDL
- 初めてのFPGA:LED点滅チュートリアル(VHDL&Verilog)
- VHDLのCase-When文マスター:効率的なマルチプレクサ設計
- PSLによるVHDLモジュールの形式的検証マスター
- VHDL並行文マスター:実践ガイド
- VHDL基礎力を試す:インタラクティブクイズ Part 1
- ブロックRAMからの正弦波でブリージングLED効果を実現する
- Xilinx Vivadoをマスターする: 統合ロジック・アナライザ(ILA)とバーチャル入出力(VIO)によるデバッグ
- VHDLのsigned/unsigned型マスター:実践ガイド
- Modelsimシミュレーション中にVHDL変数を波形表示する方法
- VHDLとは? ハードウェア記述言語の実践ガイド
- プロセス内プロシージャでVHDLステートマシンをクリーンに設計