【ソフトウェア技術者向けFPGA設計】SDSoCを使ってZedBoard上にC++プログラムをハードウェア実装し、LAN経由で実行する方法

FPGA初心者の自分による、SDSoCを使ってZedBoard上にサンプルのC++プログラムをハードウェア化、LAN経由で実行するまでの過程を今後のために残しておきます。

* SDSoCとは
    * Xilinx社の提供する、C++で書かれたコードからハードウェアの生成をしたり、生成された実行ファイルをSDカードにコピーしZedBoardに挿して動作させたりといったことができる開発環境の1つです。
本記事ではこれらの機能を、同じくXilinx社のツール「SDx IDE」から利用します。

実行までの手順は6つに分けられ、それぞれ

1. プロジェクトの作成
1. プロジェクトのビルド
1. ビルドしてできたファイルをSDカードへコピー
1. LANへつなぐ
1. ZedBoardのipアドレスを調べる
1. ssh

です。これらについて下記で詳細を説明していきます。

#環境
* windows10 64bit
* SDx IDE 2019.1
* ボード
    * ZedBoard

#1. プロジェクトの作成
SDx IDEを起動し、ウィンドウ左上のFile→New→SDx Application projectと選びプロジェクトの作成に移ります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/b75aed0f-8052-487e-aa52-176be90714e7.png" width=60%>

プロジェクト名を決めます。今回は適当にsampleとでもしておきます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/fc26c0aa-e57c-c211-833a-75e20b5f576c.png" width=60%>

「Next」を押して、次にボードの種類を選びます。今回は「zed」を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/9444e28c-2889-88d6-d864-a3af2b21bc5b.png" width=60%>

次の画面「System configuration」ですが、今回はデフォルト値を用いることにします。何も変更を加えず「Next」を押します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/af467440-66be-2b24-8a95-af2ab70f9101.png" width=60%>

プロジェクトのテンプレートを選ぶ画面です。テンプレートには例えばFIRフィルター、行列の計算などがありますが、ここでは「Array_zero_copy」（配列をただコピーして返すだけの機能を持つ）を選択します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/0239716c-bd02-adb2-c4f3-6e4738b217c7.png" width=60%>

「Finish」を押すとプロジェクトが作成されます。

#2. プロジェクトのビルド
まずプロジェクトのビルドをすることでZedBoardを動かすのに必要なファイルを生成します。
先ほど作成したプロジェクトを開くと、下のような画面が表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/064b7e23-9b86-9b72-33d2-817cba8cb359.png" width=60%>

画面左上あたりにハンマーのマークがありますが、そこをクリックして出てくる選択肢のうち「Debug」を押してビルドを開始します。
注意点として、この時「Debug」ではなく「Release」を押してしまうとビルドに数時間かかってしまうことがあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/eec31eb6-5476-5a41-ebcc-e2828b933a1c.png" width=60%>
ビルドには数分かかるので気長に待ちましょう。

ビルドが完了すると画面下の「Console」タブに「Build Finished」と表示されます。（図中の水色の枠で囲った部分）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/643778a1-86de-b88b-f03a-72a76216a9fc.png" width=60%>

#3. ビルドしてできたファイルをSDカードへコピー

ビルド後、```Debug/sd_card/```下に数個ファイルが生成されます。今回の場合は下の図の水色で囲った箇所のように４つ作成されていると思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/d5b0f592-d469-4319-d891-7f9b87ed1ee8.png" width=60%>
このうちsample.elfが実行ファイルで、「Array_zero_copy」の機能（配列をただコピーして返す）を持っています。これをZedBoardにsshでログインした状態で実行するのが目標です。

これらの```Debug/sd_card/```下のファイルを全部SDカードの直下にコピーします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/b456f0c2-9d4c-7294-1522-aee4b46d7a7c.png" width=60%>

コピーしたらSDカードをPCから取り出しZedBoardに差し込みます。


#4. LANへつなぐ
LANケーブルの一方をZedBoardに、もう一方をルーターに繋ぎます。さらにZedBoardに電源をつなぎ、下の図の水色の枠で囲ったスイッチを横にスライドして起動します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/d24d9e00-5909-567a-7387-4567d6d2b5b7.jpeg" width=60%>

下の図のようなイメージで接続ができているとベストです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/18f8e464-1f05-bd8e-b035-5b010e53f8bf.png" width=60%>

#5. ZedBoardのipアドレスを調べる
##Advanced IP Scannerのインストール
LANに接続されたZedBoardにsshするために、ZedBoardのローカルipアドレスを知る必要があります。これはAdvanced IP Scannerという、同じLANに接続されている機器の情報を取得できるツールを用いると手軽に行うことができます。以下のサイトからダウンロードできます。
https://www.advanced-ip-scanner.com/jp/

ダウンロードできたら実行し、インストールを開始できます。画面の指示に従ってインストールしましょう。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/9666ace2-1531-d1b7-24a5-c2d5ade3ddef.png" width=60%>

##ipアドレススキャン
Advanced IP Scannerをインストール後、起動すると次のようなウィンドウが表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/0b7226bb-8044-b268-a1fa-a6d83b4c6382.png" width=60%>

左上の「スキャン」を押すと同じLANに接続されている機器の情報を取得できます。LANに、起動中のZedBoardがつながっていることを確認したらこれを実行します。（少し時間がかかる場合があります。）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/1523007e-1dc1-024b-df51-95dacb7b4dd3.png" width=60%>


どんな機器がLANに繋がっているかによって結果は変化しますが、上の画像のように検出できるかと思います。
製造者が「Xilinx」となっている行の情報がZedBoardに関する情報となります。
その行の、「IP」列にあるipアドレスがZedBoardのipアドレスです。画像の場合であれば192.168.1.5が該当します。
（もしZedBoard以外にXilinx製の機器がLANに繋がっている場合この限りではありませんが、FPGA初心者の方であればすでに別のFPGAをつないでいる、あるいはよほど特殊なものをLANに繋いでいるなどの心当たりがなければおそらく大丈夫です。）

#6. ssh
##sshでログイン
得られたipアドレスを使ってZedBoardにsshでログインします。powershellを開き

```ssh root@192.168.1.5```

と打ち込みます。今回は192.168.1.5が得られたのでこのように入力していますが、LANの状況によってどんなipアドレスが得られるかは変わってくるので適宜変更してください。

実行すると下の画像のように「今までに接続したことないipアドレスだけど大丈夫？」といったことを聞いてくることがあります。ここではyesと入力し続行します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/1f98bd3b-1d13-1ed1-b5ec-1b6ed791a8c4.png" width=90%>

パスワードを聞かれます。rootと入力し続行します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/80cc72d6-3d29-eb97-3860-bb52025f13c0.png" width=90%>

ログインに成功すると下の画像のようになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/0b919957-6e42-454d-d11c-e799c2f2b558.png" width=90%>

これでZedBoardに入ることができました。
（ユーザー名、パスワードがそれぞれroot,rootとなっており比較的メジャーなものであるため、セキュリティを考えて後で変更しておくといいかもしれません。）

##実行ファイルの起動
先ほどSDカードにコピーしたファイルは```/mnt/```に入っています。
```cd /mnt/```を実行してここに移動します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/6cf75a4e-a758-5c7b-f323-39fd47bae9ee.png" width=90%>
上の画像のように、移動した後```ls```で中身を確認すると、確かに先ほどコピーしたファイルが入っていることがわかります。実行ファイルsample.elfを起動します。
```./sample.elf```
と打ち込んで実行してみます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/40fb0bac-fd35-bf88-dc4e-f42ed221da48.png" width=90%>

だいたい上の画像のようになればZedBoard上でのsample.elfの実行が成功していることになります。ここまでお疲れさまでした。

#再度接続するときの注意点
* 一度ZedBoardの電源を落として、もう一度起動したりするとipアドレスが変わることがあります。
* 2回目以降ZedBoardにsshしようとすると以下のように表示され、接続に失敗する場合があります。<br>
     <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584592/ce7ca313-3d74-5847-ca10-42a5bfb21c13.png" width=90%>

    * SSHでは初回接続時に接続先ホストの公開鍵を保存しておき、次回接続時にホスト鍵を比較して前回と同じホストに接続したかを確認するような仕組みになっています。そのため、IPアドレスの振り直しなどでホスト鍵が変わってしまった場合、次のようなエラーメッセージが出てSSH接続が失敗してしまいます。<a href="https://qiita.com/hnw/items/0eeee62ce403b8d6a23c">(参考)</a><br>この場合は例えば接続したいipアドレスが192.168.1.5であった場合、<br>```ssh-keygen -R 192.168.1.5```<br>と打つことによって鍵の情報をリセットでき、再度接続できるようになります。

#参考
* https://qiita.com/hnw/items/0eeee62ce403b8d6a23c