LoginSignup
25
11

More than 3 years have passed since last update.

Docker for MacでXilinx FPGA用の開発環境を作る

Last updated at Posted at 2019-08-11

TL;DR

  • Xilinx ISEがインストールされたdockerイメージを作成しました。
  • Mac上から自動でビルドする環境を整備し、テンプレートとして公開しました。

はじめに

FPGAを販売するXilinx社では、ISE(最近のデバイス用にはVivado)と呼ばれる自社製の開発環境を用意しています。FPGAのコンフィグレーションに必要なBit stream file(*.bit)はこのISEを使って生成できますが、逆に言えばXilinx社謹製のISEを使わなければ生成できません。そして、ISEは対応OSがWindowsとLinuxのみなんですよね...見事にMacがハブれれてしまいました。メインで使っている端末がMacということもあり、MacからFPGAの開発ができると嬉しいな...と思いしばらくいじっていたので、備忘録を兼ねて記事にします。

以前の開発環境

一年ほど前にFPGAボードの開発をしていた際には、次のような環境で開発していました。

  • ターゲットデバイス
  • 開発&シミュレーション
    • Mac端末
    • 言語: VHDL
    • エディタ: Visual Studio Code
    • テスト用コンパイラ: ghdl
  • 実装
    • Windows端末
    • エディタ&コンパイラ: Xilinx ISE

状況としてはMacの方でVHDLコードを書き、ghdlでコンパイルして挙動を確認します。だいたいいい感じまでできたらソースコードをDropboxなりGithubなりにアップロードして、Windows端末にダウンロードし、Xilinx ISEで作成したプロジェクトにソースコードを加えて、実装用のBit stream fileを生成していました。
なぜこのような面倒な手順を踏んでいたかというと、Windows端末が研究室の端末で、自宅に持ち帰りが難しかったこと、加えてXilinx ISE上でのソースコードの編集がお世辞にもやりやすいとは言えなかった(補完やSyntax Highlightが貧弱だった)ため、ソースの編集はVS Code上でやりたかったという事情があります。Mac上でVMを使うことも考えたのですが、Mac上のストレージの容量が少なく、VMを立てたくもない状況でした。
そんなこんなで、このしち面倒臭い環境でしばらく開発をしており、そのときの目的が達成された後には、もう金輪際FPGAに関わることもないだろうと思っていたわけです。ただ、幸か不幸かまたFPGAに触る機会ができたので、この際Macで実装までできるようにしてやろうと思いまして、環境構築に取り組みました。

Mac上でのFPGA開発環境の構築

あらすじは次の通りです。

  1. Docker for MacでXilinx ISEインストール済みのdockerイメージを作成
  2. Pythonのinvokeパッケージを使ってコンパイル、テスト環境の構築

以下の手順では次のソフトウェアがインストールされていることを前提にしています。

  • Docker for Mac
  • Python 3.x
  • XQuartz
  • invoke (Python package)
  • ghdl

docker、XQuartz、Python3、ghdlはHomebrewから、invokeはAnaconda経由で入手しました。invokeはpipでも入手できるようです。

1. Docker for MacでXilinx ISEインストール済みのdockerイメージを作成

~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~
以下の手順でISE Webpack editionをインストールしたものはDocker Hub上でseekworser/ise_webpackで公開しているため、Webpack版であれば

docker pull seekworser/ise_webpack

で事足ります。容量が30 GB以上あるので注意してください。
~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~/~

dockerを使ってXilinx Vivadoをインストールしている方がいらっしゃったので、その記事を参考にしました。
Xilinx の開発ツールを Docker コンテナに閉じ込める

この方はVivado HLx 2018.2: All OS installer Single-File Downloadをダウンロードしてきて、インストールまで含めてDockerfileで自動化しているのですが、ISEではSingle file Downloadが存在しないため、泣く泣くインストールは手動で行います。
そこで、まずfull installer for Linuxをダウンロードしてきて、次のようなDockerfileを作成しました。

Dockerfile
FROM ubuntu

RUN \
  sed -i -e "s%http://[^ ]\+%http://ftp.jaist.ac.jp/pub/Linux/ubuntu/%g" /etc/apt/sources.list && \
  apt update && \
  apt upgrade -y && \
  apt -y --no-install-recommends install \
  ca-certificates curl sudo xorg dbus dbus-x11 ubuntu-gnome-default-settings gtk2-engines \
  ttf-ubuntu-font-family fonts-ubuntu-font-family-console fonts-droid-fallback lxappearance && \
  apt-get autoclean && \
  apt-get autoremove && \
  rm -rf /var/lib/apt/lists/* && \
  echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers

COPY Xilinx_ISE_DS_Lin_14.7_1015_1.tar /

RUN mkdir /ise-installer &&\
  tar --strip-components 1 -C /ise-installer \
  -xvf Xilinx_ISE_DS_Lin_14.7_1015_1.tar &&\
  rm /Xilinx_ISE_DS_Lin_14.7_1015_1.tar

前半は先のリンクの方から丸パクリで、X11環境のインストールその他です。後半でインストール用のフォルダを/ise_installer下に展開しておきます。(ファイル名はバージョンに合わせて変えてください)

ここからGUIインストーラを立ち上げ、ISEをインストールします。Docker for MacでX11 GUIを立ち上げる際には次を参考にしました。
Mac+dockerでx11アプリケーションを起動する

先ほどのDockerfile、ダウンロードしたインストーラを全て同じフォルダに入れ、さらにhost側でXQuartzを立ち上げた状態で以下のコマンドを実行します。

docker build --no-cache --rm -t ise-installer .
xhost + 127.0.0.1
docker run -e DISPLAY=docker.for.mac.localhost:0 --name ise-installed ise-installer /ise-installer/xsetup

その後XQuartzでインストーラが起動するため、指示にしたがってインストールを行います。インストール後に、

(host)$ docker commit ise-installed ise-installed
(host)$ docker run -i --name ise ise-installed /bin/bash
(container)$ rm -rf /ise-installer
(container)$ exit
(host)$ docker commit ise ise
(host)$ docker container rm ise-installer ise-installed ise
(host)$ docker image rm ise-installer ise-installed

を順に実行し、ISEのインストールされたイメージiseを作成します。

2. Pythonのinvokeパッケージを使ってコンパイル、テスト環境の構築

先ほど作成したimageと、Pythonのinvokeパッケージを使用して、コンフィギュレーション用のBit stream fileを作成する環境を作成します。seekworser/ise_project_templateでPapilio pro用に作成したものは公開しています。
ディレクトリ構成は次のようになっています。

ise_project_template
.
├── Readme.md
├── log/
├── out/
├── test/
├── src/
│   ├── project.yaml
│   ├── sample.vhd
│   ├── sample_ucf.ucf
│   └── test_sample.vhd
├── sample.bit
└── tasks.py

logファイルの出力、中間ファイルの出力、ソースコード保管、test用のファイルの出力用のディレクトリとinvoke用のPythonスクリプトが置いてあります。

sample.vhdがメインのVHDLファイルです。

sample.vhd
entity sample is
    -- write ports
end sample;
architecture behavior of sample is
    -- write behavior
end behavior;

また、sample_ucf.ucfはFPGAの制約ファイルです。
プロジェクトが変わるごとにMakefileもといtasks.pyをいじるのは嫌だったので、project.yamlにコンパイル用のパラメータを格納しておくようにします。ついでに使うFPGAの情報もpart:以下に書いておきます。

project.yaml
src_files:
  - file_name: sample.vhd
    language: vhdl
    library: work
    entity_names:
      - sample 

test_files:
  - file_name: test_sample.vhd
    entity_names:
      - test_sample
      - test_sample2

ucf_file: sample_ucf.ucf

top_module: sample

part:
  device: xc6slx9
  package: tqg144
  speed: -2

tasks.pyではこの情報を読み取って、ビルドやテストなどを行うようコードを書いておきます。例えば次のようなイメージです。

tasks.py(一部)
import yaml
import invoke

def get_project_parameter(*keys):
    param = yaml.load(open(PROJECT_YAML_FILE_NAME, "r+"))
    for item in keys:
        param = param[item]
    return param

@invoke.task
def bitgen(c):
    c.run(
        "docker run --rm -i -v $(PWD):/project seekworser/ise_webpack:latest sh <<_EOT_\n"
        "cd /project\n"
        "{ise_base:s}bitgen -w {outdir:s}{top_module:s}.ncd {top_module:s}.bit {outdir:s}{top_module:s}.pcf\n"
        "mv *.drc {logdir:s}{top_module:s}_drc.log\n"
        "mv *.bgn {logdir:s}{top_module:s}_bitgen.log\n"
        "rm -rf *.xwbt _xmsgs xilinx_device_details.xml *.xrpt\n"
        "_EOT_".format(
            ise_base=ISE_BASE,
            top_module=get_project_parameter(TOP_MODULE_KEY),
            outdir=OUTDIR,
            logdir=LOGDIR,
        )
    )
    return

# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 
# some other tasks
# ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ 

ISE_BASE = "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/"
OUTDIR = "./out/"
SRCDIR = "./src/"
LOGDIR = "./log/"
PROJECT_YAML_FILE_NAME = SRCDIR + "project.yaml"
TOP_MODULE_KEY = "top_module"

最終的にどうなったか

以上の結果として

invoke builde

のコマンド一発でMacからBit stream fileが生成できるようになりました。ISEの使いにくいエディタを使う必要もなくなったため、開発がよりスムーズに進むようになりました。

25
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
25
11