FPGAボードのKR260でGPIOを制御してみました。
Python(PYNQ)経由でPMODコネクタからLED出力・SW入力しています。
オリジナルの基板を作り、テスト動作させた内容を紹介します。
KR260とPYNQでLチカ+SW入力してみた
AMD(Xilinx)のFPGAボードであるKR260には、PMODコネクタがあります。
GPIOとしても使用することができます。
専用の基板を作成して、LED出力・SW入力をしてみました。
実際のテスト動画は下記です。
ipynbファイルから制御できていることが分かります。
基板の回路図・AWや、FPGAのプロジェクトの作成まで一から紹介してきます。
KR260のUbuntu環境
今回のKR260の環境は、下記記事で紹介したコンテストの環境です。
詳細を確認したい方は、各リンク先・また下記のメインプロジェクトを参考ください。
https://www.hackster.io/iotengineer22/360-object-detection-robot-car-bdb1bd
また今回コンテストのリファレンスである下記のセットアップが前提となっています。
下記GitHubの手順を沿うことでKR260上のUbuntuの開発環境(PYNQ,ROS)が整います。
https://github.com/amd/Kria-RoboticsAI
最低限のセットアップ
もしリファレンスのセットアップが面倒だよという方は下記手順でいけると思います。(多分)
KR260用のUbuntu 22.04をダウンロードしてSDに書き込みます。
https://ubuntu.com/download/amd
iot-limerick-kria-classic-desktop-2204-x07-20230302-63.img.xz
あとは何時ものKriaのセットアップと、リポジストリのスクリプトを走らせます。
困ったらリポジストリのReadmeを読んでください。
1 2 3 4 5 6 7 |
sudo su sudo snap install xlnx-config --classic --channel=2.x xlnx-config.sysinit reboot git clone https://github.com/amd/Kria-RoboticsAI.git sudo sh Kria-RoboticsAI/files/scripts/install_update_kr260_to_vitisai35.sh |
回路図とAW(アートワーク)
PMODに接続した、基板の回路図とAWのデータはGitHubに置いています。
KiCadで作成しています。
https://github.com/iotengineer22/PCB-KV260-PMOD-TEST
直接PMODコネクタに接続するために、2.54mmピッチのピンヘッダーを使っています。
回路図は下記です。
AWは下記です。
宣伝にもなりますが、この基板はPCBGOGOにて作成しています。
VivadoでKR260のプロジェクトを作る
Vivadoを開いて、プロジェクトを作成していきます。
Create Project
「Create Project」→適当な名前つけて進めていきます。
Project Typeでは、デフォルトのRTLにしておきます。
Default Partでは、Boardを選択してKR260を選びます。
Create Block Design
Projectファイルが出来上がります。
Create Block Designを選択して、ブロックのデザインを進めます。
Diagramの「+」箇所から、Zynq UltraScale+ MPSoCを選びます。
Diagramの「+」箇所から、GPIOのIPを選びます。
Run connection Automationをクリックして、デフォルトでOKを選択します。
リセットやAXIなどのIPが勝手に配置されます。
更新ボタンのような「Regenerate Layout」をクリックすると綺麗に配置されます。
同様にGPIOのIPを1個追加します。2個用意して出力用と入力用でIPを分けておきます。
GPIOの名前も、IPの番号に合わせておきました。
- axi_gpio_0→gpio_rtl_0
- axi_gpio_1→gpio_rtl_1
GPIOのIPを編集します。デフォルトだとGPIOが32本のバスになっています。
今回は各IPでOUTPUT3本とINPUT1本で使いますので、GPIO Widthを設定しました。
またAll outputs ,All inputs にもチェックを入れています。
Create HDL Wrapper
Sourceのデザインを右クリックして、Create HDL Wrapperします。
何かoptionsのウインドウが出るかもしれませんが、デフォルトで進めます。
IPブロックのデザインから、入出力につながるHDLが作られます。
作られたファイルを確認すると,各GPIOからのoutput,inputが確認できます。
XDCファイルを作成する
ピンアサインをしていきます。
Constrainsの箇所で右クリックしてAdd Sorucesから設定します。
Create FileでXDCファイルを追加します。
今回はPMOD4の1ピン(AC12)、3ピン(AD12)、5ピン(AE10)、7ピン(AF10)を設定しています。
- 入力…7ピン(AF10)
- 出力…1ピン(AC12)、3ピン(AD12)、5ピン(AE10)
1 2 3 4 5 6 7 8 9 |
set_property PACKAGE_PIN AC12 [get_ports gpio_rtl_0_tri_o[0]] set_property PACKAGE_PIN AD12 [get_ports gpio_rtl_0_tri_o[1]] set_property PACKAGE_PIN AE10 [get_ports gpio_rtl_0_tri_o[2]] set_property PACKAGE_PIN AF10 [get_ports gpio_rtl_1_tri_i[0]] set_property IOSTANDARD LVCMOS33 [get_ports gpio_rtl_0_tri_o[0]] set_property IOSTANDARD LVCMOS33 [get_ports gpio_rtl_0_tri_o[1]] set_property IOSTANDARD LVCMOS33 [get_ports gpio_rtl_0_tri_o[2]] set_property IOSTANDARD LVCMOS33 [get_ports gpio_rtl_1_tri_i[0]] |
Bitstreamを作成
Generate Bitstreamのファイルを作成します。エラーなければ作成できます。
プロジェクトの~.runs/impl_1/あたりにbitファイルができます。
今回筆者の場合は「~/kr260-gpio-test/kr260-gpio-test.runs/impl_1」でした。
hwhファイルを作成
ハードウェアの情報が入っている.hwhファイルも必要になります。
Bitstreamを作った後に下記例のプロジェクトフォルダにあるはずです。
~/kr260-gpio-test/kr260-gpio-test.gen/sources_1/bd/design_1/hw_handoff
.hwfファイルは必ず、名前をBitstream.bitを合わせて名前変更しておきます。
下記のように合わせておきました。KR260に.bitと.hwhファイルを転送します。
- design_1_wrapper.bit
- design_1.hwh→design_1_wrapper.hwh
Jupyter Notebook
Kria-PYNQのJupyter Notebookから使って、GPIOを制御します。
KR260にはLANケーブルがあるので、LANで繋げてブラウザ経由で編集していきます。
インストール後にifconfigなどでIPアドレスを確認します。
今回筆者の場合IPアドレスは「192.168.11.7」でした。
Webブラウザ(筆者の場合はChrome)で「http://192.168.11.7:9090/」と入力します。
Jupyter Notebookが表示されます。ディレクトリ位置は下記です。
/home/root/jupyter_notebooks/
フォルダを作成して、実行する.ipynbとVivadoで作成した.bitと.hwlを置きました。
ipynbファイル
今回筆者が作成・実行したipynbファイルは下記です。
AxiGPIO
Vivadoで作成した(.bit)ファイルを読み込んだ後にAXI-GPIOのIPを制御しています。
PYNQのライブラリにAXI-GPIOがあります。
AXI-GPIOの操作方法の公式は下記です。
https://pynq.readthedocs.io/en/latest/pynq_package/pynq.lib/pynq.lib.axigpio.html#pynq-lib-axigpio
ipynbの3つ目の手順です。
AxiGPIOをインポート→GPIOのIPを指定→channel1を指定しています。
1 2 3 4 5 6 7 8 |
from pynq import Overlay from pynq.lib import AxiGPIO ol = Overlay("/root/jupyter_notebooks/pynq-gpio/send-kr260-gpio-test/design_1_wrapper.bit") gpio_0_ip = ol.ip_dict['axi_gpio_0'] gpio_1_ip = ol.ip_dict['axi_gpio_1'] gpio_out = AxiGPIO(gpio_0_ip).channel1 gpio_in = AxiGPIO(gpio_1_ip).channel1 |
LED出力の箇所はWriteしています。ipynbの4~7つ目の手順です。
今回2出力(2bit)のため、0x3→0x2→0x1→0x0 とLEDを点灯・消灯させました。
1 2 |
mask = 0xffffffff gpio_out.write(0x3,mask) |
SW入力の箇所はReadしています。
SW押している時は「1」が、押していないときは「0」が確認できます。
1 |
gpio_in.read() |
for文で3つのLEDを順番に点灯させています。
1 2 3 4 5 6 7 |
import time mask = 0xffffffff for i in range(3): for num in range(8): gpio_out.write(num,mask) time.sleep(1) |
まとめ
FPGAボードのKR260でGPIOを制御してみました。
Python(PYNQ)経由でPMODコネクタからLED出力・SW入力できました。
今回のKR260で実施した内容は、下記記事で紹介したテストの一部です。
コメント