1500円ZYNQ基板でFPGAプログラミング大全Xilinx編(第2版)の実習 5-2 Zynqシステムのハードウェア構築

#はじめに
1500円 ZYNQ 基板(EBAZ4205)で、
FPGAプログラミング大全Xilinx編(第2版)
の実習を続けます。

3 章「論理シミュレーションによる事前確認」
4 章「ロジックアナライザによる回路デバッグ」
は、基板が無くても実習できるので飛ばします。

今回は、
課題5-2「Zynq システムのハードウェア構築」
を実習したいと思います。


#基板の違い (Digilent vs EBAZ4205)
大全で解説されている Digilent 社の各基板と EBAZ4205 では、PS の外部 I/O ピンの接続が大きく違っています。
これがデザインに与える影響を説明します。

ZYNQ は、内部に ARM プロセッサと周辺回路(まとめて PS と呼ばれる)を搭載しているのが大きな特徴となっています。
要するに CPU がそのまま乗っていますが、I/O ピンは直接外には出ていません。
必要な機能の I/O ピンだけを選んで、PS_MIO ピンに割り当てるようになっています。

CPU 周辺回路の全 I/O 数と比べて、ピン数は限られているので、使わない機能は I/O ピンを出さずに放置する事になります。

ピン選択肢が沢山ある、多機能マイコンと同じやり方です。

#PS の外部 I/O ピン = PS_MIO
PS から外部に引き出せる I/O ピンは、PS_MIO0～53 の 54 本あります。
(DDR 関連ピンは除く)

PS の機能ブロックが持つ I/O のうち、どれを実際に PS_MIO ピンに割り当てて外に出すかは、Vivado の IP インテグレータで設定します。
その設定で PS_MIO のピン配置が決まり、回路図で配線を引く素になります。

Digilent 社の基板では、基板に合わせて PS_MIO を設定したファイルが用意されているので、自分で設定することはありません。
しかし、EBAZ4205 では、PS_MIO の設定を自分で作らないといけません。
ZYNQ を搭載した基板を自分で設計するときは、必ず必要になる作業ですので、マスターしておいて損は無いかと思います。


#PS_MIO の現状確認
EBAZ4205 の回路図から読み取った PS_MIO のピン割り当てと接続先を、表にしてみました。
54 本の PS_MIO ピンがすべて引き出されているわけではなく、NC になっているピンがあります。
(BGA 下のパッドから、どこにも接続されていないので、ジャンパで配線を引き出すことができない)
実際に部品が搭載されているのは、さらにごく一部です。
色のつけてあるセルが、実際に使用している機能です。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/8528e836-626b-b920-0a0b-b4770cac6699.png)


#PS_MIO の割り当て

PS_MIO には 2 つの BANK があります。
・PS_MIO0～15 が含まれる BANK500
・PS_MIO16～53 が含まれる BANK501

##BANK500
BANK500 は、主にブートデバイスを接続するための BANK です。
NAND/QSPI/SD などが接続できます。
(QSPI など省ピンのブートデバイスを選んだ場合、他の機能の I/O も割り当てられる)

EBAZ4205 では、1Gbit の x8 NAND メモリが接続されています。
私の基板では Winbond W29N01HVSINA が乗っていますが、他メーカー品が乗っている基板もあるようです。

##BANK501
BANK501 は、各機能ブロックの I/O ピンを自由に割り当てられる BANK です。
自由とはいっても、決められた機能の中から選択する形です。
(多機能マイコンと同様)

UG585 の表 2-4 に、PS_MIO 各ピンへ割り当てられる機能の一覧があります。
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/641a2c79-a224-4c09-9ef1-1e901906b4d4.png)


EBAZ4205 では、UART1 と microSD が、とりあえず必要な I/O です。
microSD は、Petalinux などの起動デバイスとして使用できます。
UART1 は J7 へ出ているので、USB-UART でシリアルコンソール接続に使います。

#PS_MIO の割り当て(追加)
I2C とか SPI も、とりあえず PS_MIO に引き出しておくと、後で自作回路につなぐのに使えます。
EMIO に割り当てて、内部的に PL 側へ出すこともできます。

検討の結果、下記の PS_MIO 配置としました。
水色のセルが、新規に機能を割り当てる PS_MIO ピンです。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/f69ed3d0-f79d-4390-16cc-78730ad9b75a.png)


#PS_DDR の検討
PS_DDR ピンは、ARM のメインメモリとして使用される DDR メモリを接続する端子です。
PS_MIO ピンと違い、接続する DDR メモリの信号は決まっています。
搭載するメモリの種類や量により、接続されない信号もあります。

ZYBO Z7 では 1GB、Cora Z7 では半分の 512MB の DDR3 メモリが搭載されていました。

EBAZ4205 では、2Gbit 128M x16 (= 256MB) の DDR3 メモリが搭載されています。
EBAZ4205 は Cora Z7 の半分の 256MB しかありません。コストダウン命。

回路図では EM6GD16EWKG-12H (Etron Technology) ですが、私の基板では Micron D9PTK (MT41K128M16JT-125)が乗っています。
PS の設定時に、メモリの型番と、データバス接続幅(x16)が必要になりますので、メモしておきます。

>型番: MT41K128M16JT-125
>接続幅: x16 (16bit)

他のブランドの DDR3 が乗っている場合も、Micron 用の設定をそのまま適用すれば良いはずです。
(DDR3 の部品バリエーションで基板を派生させて、派生の数だけ別々のブートイメージを用意するのは大変なので、同じ設定で使える DDR3 メモリが搭載されるはず)


#Vivado でプロジェクトを作成
上で検討した内容で、実際に Vivado のプロジェクトを作成します。
p.190【5-2-2】IP インテグレータによるシステム構築
を参照しつつ実施してください。

Vivado 2020.1 を起動後、

1. Create Project

2. Create a New Vivado Project で Next

3. Project Name で下記を設定
Project name: EBAZ4205
Project location: C:/Users/(ユーザー名)/Desktop/EBAZ4205_taizen

4. RTL Project かつ Do not specify sources at this time で Next
5. Default Part で
Category: All
Family: Zynq-7000
Package: clg400
Speed: -1
として、xc7z010clg400-1 を選んで Next
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/9f3b3a3b-515e-7be0-791e-2a1f9e373432.png)

6. New Project Summary で内容確認したら Finish

#IP インテグレータによるシステム構築
p.190【5-2-2】IP インテグレータによるシステム構築
を参照しつつ進めます。

1. p.190 ◎IP インテグレータの起動(図5-9)
Vivado の Flow Navigator で、IP INTEGRATOR の下の Create Block Design を左クリック。
Create Block Design で、design_1 として OK。

2. p.191 ◎Zynq PS の配置と設定(図5-10)
Diagram ペインで + を押して ZYNQ7 Processing System を選択。
Run Block Automation をクリック。
・デフォルト設定は無し
・Cross Trigger IN と OUT は、どちらも Disable のまま
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/9c24a01d-ee6f-44a6-3efb-295660b9e7af.png)

3. OK を押すと、DDR と FIXED_IO のポートが接続された ZYNQ7 Processing System ブロックが完成。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/3d8cb8b4-40e5-d720-0457-152aeba1febf.png)

ここから、EBAZ4205 専用 PS の詳細設定に入ります。


#PS の詳細設定
Diagram ペインで ZYNQ7 Processing System をダブルクリックすると、Re-customize IP のウインドウが開きます。
左の Page Navigator で設定項目を選んで、各項目を設定していきます。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/00892fec-eb8b-3d0b-4f3e-b49cd05b0430.png)

##1. PS-PL Configuration
特に設定するところありません。

##2. Peripheral I/O Pins
必須の設定は下記4点です。
1. NAND Flash を押す。data[8:15] は不要。
2. Ethernet 0 を右端の EMIO で押す。MDIO も EMIO で。
3. SD0 を Pin40-45 で押す。Card Detect は Pin34 で押す。Write Protect と Power Control は不要。
4. UART1 を Pin24-25 で押す。Modem Signals は不要。

以下は、大全の課題では使いませんが、RasPi 的に自分で回路をつなぐとき用の拡張設定です。
EBAZ4205 基板上のランドから引き出したり、DATA1, DATA2, DATA3 コネクタから引き出して使います。

5. SPI0 を EMIO で押す。
6. SPI1 を Pin46-49 で押す。SS[1] は Pin50 で押す。SS[2] は不要。
7. I2C0 を Pin26-27 で押す。
8. I2C1 を EMIO で押す。
9. CAN0 を EMIO で押す。
10. CAN1 を EMIO で押す。
11. GPIO MIO をチェック → ここまでで使われなかった MIO ピンは GPIO に割り当てられる

※UART0 は、どこにも出さないでおきます。
　Vitis IDE のターミナルがそちらに接続されてしまい、デバッグ用のコンソールが見えなくなってしまいます。
　Petalinux 等のブートイメージが完成して Vitis IDE のデバッグ環境を離れてから、UART0 を有効にする方がよいです。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/b649f6bc-1a38-ba6f-8fb7-9cd2da632d83.png)


##3. MIO Configuration
Peripheral I/O Pins で設定した内容が項目別に確認できます。

##4. Clock Configuraion
Basic Clocking ペインを開きます。
・IO Peripheral Clocks の ENET0 を、External の 100 Mbps に変更します。
・同、SDIO を 25 MHz に変更します。
・同、SPI を 200 MHz に変更します。
・PL Fabric Clocks の FCLK_CLK3 にチェックを入れて、25 MHz に変更します。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/efab2154-83c5-149e-f633-4ae7206bd6fb.png)


##5. DDR Configuration
DDR Controller Configuration を開いて、下記 2 点を変更します。
・Memory part: MT41K128M16JT-125
・Effective DRAM Bus Width: 16 bit
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/fa68da9f-699d-cfac-9225-c441d743b91d.png)


##6. SMC Timing Calculation
特に設定するところありません。

##7. Interrupts
特に設定するところありません。

##8. Zynq Block Design の確認
Zynq Block Design を開くと、設定したプロセッサ周辺回路にチェックが入っています。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/72a09d61-c2c4-dfa9-8bb7-c72c668152a5.png)

最後に、OK を押して設定を完了します。

p.192 (d) DDR とFIXED_IO のポートが接続された
と同じ状態ですが、周辺回路を追加した分、入出力のピンが増えています。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/bfa0f638-66fb-9cca-ce7a-b1d699809f8c.png)


#エクスポートまでの作業
##大全の手順をなぞる
p.192 ◎GPIOを接続(図5-11)
Default Output Value を 0x00000000 → 0xFFFFFFFF へ変更してください。
LED 出力の論理が負論理のためです。
それ以外は、大全のまま進めます。

p.195 ◎ポート名の修正(図5-13)
p.195 ◎ダイアグラムのチェック(図5-14)
p.197 ◎上位階層の作成(図5-16)
これらは全て、大全の手順をそのまま実施します。

##FCLK_CLK3 出力の追加
PS の Clock Configuraion 設定で、25 MHz クロックを追加しました。
その出力が、FCLK_CLK3 として出ています。
GPIO と同様に出力ポートを追加して、FCLK_CLK3 という名前にしてください。

#デザイン完成
完成した Diagram 図は下記のようになります。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/fdd045d5-a474-dd90-6c40-56645faed28a.png)


##制約ファイルの作成
p.198 ◎制約ファイルの読み込みとコンパイル の代わりに実施します。
ここでは、EBAZ4205 専用の制約ファイル EBAZ4205.xdc を新規作成します。

Sources ペインの Add Source を右クリックして、
Add Sources で Add or create constrains を選んで Next し、Create File で新規作成します。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/955220/675cc2fa-8c51-24a4-44cc-5089521511b2.png)


エディタが開くので、下記をコピペしてください。
前回までの .xdc の内容に、LAN で使う FCLK_CLK3 (25 MHz クロック)と、EMIO 経由で PL から出す MII のピンを追加しています。

```EBAZ4205.xdc
## EBAZ4205 constraints file
## chapter: 2
## project: ebaz4205_taizen

#Clock signal
set_property -dict { PACKAGE_PIN N18   IOSTANDARD LVCMOS33 } [get_ports { CLK }];
create_clock -add -name sys_clk_pin -period 30.00 -waveform {0 4} [get_ports { CLK }];

#Reset
set_property -dict { PACKAGE_PIN V13   IOSTANDARD LVCMOS33 } [get_ports { RST }]; # BTN[1]

# RGB LEDs
set_property -dict { PACKAGE_PIN W14   IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[2]  }]; # Red
set_property -dict { PACKAGE_PIN W13   IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[1]  }]; # Green
set_property -dict { PACKAGE_PIN U12   IOSTANDARD LVCMOS33 } [get_ports { LED_RGB[0]  }]; # Blue

# Buttons
set_property -dict { PACKAGE_PIN V15   IOSTANDARD LVCMOS33 } [get_ports { BTN[0] }];

# 25MHz Out
set_property -dict { PACKAGE_PIN U18   IOSTANDARD LVCMOS33 } [get_ports { FCLK_CLK3 }];

# EMIO PHY
set_property IOSTANDARD LVCMOS33 [get_ports ENET0_GMII_RX_CLK_0]
set_property IOSTANDARD LVCMOS33 [get_ports ENET0_GMII_TX_CLK_0]
set_property PACKAGE_PIN U14 [get_ports ENET0_GMII_RX_CLK_0]
set_property PACKAGE_PIN U15 [get_ports ENET0_GMII_TX_CLK_0]

set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_RXD_0[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_RXD_0[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_RXD_0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_RXD_0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TX_EN_0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TXD_0[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TXD_0[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TXD_0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TXD_0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports ENET0_GMII_RX_DV_0]
set_property IOSTANDARD LVCMOS33 [get_ports MDIO_ETHERNET_0_0_mdc]
set_property IOSTANDARD LVCMOS33 [get_ports MDIO_ETHERNET_0_0_mdio_io]
set_property PACKAGE_PIN Y17 [get_ports {ENET0_GMII_RXD_0[3]}]
set_property PACKAGE_PIN V17 [get_ports {ENET0_GMII_RXD_0[2]}]
set_property PACKAGE_PIN V16 [get_ports {ENET0_GMII_RXD_0[1]}]
set_property PACKAGE_PIN Y16 [get_ports {ENET0_GMII_RXD_0[0]}]
set_property PACKAGE_PIN W19 [get_ports {ENET0_GMII_TX_EN_0[0]}]
set_property PACKAGE_PIN W18 [get_ports {ENET0_GMII_TXD_0[0]}]
set_property PACKAGE_PIN Y18 [get_ports {ENET0_GMII_TXD_0[1]}]
set_property PACKAGE_PIN V18 [get_ports {ENET0_GMII_TXD_0[2]}]
set_property PACKAGE_PIN Y19 [get_ports {ENET0_GMII_TXD_0[3]}]
set_property PACKAGE_PIN W15 [get_ports MDIO_ETHERNET_0_0_mdc]
set_property PACKAGE_PIN Y14 [get_ports MDIO_ETHERNET_0_0_mdio_io]
set_property PACKAGE_PIN W16 [get_ports ENET0_GMII_RX_DV_0]

```
#コンパイル
EBAZ4205.xdc が準備できたら、Generate Bitstream でコンパイルします。


#プラットフォームファイルの Export
p.198 ◎プラットフォームファイルの Export(図5-17)
の手順をそのまま実施します。
保存先は、
C:/Users/(ユーザー名)/Desktop/ebaz4205_taizen/ebaz4205.vitis
としておきます。

これで、次章「5-3 Zynq のプログラムを実行」
を実習する準備ができました。


#まとめ
FPGAプログラミング大全Xilinx編(第2版)の課題5-2
「Zynq システムのハードウェア構築」
を EBAZ4205 で実習することができました。