第5章,第6章
- Vitisについては2025.1と書籍の2020.1で随分と違うようなので、改めて2020.1をインストールしなおし
- 最新のツールの使い方は後日、続FPGAプログラミング大全でおさらいしたい
- https://zenn.dev/cobac/books/8c5d54ea322813
- 大きな流れは
- Vivado: IPインテグレータでブロックデザイン作成→BitStream作成→エクスポート
- Vitis: エクスポートされたデータをPlatformとして、それ上でSWを開発する
- 第5章はPS(CA9)を、第6章はMicroBrazeをそれぞれ用いて、ほぼ同様のデザインを作成する
AXI GPIO
Config
2chあるGPIOのうち1chのみを使用し、データ幅を3bit、すべてをOutputポートとしてコンフィグ。
レジスタマップ
led_test.cではAXI GPIOの0x0,0x4番地へレジスタ設定をしているため、レジスタの仕様をデータシートで確認。
https://docs.amd.com/v/u/en-US/pg144-axi-gpio
| Offset Address | Register Name | Bit Width | Access Type | Default Value | Description |
|---|---|---|---|---|---|
| 0x0 | GPIO_DATA | [GPIO_Width-1:0] | R/W | 0x0 | AXI GPIO ch1のデータ inputポートの時、ピンの値をRead可能 outputポートの時、Writeした値をピン出力 |
| 0x4 | GPIO_TRI | [GPIO_Width-1:0] | R/W | 0x0 | AXI GPIO ch1の3-state制御レジスタ 0=outputとしてコンフィグ 1=inputとしてコンフィグ |
IPをall_outputとしてコンフィグしているので、GPIO_TRIは設定しなくてもよいように思える。実際、led_test.cでGPIO_ctrl行をコメントアウトしても、同じ挙動をする。
オフセットアドレス
ユーザプログラムでは、下記のようにAXI GPIOのオフセットアドレスを参照している。
#define LED *((volatile unsigned int*) (XPAR_GPIO_0_BASEADDR + 0x00))
#define LED_ctrl *((volatile unsigned int*) (XPAR_GPIO_0_BASEADDR + 0x04))
XPAR_GPIO_0_BASEADDRは、xparameters.hに定義されている。
blink_zq\blink_zq.vitis\blink_zq_project\ps7_cortexa9_0\standalone_domain\bsp\ps7_cortexa9_0\include\xparameters.h
/* Canonical definitions for peripheral AXI_GPIO_0 */
#define XPAR_GPIO_0_BASEADDR 0x41200000
#define XPAR_GPIO_0_HIGHADDR 0x4120FFFF
#define XPAR_GPIO_0_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID
#define XPAR_GPIO_0_INTERRUPT_PRESENT 0
#define XPAR_GPIO_0_IS_DUAL 0
このxparameters.hは自動生成であり、元をたどるとBlock DesignのAddress Editorにたどり着く。ここでシステムのメモリマップを決め、xparameters.hとしてエクスポートしていると思われる。

Clock,Resetについて
- PSを使用する場合、Clock,ResetはPS自身が作成する。これを分周したクロックを最大4系統(FCLK_CLKx)PL側に出力可能。PS内蔵PLLで所望の周波数が作れない場合は、外部から供給する
- MicroBlazeの場合は、外部からClock,Resetを供給する
ZYBOのリファレンスマニュアルによると基板上のオシレータから50MHzが供給され、PSは直結、PLはEthernetPHYを通して125MHz化されたものがL16ピン経由で供給される。
##Clock signal set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { CLK }]; create_clock -add -name sys_clk_pin -period 8.00 -waveform {0 4} [get_ports { CLK }]; ##Reset set_property -dict { PACKAGE_PIN Y16 IOSTANDARD LVCMOS33 } [get_ports { RST }]; # BTN[3]
これをMMCM(Clocking Wizard)で分周して所望の周波数を得る。(第2章ではIPインテグレータを使用せず、コード上に直接MMCMをインスタンスして使用した)
https://digilent.com/reference/_detail/zybo/clock.png?id=programmable-logic%3Azybo%3Areference-manual