PYNQ-Z1のOverlay読み込みとPythonからのFPGA PLの制御(2)
前回の「PYNQ-Z1のOverlay読み込みとPythonからのFPGA PLの制御」の続編です。前回のポストでは、Overlayのダウンロードに"/dev/xdevcfg"というデバイスファイルを叩いたり、LEDの点滅のためにmmapを直接叩いたりと非常に低レベルな処理になっていました。今回は、PYNQらしく、PythonのOverlayクラスを使ってOverlayをダウンロードし、LEDの制御もMyLEDクラスを使って、より抽象化した処理で動くようにしてみました。
Overlayクラスを使えるようにする
Overlayクラスを使ってOverlayをダウンロードするためには、カスタムOverlayのbitstreamを作った際のVivado tclファイルが必要になります。まず、カスタムOverlayのVivadoプロジェクトを開いて、Block Designを表示します。
「File > Export > Block Design..」を実行すると、Block Designをtclファイルとしてexportしてくれます。ここでは、led.tclというファイル名で保存しました。
生成した、tclファイルをPYNQのカスタムbitstreamと同じディレクトリーに保存します(/home/xilinx/pynq/bitstream)
次に、以下のPyhonコードを実行すると、Overlayクラスのインスタンス作成性時に、led.tclがパースされて、bitstreamに含まれるI/Oとそのアドレスが抽出されます。この例では、axi_gpio_0が0x41200000で識別されていることが分かります。
次に、axi_gpio_0に値を書き込むことによってLEDを制御するコードを書いて、/home/xilinx/pynq/boardにmyled.pyというファイル名で保存します。14行目のコードで、PL.ip_dictアトリビュートから、GPIOのアドレスを抽出して、mmioクラスのコンストのラクターに渡しています。これで、GPIOのアドレスの紐付けができました。
from pynq import MMIO from pynq import PL LEDS_OFFSET0 = 0 class MyLED(object): """This class controls the onboard LEDs vi axi_gpio_0. """ _mmio = None _leds_value = 0 def __init__(self): """Create a new MyLED object. """ if MyLED._mmio is None: MyLED._mmio = MMIO(int(PL.ip_dict["SEG_axi_gpio_0_Reg"][0],16),16) MyLED._mmio.write(LEDS_OFFSET0, 0x0) def set(self, value): """Turn on a LED. Parameters ---------- Value = GPIO out data Returns ------- None """ MyLED._mmio.write(LEDS_OFFSET0, value)
/home/xilinx/pynq/board/__init__.pyに最後の一行を追加しておきます。
from .led import LED from .rgbled import RGBLED from .switch import Switch from .button import Button from .myled import MyLED
これでMyLEDクラスが使えるようになりました。
Jupyter Notebookの作成
以下のように、Overlayをダウンロードして、MyLEDクラスを使ってLEDを点灯させます。
これで以下のように、カスタムOverlayを使ってLチカができます。前回のコードよりだいぶ簡潔で分かりやすなりました。
後書き
ということで、思ったより簡単にカスタムOverlayをPYNQのお作法に従って動かすことができました。PYNQにもZYBOのように安価なSDSoCのボード限定ライセンスが提供されればソフト屋さんもFPGAを使ったハードウェアオフロードが簡単にできるようになるのではと思います。PYNQのSDSoC、来ないのかな。
最近のコメント