【EBAZ4205(激安Zync Board)で遊ぼう】 ♯1 ハードウエアの準備
Aliexpressにて激安で販売されている、Zync-7000(xc7z010clg400-1)を搭載したマイニング用ボード「EBAZ4205」をAMDの統合環境であるVivado(Vitis)で動かしてみます。
EBAZ4205とは
2021年頃にAliexpressで1500円くらいで大量に登場した、AMD(Xilinx)のZynq-7000を搭載したマイニング用のボードです。
2025年末時点でもAliexpressで「EBAZ4205」で検索すると3000~4000円程度で販売されています。

このボード向けに作成された拡張基板(Type-Cポートからの給電とUART通信・HDMIコネクタ・カラー液晶・スイッチを搭載)も1500~2000円くらいで販売されています。

かなり便利に使えますので、このシリーズではそれを使う前提で進めていきます。
AMD FPGA用ダウンロードケーブル
FPGAのプログラミングに必要なダウンロード(JTAG)ケーブルもAliexpressで購入することができます。
小型の(多分)互換品は3500円程度で販売されています。

ハードウエア情報の入手先
EBAZ4205の回路図等は以下より入手出来ます

液晶付きのアダプタボードの回路図は以下です

EBAZ4205を使うために必要そうな資料は 筆者のGitHubリポジトリに置いておきます(随時更新)
使い始めるための準備
ハードウエアを使用するために、PLクロック入力対応や各種スイッチの追加といった基板の改造が必要となります。改造内容については@kan573氏の以下の記事を参考にさせていただきました。
(改造内容はこの記事では省略)
1500円ZYNQ基板でFPGAプログラミング大全Xilinx編(第2版)の実習 その1:準備
1500円ZYNQ基板で microSD から起動する
Vivadoでアダプタボード用ハードウエアを設計
アダプタボードを使うためのハードウエアを設計します。
今回は "Vitis Classic"を使用したいので2024.2を使用します。
(Vitis Unifiedではネットワークを使ったライブラリ(lwip)にバグがあり動かないため、Vitis Classicをサポートする最後のバージョンである2024.2を使用)
ブロックデザイン
アダプタボードのLCD制御はZynq Processor System(PS)のGPIO(EMIO)を使用します。
アダプターボードのLEDとボタン入力を行うためにAXI_GPIOを追加しています。

Processor System設定
以下はProcessor Systemの設定画面です。✔のはいっているI/O Pripheralを有効にしています。

PS-PL ConfigurationでAXI_GPIOを接続するためにPSの設定でAXI Masterを有効にします。

以下の設定はMIO Cofgigurationです。ポイントはUART設定です。
アダプタボード上のType-CへUART出力するためにUART0を追加してEMIOに出力し、これによりPCからType-Cへ接続するだけでEBAZ4205への電源供給とターミナルでのログ確認ができるようにします。

アダプタボードのLCDを制御するために5bitのGPIOをEMIOに出力します。

DDR Configurationは、EBAZ4205に搭載されているDDR3メモリに合わせて以下の用に設定します。

AXI_GPIO設定
AXI_GPIOのチャンネル1をアダプタボードのLED制御出力、チャンネル2をアダプタボードのボタン入力に割り当てます。

制約ファイル
基板改造で追加したボタン・クロック入力と、アダプタボードのピン配置情報を反映した制約ファイル(.xdc)を以下の内容で作成します。
Ether PHYへのTXD/RXDはPSからの出力は8bitですが、PHYの入力は4bitしかないので、未使用の上位4bitはPSの未接続ピンへダミーで接続しています。
## EBAZ4205 constraints file
## chapter: 2
## project: ebaz4205_extension_brd
# PL Clock (33MHz): 本記事のハードウエアでは未使用
# set_property -dict { PACKAGE_PIN N18 IOSTANDARD LVCMOS33 } [get_ports { PL_CLK }]
# create_clock -period 30.000 -name PL_CLK [get_ports PL_CLK]
# PL Reset(U67), Actie HIGH: 本記事のハードウエアでは未使用
# set_property -dict { PACKAGE_PIN V13 IOSTANDARD LVCMOS33 } [get_ports { PL_RST }]
# PL BTN(U68), Active HIGH: 本記事のハードウエアでは未使用
# set_property -dict { PACKAGE_PIN V15 IOSTANDARD LVCMOS33 } [get_ports { PL_BTN }]
# LEDs
set_property -dict {PACKAGE_PIN H18 IOSTANDARD LVCMOS33} [get_ports {LED_RGB[2]}]
set_property -dict {PACKAGE_PIN K17 IOSTANDARD LVCMOS33} [get_ports {LED_RGB[1]}]
set_property -dict {PACKAGE_PIN E19 IOSTANDARD LVCMOS33} [get_ports {LED_RGB[0]}]
# Buttons
set_property PACKAGE_PIN T19 [get_ports {BTN[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {BTN[0]}]
set_property PACKAGE_PIN P19 [get_ports {BTN[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {BTN[1]}]
set_property PACKAGE_PIN U20 [get_ports {BTN[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {BTN[2]}]
set_property PACKAGE_PIN U19 [get_ports {BTN[3]}]
set_property PACKAGE_PIN V20 [get_ports {BTN[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {BTN[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {BTN[3]}]
# UART on Type-C
set_property PACKAGE_PIN H16 [get_ports UART_0_rxd]
set_property IOSTANDARD LVCMOS33 [get_ports UART_0_rxd]
set_property PACKAGE_PIN H17 [get_ports UART_0_txd]
set_property IOSTANDARD LVCMOS33 [get_ports UART_0_txd]
# LCD Panel
set_property PACKAGE_PIN T20 [get_ports {GPIO_0_0_tri_io[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[0]}]
set_property PACKAGE_PIN R18 [get_ports {GPIO_0_0_tri_io[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[1]}]
set_property PACKAGE_PIN N17 [get_ports {GPIO_0_0_tri_io[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[2]}]
set_property PACKAGE_PIN R19 [get_ports {GPIO_0_0_tri_io[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[3]}]
set_property PACKAGE_PIN P20 [get_ports {GPIO_0_0_tri_io[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {GPIO_0_0_tri_io[4]}]
## Ether PHY
# 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]
## unused signals(dummy)
set_property PACKAGE_PIN G17 [get_ports {ENET0_GMII_RXD_0[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_RXD_0[4]}]
set_property PACKAGE_PIN G18 [get_ports {ENET0_GMII_RXD_0[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_RXD_0[5]}]
set_property PACKAGE_PIN H15 [get_ports {ENET0_GMII_RXD_0[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_RXD_0[6]}]
set_property PACKAGE_PIN M14 [get_ports {ENET0_GMII_RXD_0[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_RXD_0[7]}]
set_property PACKAGE_PIN T10 [get_ports {ENET0_GMII_TXD_0[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TXD_0[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TXD_0[4]}]
set_property PACKAGE_PIN T11 [get_ports {ENET0_GMII_TXD_0[5]}]
set_property PACKAGE_PIN T12 [get_ports {ENET0_GMII_TXD_0[6]}]
set_property PACKAGE_PIN T14 [get_ports {ENET0_GMII_TXD_0[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TXD_0[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ENET0_GMII_TXD_0[6]}]
## Clock from Ether PHY
create_clock -period 40.000 -name ENET0_GMII_RX_CLK_0 -waveform {0.000 20.000} [get_ports ENET0_GMII_RX_CLK_0]
create_clock -period 40.000 -name ENET0_GMII_TX_CLK_0 -waveform {0.000 20.000} [get_ports ENET0_GMII_TX_CLK_0]
# I/O delay(dummy)
set_input_delay -clock [get_clocks clk_fpga_0] -min -add_delay 0.000 [get_ports {BTN[*]}]
set_input_delay -clock [get_clocks clk_fpga_0] -max -add_delay 0.000 [get_ports {BTN[* ]}]
set_input_delay -clock [get_clocks ENET0_GMII_RX_CLK_0] -min -add_delay 0.000 [get_ports {ENET0_GMII_RXD_0[*]}]
set_input_delay -clock [get_clocks ENET0_GMII_RX_CLK_0] -max -add_delay 0.000 [get_ports {ENET0_GMII_RXD_0[* ]}]
set_input_delay -clock [get_clocks ENET0_GMII_RX_CLK_0] -min -add_delay 0.000 [get_ports ENET0_GMII_RX_DV_0]
set_input_delay -clock [get_clocks ENET0_GMII_RX_CLK_0] -max -add_delay 0.000 [get_ports ENET0_GMII_RX_DV_0]
set_output_delay -clock [get_clocks ENET0_GMII_TX_CLK_0] -min -add_delay 0.000 [get_ports {ENET0_GMII_TXD_0[*]}]
set_output_delay -clock [get_clocks ENET0_GMII_TX_CLK_0] -max -add_delay 0.000 [get_ports {ENET0_GMII_TXD_0[* ]}]
set_output_delay -clock [get_clocks clk_fpga_0] -min -add_delay 0.000 [get_ports {LED_RGB[*]}]
set_output_delay -clock [get_clocks clk_fpga_0] -max -add_delay 0.000 [get_ports {LED_RGB[* ]}]
set_output_delay -clock [get_clocks ENET0_GMII_TX_CLK_0] -min -add_delay 0.000 [get_ports {ENET0_GMII_TX_EN_0[0]}]
set_output_delay -clock [get_clocks ENET0_GMII_TX_CLK_0] -max -add_delay 0.000 [get_ports {ENET0_GMII_TX_EN_0[0]}]
ハードウエア情報(XSA)のEXPORT
上記の内容でボード設計をしたらBitstreamを生成し、XSAファイルをExportしておきます。
このファイルは、Vitisでソフトウエア設計を行う際のPlatform生成に使用します。
この記事の内容で作成したVivado 2024.2のプロジェクトとXSAファイルは筆者のGitHubのリポジトリに置いておきます。
ハードウエアの設定は以上になります。
参考
- 1500円の ZYNQ 基板を買ってみた (EBAZ4205, ANTMINER)
https://qiita.com/kan573/items/e951a0b2e26e19372800 - EBAZ4205 "How to Build"
https://github.com/wavelet2/EBAZ4205/blob/2023.1/docs/how-to-build.md - 筆者のGitHubリポジトリ
https://github.com/tomorrow56/EBAZ4205_tutorial/
Discussion