備忘：QuartusとModelSimの環境構築メモ

自宅で行ったQuartusとModelSimの環境構築メモ。
やったことはQuartusとModelSimが要求するライブラリをDockerイメージに閉じ込めてサーバ(ホスト)をキレイに保っただけ。

今回作成したDockerfileは、[quartuslib](https://github.com/sarakane6090/dockerfiles/tree/master/quartuslib)

# まずは結論

だいたい下の図のような環境になった。
FPGAボードにはQuartus Prime Programmerのリモート機能を使って書き込みを行う。
![quartus_setup](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84681/9e448b68-e521-9119-9c47-c46c7842ec5d.png)

# 試した環境

* クライアント
    * Windows 10 Pro 64bit (1801)
        * Quartus Prime Programmerのみインストールした
* サーバ
    * Ubuntu 18.04 x86_64
        * QuartusPrime Lite 18.1
    * Docker 18.09

# 1. QuartusとModelSimのインストール

必要なライブラリだけDockerイメージに入れる主義なので、QuartusとModelSimはサーバ(ホスト側)に直接インストールする。
デフォルトの`/home/$USER`下ではなく`/eda`を作りそこにインストールした。

またModelSim内のvco等が`linuxpe`を参照しているがそんなディレクトリは存在しない。
これはシンボリックリンクを貼ることで解決した。

```bash
sudo ln -s /eda/intelFPGA_lite/18.1/modelsim_ase/linuxaloem/ /eda/intelFPGA_lite/18.1/modelsim_ase/linuxpe
```

# 2. 必要なライブラリ類をDockerイメージに

今回書いたDockerfileは、[ittouogami](https://github.com/ittouogami)さんの[quartus18.1_docker](https://github.com/ittouogami/quartus18.1_docker)を大いに参考させていただいた。

<details><summary>Dockerfile</summary><div>

```Dockerfile:Dockerfile
FROM ubuntu:18.04

ENV DEBCONF_NOWARNINGS noninteractive

COPY build_freetype.sh /tmp
COPY entrypoint.sh /usr/local/bin/entrypoint.sh

# Environment Variables for Quartus Prime and ModelSim
ARG QUARTUS_VER="18.1"
ENV QSYS_ROOTDIR="/eda/intelFPGA_lite/$QUARTUS_VER/quartus/sopc_builder/bin"
ENV PATH=$PATH:/eda/intelFPGA_lite/$QUARTUS_VER/quartus/bin
ENV PATH=$PATH:/eda/intelFPGA_lite/$QUARTUS_VER/modelsim_ase/linuxaloem
ENV LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib32

RUN set -eux && \
    sed -i -e '$a deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse' /etc/apt/sources.list && \
    dpkg --add-architecture i386 && \
    apt-get update && \
    apt-get install --no-install-recommends -qq -y \
        software-properties-common \
        build-essential \
        g++-multilib \
        gcc-multilib \
        gosu \
        && \
    # Install libraries required for Quartus Prime
    apt-get install --no-install-recommends -qq -y \
        libfontconfig1:amd64 \
        libglib2.0-0:amd64 \
        libpng12-0:amd64 \
        libsm6:amd64 \
        libxext6:amd64 \
        libxrender1:amd64 \
        locales \
        && \
    locale-gen en_US.UTF-8 && \
    # Install librarise required for Platform Designer(Qsys)
    apt-get install --no-install-recommends -qq -y \
        openjdk-8-jre \
        && \
    # Install libraries required for ModelSim
    apt-get install --no-install-recommends -qq -y \
        libncurses5:i386 \
        libxext6:i386 \
        libxft2:i386 \
        wget \
        && \
    chmod +x /tmp/build_freetype.sh && \
    /tmp/build_freetype.sh && \
    # Clean up
    rm -rf /tmp/* && \
    apt-get autoclean && \
    apt-get autoremove && \
    rm -rf /var/lib/apt/lists/* && \
    # Set entry point
    chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

CMD ["/bin/bash", "-l"]
```
</div></details>

Dockerを使わない場合は下記の4つのライブラリを入れればいけると思う(Ubuntu18.04では)
注意点はModelSimが32bitライブラリや古いfreetypeを要求してくる。
特にfreetypeはソースからコンパイルするか`.deb`とか見つけてインストールする必要があった。

```bash
# ※Dockerを使わない場合

# QuartusとModelSimに必要なライブラリのインストール
$ sudo sed -i -e '$a deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse' /etc/apt/sources.list
$ sudo dpkg --add-architecture i386
$ sudo apt-get update && \
  sudo apt-get install -y \
  libpng12-0:amd64 \
  libncurses5:i386 \
  libxext6:i386 \
  libxft2:i386

# freetypeを自分でコンパイルするなら
$ sudo apt-get install build-essential gcc-multilib g++-multilib
$ wget http://download.savannah.gnu.org/releases/freetype/freetype-2.4.12.tar.bz2
$ tar xf freetype-2.4.12.tar.bz2
$ cd freetype-2.4.12
$ ./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
$ make
```

Dockerイメージでは`freetype-2.4.12/objs/.libs`の中身をすべて`/lib32`に入れた

またDockerコンテナ内では一般ユーザとして作業をしたいためエントリーポイントを下記のようにした

```bash:entrypoint.sh
#!/bin/bash

USER=${USER:-root}
USER_ID=${LOCAL_UID:-1000}
GROUP_ID=${LOCAL_GID:-1000}
echo "Starting with UID: $USER_ID, GID: $GROUP_ID, USER: $USER"

if [[ -n "$USER_ID" ]]; then
  export HOME=/home/$USER
  useradd -s /bin/bash -u $USER_ID -o -d $HOME $USER
  echo ${USER}:${USER} | chpasswd
  chown $USER_ID:$GROUP_ID -R $HOME
  chown $USER $(tty)
  exec /usr/sbin/gosu "$USER" "$@"
else
  exec "$@"
fi
```

# 3. コンテナに入る

指定する環境変数やボリュームが多いため起動用のシェルスクリプトを書いた。

```bash:boot_docker.sh
docker run -it --rm \
    --net host \
    -e LOCAL_UID=$(id -u $USER) \
    -e LOCAL_GID=$(id -g $USER) \
    -e USER=$USER \
    -e DISPLAY=$DISPLAY \
    -e "QT_X11_NO_MITSHM=1" \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    --privileged \
    -v /sys:/sys:ro \
    -v /eda:/eda \
    -v $HOME:$HOME \
    -v $(pwd):$(pwd) \
    -w $(pwd) \
    sarakane6090/quartuslib:1.0 $1
```

起動時に引数を指定しなければそのままコンテナに入れ、
例えば`quartus`を指定すれば直接QuartusがGUIで立ち上がる。

```bash
# コンテナに入る
$ ./boot_docker.sh

# QuartusをGUIで立ち上げる
$ ./boot_docker.sh quartus
```

GUIはホストのX11-unixを利用している。XクライアントはmobaXtermを利用、万能である。

またコマンド入力を楽にするためmakeを利用した

```Makefile:Makefile
PRJ_NAME := <project_name>
PRJ_DIR := ./path/to/<project_dir>
DOCKER := ./path/to/boot_docker.sh

synthesis:
	$(DOCKER) "quartus_sh --flow compile $(PRJ_DIR)/$(PRJ_NAME)"

program:
	$(DOCKER) "quartus_pgm --id 1 --mode=JTAG -o ""p;/path/to/output_files/$(PRJ_NAME).sof"""

quartus:
	$(DOCKER) "quartus $(PRJ_DIR)/$(PRJ_NAME)"

modelsim:
	$(DOCKER) "vsim"
```

# 4. リモート機能(Jtag Server)を有効にする

クライアントPCではコーディングと実機デバッグのみ行えればいいため、
最低限書き込みとSignal tapが使える`Quartus Prime Programmer and Tools`をインストールした。
消費容量は1.25GBくらいなのでノートPCにも安心して入れられる。

ただしWindowsでもLinux(Ubuntu)でもインストールしただけでは使えなかった。
それぞれ下記の作業が必要

* Windows
    * ファイアウォールに`Jtag Server`を許可する
    * 初期状態ではプライベートは無効でパブリックが有効だった。（普通逆では？）
* Linux(Ubuntu)
    * jtagconfigが必要とする`libudev.so.0`が`/usr/lib`に無いためシンボリックリンクを貼る。
    * `sudo ln -s /lib/x86_64-linux-gnu/libudev.so.1 /usr/lib/libudev.so.0`

Jtag Serverを有効にするには下記のコマンドを管理者権限で実行
Linuxなら一般ユーザから実行する。

```powershell

# PowerShellなら
cd $env:QUARTUS_ROOTDIR¥bin64

# CMDなら
cd %QUARTUS_ROOTDIR%¥bin64

# 下記のコマンドでJtag Serverを有効にする
jtagconfig --enableremote <password>
```

Quartus Prime Programmerを立ち上げ、先程設定したJtag Serverを追加する。
下記の画像でいうと(4)にホスト名またはIPアドレスとパスワードを入れる。
![quartus_prime_programmer](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84681/04d452f1-9ae5-4db8-5232-f241a5dcd6d2.png)

Conection StatusにOKやNo Hardwareと表示されればリモート先と接続できている。
もし長い間描画が固まれば100%失敗しているので、ファイアウォールなどネットワーク周りを確認すること。

# 参考

* [Altera(Intel)のFPGA開発ツール「Quartus Prime」をUbuntuにインストールする](http://cellspe.matrix.jp/zerofpga/inst_quartus.html)
    * 一番始めに参考にさせていただいた。
* [Ubuntu16.04 64-bitで、Quartus II 13.1からModel-sim](http://uzusayuu.hatenadiary.jp/entry/2017/04/23/073831)
* [Installing Altera Quartus II 14.0 and ModelSim on Ubuntu Linux 14.10 system](https://www.molnar-peter.hu/en/altera-quartusii-14-0-install-ubuntu-14-10.html)
    * 上記2つはModelSimを動かすために参考になった
* [ittouogami/quartus18.1_docker](https://github.com/ittouogami/quartus18.1_docker)
    * Dockerfile作りに大いに参考になった。感謝