1500円ZYNQ基板でFPGAプログラミング大全Xilinx編(第2版)の実習 7-2 文字表示回路の IP 作成 / 7-3 実機確認

#はじめに
1500円 ZYNQ 基板(EBAZ4205)で、
FPGAプログラミング大全Xilinx編(第2版)の課題7-2
「文字表示回路の設計とIP作成」
と、課題7-3
「実機確認」
を実習したいと思います。

#プロジェクトの概要
ZYNQ の PS(ARM) に接続するテキスト VRAM を作り、HDMI で画面出力する、というのがプロジェクトの概要です。

設計については、大全で解説されている通りです。

・文字表示回路の IP パッケージ作成までが前半の作業
・回路デザインを作成して、ARM プログラムで文字を表示するまでが後半の作業

になっています。

EBAZ4205 からの HDMI 出力には、
[1500円ZYNQ基板でFPGAプログラミング大全Xilinx編(第2版)の実習 2-3 HDMIでパターン表示](https://qiita.com/kan573/items/44ced51037d221a4d171#hdmi-%E5%87%BA%E5%8A%9B%E3%81%AE%E6%8E%A5%E7%B6%9A%E5%9B%B3)
で作成した HDMI 出力端子(ケーブル)を使用します。
![22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/35f17aa4-bc36-bbf1-c9ac-83a36b159be4.jpeg)


#プロジェクト作成と VRAM の生成
p.306 【7-2-3】プロジェクトの作成と VRAM の生成
の手順に沿って進めます。

##1. プロジェクトの準備
\XilinxFPGA_SE\Cora_Z7-10\dai7sho\chardisp
を、フォルダごとデスクトップにコピーして、Vivado の作業フォルダとします。

フォルダの中にある、chardisp.xdc と chardisp.tcl は削除しておきます。
EBAZ4205 用の制約ファイル chardisp_ebaz4205.xdc を新規作成します。

```chardisp_ebaz4205.xdc
# EBAZ4205 constraints file
# chapter: 7
# project: chardisp

#HDMI TX
set_property -dict { PACKAGE_PIN D20   IOSTANDARD TMDS_33  } [get_ports { HDMI_CLK_N }];
set_property -dict { PACKAGE_PIN D19   IOSTANDARD TMDS_33  } [get_ports { HDMI_CLK_P }];
set_property -dict { PACKAGE_PIN B20   IOSTANDARD TMDS_33  } [get_ports { HDMI_N[0] }];
set_property -dict { PACKAGE_PIN C20   IOSTANDARD TMDS_33  } [get_ports { HDMI_P[0] }];
set_property -dict { PACKAGE_PIN A20   IOSTANDARD TMDS_33  } [get_ports { HDMI_N[1] }];
set_property -dict { PACKAGE_PIN B19   IOSTANDARD TMDS_33  } [get_ports { HDMI_P[1] }];
set_property -dict { PACKAGE_PIN H17   IOSTANDARD TMDS_33  } [get_ports { HDMI_N[2] }];
set_property -dict { PACKAGE_PIN H16   IOSTANDARD TMDS_33  } [get_ports { HDMI_P[2] }];

#L6 : CLK_N: H17 → D20
#L7 : CLK_P: H16 → D19
#L8 :  N[0]: D20 → B20
#L9 :  P[0]: D19 → C20
#L10:  N[1]: B20 → A20
#L11:  P[1]: C20 → B19
#L12:  N[2]: A20 → H17
#L13:  P[2]: B19 → H16
```

あと、
\XilinxFPGA_SE\COMMON
も、フォルダごとデスクトップにコピーしておきます。
これは後で使う HDMI_VGA の IP になっています。

##2. プロジェクトと IP パッケージの作成
Vivado を起動したら、Create Project でプロジェクトを作成します。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/e3600ab0-91e9-fc6e-0731-aed366ed2d05.png)

Default part は xc7z010clg400-1 を選択。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/92c6e317-e0e2-2317-b63f-f5e69d2537a9.png)


chardisp プロジェクトが開いたら、
Tools → Create and Package New IP...
を開きます。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/98e2f424-3fbd-1a8f-5488-344e82ce0cfb.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/36dd2c7b-fb12-3b4e-8d80-cfe0a9212ae9.png)

p.307, p.308 の通りに設定を進めると、edit_ip_project の画面になります。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/a8a72bea-47cf-32b4-2401-6896f9bcc50e.png)

p.309-p.316 の通りに VRAM を作成します。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/2b9536f9-1ff8-fa55-34ae-6262e098f31e.png)

p.317-p.320 の通りに CGROM を作成します。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/eb767b37-e2aa-3359-d97b-c6d9bc7876d8.png)

File Groups で登録されたファイルを確認して、Synthesis (9) になっていれば完成です。
VRAM が登録されない時は、p.315 の不具合対策を実施してみてください。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/8f113c29-f158-f248-49be-912eb10c762e.png)

私はそれでも治らなかったので、VRAM を再度作成したら登録されました。
フォルダ名が VRAM_1 になっているのはそのためです。

全ての問題が解決したら、Review and Package から Re-Package IP を押して IP パッケージの作成を完了します。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/9699dc6a-89ac-05d5-c962-90ef9bde0f3e.png)

edit_ip_project が閉じられ、chardisp プロジェクトに戻ります。
シミュレーションは省略して、システムの構築と動作確認に移ります。


#システムの構築
p.327 【7-3-2】システムの構築と動作確認
に沿って進めます。
EBAZ4205 専用の部分が必要ですので、順に説明します。

##1. HDMI_VGA の IP カタログへの登録
chardisp プロジェクトが開いているところで、
PROJECT MANAGER → Settings から IP の Repository を開いて、
C:\Users\(ユーザー名)\Desktop\COMMON
を指定します。
HDMI_VGA の IP が追加されます。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/b58c8609-2061-84df-0cc4-fa82205d2e30.png)

先ほど作成した chardisp_ip も登録されているので、2 つの IP が使えるようになります。

OK を押して、IP の登録を完了します。


##2. システムの作成
最初にシステムを作成します。

素の Vivado が起動している状態で、IP INTEGRATOR から Create Block Design を選択し、Create Block Design で新規デザインを作成します。

Design name はデフォルトのままでよいです。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/d0501100-4945-f91c-6eb0-edb1894b9e28.png)

design_1 が開きますので、+ を押して ZYNQ7 Processing System を追加します。

##3. PS の設定
ZYNQ7 Processing System をダブルクリックして、PS の設定を行います。
設定内容は、
[1500円ZYNQ基板でFPGAプログラミング大全Xilinx編(第2版)の実習 5-2 Zynqシステムのハードウェア構築 - PS の詳細設定](https://qiita.com/kan573/items/3c1ca1c4cd7ff94da38c#ps-%E3%81%AE%E8%A9%B3%E7%B4%B0%E8%A8%AD%E5%AE%9A)
の通りでよいですが、一か所だけ変更します。

>FCLK_CLK0 : 50MHz → 100MHz

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/55112c36-3d0b-d512-3ff4-e9319ec2f848.png)


##4. 各 IP の追加とダイアグラムの完成
p.328 下段の手順通り、IP を追加します。
・chardisp_ip_v1_0_v1_0 と hdmi_vga_v1_0 を配置
・Run Connection Autiomation で AXI バスを接続
・chardisp_ip_v1_0_v1_0 と hdmi_vga_v1_0 の対応する入出力を接続
・hdmi_vga_v1_0 の nRST を PS の FCLK_RESET0_N と接続
・hdmi_vga_v1_0 の出力端子で Make External を実行
・出力ポート名の修正(_0 を外す)
・Validate Design でチェック

これでダイアグラムが完成しました。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/6e6f34b3-d63c-ac2a-eac0-fdd7faa0bb56.png)

##5. 上位階層の作成からエクスポートまで
p.330 の手順通り進めます。
・Create HDL Wrapper で上位階層を作成
・chardisp_ebaz4205.xdc の読み込み
・Generate Bitstream でコンパイル
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/838ee32e-3d55-8f7b-3635-be288c6c34e2.png)


問題なくコンパイルが完了したら、エクスポートします。
File → Export → Export Hardware → Platform type = Fixed で Next → Include bitstream で Next →
 XSA file name: chardisp
 Export to: chardisp.vitis
で Next → Finish

chardisp.xsa が作成され、エクスポートが完了しました。

#動作確認の準備
ワークスペースを、
C:\Users\(ユーザー名)\Desktop\chardisp.vitis
として、Vitis を起動します。

・プラットフォームプロジェクトを chardisp.xsa から作成します。out-of-date なので、先に Build Project しておきます。
・アプリケーションプロジェクトを Empty Application で作成します。
・アプリケーションプロジェクトの src フォルダに、char_test.c を登録します。
・アプリケーションプロジェクトを Build Project します。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/6c0d0cde-d8c7-84f5-17eb-ece93ad202fc.png)


#動作確認
Debug Configurations を作成して、デバッグを開始します。

chartest.c のブレークポイント指定2箇所にブレークポイントを設定します。
(char_test.c の行番号表示の左横の網部分をダブルクリックすると、ブレークポイントが設定できます)
![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/3c272d43-62c8-4e83-72ae-a393f8083502.png)

Resume ボタンを押すと、文字表示プログラムが動き出します。

最初のブレークポイントでの HDMI モニタの表示。
![18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/64e51bfa-8c3a-851f-30d2-32c6aa64a70d.jpeg)

2番目のブレークポイントでの表示。
![19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/2e638598-25e0-664d-6d9e-2624e5cc6df7.jpeg)

最後まで走った後の表示。
(1 行スクロールアップしている)
![20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/01a9d4a4-4f6b-8a4f-9a1c-eb589b55a5d2.jpeg)

無事、動作させることができました。

#一文字表示関数の動作確認
chartest.c の代わりに、disp_func.c を入れてビルドすると、
p.340【7-4-2】1文字表示関数を作成し英文字の文章を表示する
の課題解答が確認できます。

こちらは、デバッグ起動すると UART からテキスト入力を待つ状態になります。
Vitis Serial Terminal を起動して、文字を入力して Send すると、送信した文字が HDMI 出力に表示されます。
![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/d232b151-92b0-c507-a5e2-30c1332e5910.png)
![21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/ac4e221d-94ec-cb4c-807f-8e3bb7cfc730.jpeg)

Teraterm からテキストを送り込めば、改行して複数行のテキストを表示することもできます。
送信の改行コードを CR+LF にして、複数行テキストをペーストしてみてください。

#まとめ
FPGAプログラミング大全Xilinx編(第2版)の課題7-2
「文字表示回路の設計とIP作成」
と、課題7-3
「実機確認」
を EBAZ4205 で実習することができました。