XilinxのベンダーIPをMATLAB/Simulink/HDLCoderに取り込む方法

# はじめに
MathWorks社のHDL Coderを使うことで、SimulinkモデルからVerilogHDL／VHDLを生成しFPGAの実装まですることが出来ます。

HDL Coderが対応しているFPGAは[このページ](https://jp.mathworks.com/help/hdlcoder/gs/language-and-tool-version-support.html)に載っているのですが、各FPGAに載っているベンダーIPがフルに使えるわけではなく、一部のIPについてはカスタムボードの設定が必要のようです。
ここらへんの情報(特にPS+PL部を動かす場合)があまりネット上に転がっていない上に、公式ドキュメントにもあんまり明記されていないようなので、やり方を備忘録がてら記載します。

そこで、この記事では、Xilinx社のSoC ZC702のXADCの取り込みを例に下記の順番で実装手順を解説します。

- 前提となる知識
- 開発環境の構築方法
- 具体的な実装手順
- 動作確認

本記事ではZC702ですが、ゆくゆくはほかのFPGAのカスタム手順も追加出来ればなあと思っております。

## 開発環境
開発環境はこの記事を書いている時点で最新のバージョンであるMATLAB R2023bを入れています。
また、サポートパッケージとしてHDL Coder Support Package for Xilinx Zynq Platformを入れています。

- OS: Windows 11
- MATLAB: R2023b
    - MATLAB
    - Simulink
    - MATLAB Coder
    - Fixed-Point Designer
    - HDL Coder
        - HDL Coder Support Package for Xilinx Zynq Platform
- Xilinx Vivado 2022.1


HDL CoderはSimulinkの中で作成したサブシステムから、FPGAに搭載するサブシステム、CPUに搭載するサブシステムを指定し生成します。それぞれインターフェイスが用意されたひな形（リファレンスデザイン）が用意されており、そこにソフトウェア・ユーザロジックはめ込むイメージです。そのため、インターフェイスをわざわざ作ることなく設計をすることが出来ます。

![HDLCoder_to_SoC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/1117c275-cc8f-77e1-4fea-b573ebd3daf9.png)

しかし、逆に言うとリファレンスデザインに含まれていないベンダーIPを含むシステムは生成することが出来ません。そこで、リファレンスデザインのカスタマイズを行います。

リファレンスデザインのカスタマイズは、まずFPGA側のリファレンスデザインのカスタマイズを行います。続いて、その内容をCPU上Linuxに知らせるためDeviceTreeの作成を行います。
それぞれ、FPGAのリファレンスデザイン作成についてはPL側イメージ作成編、デバイスツリー作成についてはPS側イメージ作成編で解説します。

今回はZC702にXADCコアを追加して取り込んでみます。イメージは下記の図のようになります。

![old_to_new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/1b6194d4-5307-a4f0-767b-689037289867.png)

## PL側イメージ作成編
本記事では、ベンダーIPの例としてXilinxのADコンバータであるXADCを取り込み、SimulinkからHDLのコード生成をする際に叩けるように設定してみます。
そのためには、2つのファイルが必要になります。
- Vivadoでの「リファレンス設計」ファイル
- HDL Coder用「ボード登録」ファイル

ボード登録ファイルよりリファレンス設計ファイルを参照することで、連携させることが可能です。

### Vivadoでの「リファレンス設計」ファイル作成編
MATLABにはサポートパッケージというものがあり、リファレンスとなるデザインが簡単にインストール出来るようになっています。このデフォルトのリファレンスデザインを拡張し、XADCのコアを追加します。

まず、MATLABのアドオンマネージャからHDL Coder Support Package for Xilinx Zynq Platformをダウンロードします。
![supportpackage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/3242dace-76d8-f1ea-b6c9-a599821e8971.png)

### HDL Coder用「ボード登録」ファイル作成編
HDL Coder Support Package for Xilinx Zynq PlatformにおけるZC706ボードのリファレンスデザインを拡張します。まず、ZC706のVivadoのデザインファイル（拡張子xpj）を開きます。

そこから、下記のようにXADCへアクセスするためのIPを追加します。

![added.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/a11c2903-518f-0008-338c-4a206631f35c.png)

追加するIPはXADC WizardのIPを追加します。
Wizardでの設定は下記の通りです。

![Setting1png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/23e5f658-d148-9c66-5482-ff04e6414533.png)
![Setting2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/d1e1e2c2-3d5b-dab8-a825-7f798581d6ff.png)
![setting3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/a45227b7-5c09-30de-eaff-57e07c86d7a4.png)
![setting4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/81784a58-0de4-dafa-256d-0d008de30109.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/447b68c7-ebb9-b628-6b7d-c38990e5fa66.png)


WizardでのXADCの追加が完了したら、AXI Interconnectへ接続します。

参考：
[Zynq XADCの使い方](https://qiita.com/gepi/items/171fe474970c05359679)
[Testing input voltage on Xilinx zynq-7020 Z-turn by XADC](https://www.youtube.com/watch?v=QfjBP9KT5lo)
[7シリーズFPGAおよびZynq-7000 SoC XADCデュアル12ビット1MSPSアナログ-デジタルコンバーター](https://docs.xilinx.com/v/u/ja-JP/ug480_7Series_XADC)

レジスタのアドレスの設定は下記のように行います。
XADC用のAXIインターフェイスと、HDL Coderから接続するためのインターフェイスを用意します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/91d47fa7-10c2-7c47-418f-f4ebe6d18cc4.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/8bd2ddb5-1e1a-2331-7cf0-e31e3df528c8.png)

続いて、XADC IPからペリフェラルのピンアサインを行います。まず、外部ポートを作成し、XADC IPのうちVaux0とVaux8に接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/f102836f-73d3-c74d-a767-783dda367b03.png)

作成した外部ポートに物理ピンをアサインします。先ほど作成した、Vaux0とVaux8に加え、デフォルトで用意されるVnVpも赤枠内に表示されていると思います。
赤枠で囲んだ通り、ピンアサインを行うため、Package PinとBankの値を設定します。

これらの値はデータシートより確認することが可能です。「xilinx zc702」等でググることでXilinxのドキュメントページが出てきますので、その中を覗いてみると回路図のデータシートからピンの番号・バンクを確認することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/1f38d535-10f8-f362-f64b-6e2c9b7acbb6.png)

また、そのピンの接続先のピンヘッダも確認することが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/ae5cbe9d-8785-1fff-3814-89e569a15e36.png)

XDCファイルに下記の情報を書き込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/0d2b299d-ee28-3a47-af20-6aed6614c310.png)

モデルのエクスポートを行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/bae7ee3f-2727-67a3-522c-a998dfe18728.png)

### HDL Coder用「ボード登録」ファイル作成編
ボード登録ファイルは４つのファイルから構成されます。
下記のフォルダ構成にしてそれぞれのファイルを配置してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/1f71213c-bd14-b20e-21cb-3ab7397cff4d.png)

各ファイルの記述は下記のとおりにしました。
BoardNameはほかと区別出来る名前を付けてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/af00d08b-46cf-3ef1-7b9b-cf56887fa5c9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/08476d76-3f32-61ba-eb55-592c1ebef329.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/fd16079b-40c5-b282-1e0f-14e97d20c096.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/daf09086-73f6-f7bc-ab1a-774480e6b938.png)

ここまでできれば取り込みが出来ます。上手くいっていればHDL Coderのワークフローアドバイザーにおけるターゲットプラットフォームから下記の通り自分の追加したカスタムデザインの選択肢が出るはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569326/e0b15f8c-ef3d-521a-a8dc-4a4a7694b450.png)


続いて、次回はPS側のイメージを作成する手順について解説出来ればと思います。
<!-- 

### XADC動作確認編
## PS側イメージ作成編
### 環境構築編
### デバイスツリー作成編
### 動作確認編

-->

##### 更新履歴
2023/11/20 初版