ZYBO Z7によるZYNQ入門 (9)AXI DMAを使用したPL-PS間のデータ転送
- (1)Vivado, Xilink SDK開発環境構築
- (2)Hello Worldプログラムによる動作確認
- (3)Ubuntu, PetaLinuxツール環境構築
- (4)ベアメタル環境のlwIPでUDP通信
- (5)PetaLinuxツールでLinuxイメージを作成
- (6)Linux環境でUDP通信(iperf)
- (7)Linux環境でUDP通信(ユーザアプリ)
- (8)Audio Codec
- (9)AXI DMAを使用したPL-PS間のデータ転送
環境
- PC: Windows 10 64bit
- Vivado 2019.1 WebPACKライセンス
- Xilinx SDK 2019.1
- Tera Term
- ボード: ZYBO (Z7-10)
- micro USBケーブル
AXI DMA
前回の(8)Audio Codecでは、ZYBOのAudio Codecを使用するため、Digilentが提供しているデモプログラムを使用しました。今回はこのプログラムでも使用されていたAXI DMAについて、Xilinxが提供しているサンプルプログラムを参考にして掘り下げます。
サンプルプログラムの概要
Xilinxが提供しているPSのサンプルプログラムAXI_DMA_bsp_xaxidma_example_sg_intr1では、PSからDDRメモリのTX_BUFFER_BASE(0x01100000)に書き込んだデータをPLのFIFOにAXI DMAで送信した後、PLからデータをDDRメモリのRX_BUFFER_BASE(0x01300000)にAXI DMAで送信します。Scatter Gatherモードで動作し、TXとRXのDMA割り込みを使用して、データが送信されたか確認しています。
今回作成するPLのブロックは、PSからAXI DMAで送信されたデータをFIFOで受信し、そのデータをループバックしてPSにAXI DMAで送信するようにしています。
DMAとは
DMAはダイレクトメモリアクセスの略で、DMAを使用するとシステムのある部分から別の部分にデータを転送できます。DMAを使用して任意のデータプロデューサー(ADCなど)からメモリに、またはメモリから任意のデータコンシューマー(DACなど)にデータを転送できます。
AXIとは
AXI(Advanced eXtensible Interface)はAMBA(Advanced Microcontroller Bus Architecture) 4仕様に基づいて標準化されたインターフェイスプロトコルです。ZYNQのPSとPLはAXIバスで接続されていますので、自作のロジックIPをCPUから制御する場合にはAXIバスに接続する必要があります。AXIには次の3種類のインターフェースがあります。
インターフェース | 概要 |
---|---|
AXI4 (Full) | フル機能のAXIで、大量のデータ転送に向いています。ただし、制御は複雑です。 |
AXI4 Lite | アドレスの転送とデータの転送とが必ず1対1で対応するという特徴があります。制御が比較的簡単であり、制御や少量のデータのやりとりに向いています。 |
AXI4 Stream | AXI4と同様に大量のデータ転送向けであり、なおかつ制御が簡単なインタフェースです。音声、ビデオなどのデータ転送に向いています。 |
AXI DMAとは
AXIバスを使用したDMAのことで、PSに接続されたDDRメモリとPL間をCPUを介在することなくデータを転送することができます。
チャネル | 概要 |
---|---|
MM2S (Memory Map to Stream) | メモリ(PS)からストリーム(PL)へのデータ転送 |
S2MM (Stream to Memory Map) | ストリーム(PL)からメモリ(PS)へのデータ転送 |
Scatter Gatherとは
散り散りになっている(scatter)メモリブロックに対して、まとめて(gather)DMA転送を行うことができます。
PL部の作成(Vivado)
プロジェクトの作成
Vivado 2019.1を起動します。Create ProjectでProject NameをAXI_DMAにします。Project Typeは RTL Projectにします。Add SourcesとAdd Constraintsでは何もせずNextをクリックします。Default PartではBoardsを選択してからZybo Z7-10を選択します。Next、Finishをクリックしてプロジェクトを作成します。
ブロックデザインの作成
Flow Navigator -> IP INTEGRATOR -> Create Block Designで、新しいブロックデザインを作成します。名前はデフォルトのままdesign_1とします。
ZYNQ7 PS
Diagramビューの+ボタンをクリックして、ZYNQ7 Processing Systemを追加し、Run Block AutomationをクリックしてOKします。
AXI DMA
+ボタン(Add IP)をクリックして、AXI Direct Memory Accessを追加します。ステータスおよび制御ポートは必要ないため、AXI DMAブロックのEnable Control/Status Streamオプションのチェックは外します。Run Connection AutomationでAXI Liteを自動配線します。
ZYNQ7 PS AXI Interface
ZYNQブロックをダブルクリックして、PS-PL Configurationを選択し、HP Slave AXI Interfaceブランチを開き、S AXI HP0 interfaceにチェックをつけて有効にします。
Run Connection AutomationでS_AXI_HP0のOptionsのMasterをM_AXI MM2Sに選択して自動配線します。
再びRun Connection Automationが表示されるので、M_AXI_S2MMとM_AXI_SGを自動配線します。
AXI4 Stream Data FIFO
+ボタン(Add IP)をクリックして、AXI Stream Data FIFOを追加します。FIFOのS_AXISポートとDMAのM_AXIS_MM2SポートおよびFIFOのM_AXISポートとDMAのM_AXIS_S2MMポートを接続します。Run Connection AutomationでFIFOのクロックを自動配線します。
ZYNQ7 PS Interrupt
ZYNQブロックをダブルクリックして、Interruptsを選択し、Fabric InterruptsとIRQ F2P[15:0]
にチェックを入れて、DMA割り込みを有効にします。
+ボタン(Add IP)をクリックして、Concatを追加します。AXI DMAのmm2s_introutをIn1に、s2mm_introutをIn0に、doutをZYNQのIQQ_F2Pに接続します。
ビットストリームファイルの作成
BLOCK DESIGN -> Sourcesタブ上で、design_1で右クリックして、Create HDL Wrapper -> OKします。
左側のFlow Navigator -> PROGRAM AND DEBUG -> Generate Bitstreamをクリックして、論理合成&配置配線を行い、ビットストリームファイルを生成します。
生成したビットストリームをエクスポートします。メニューバー -> File -> Export -> Export Hardware。Include bitstreamにチェックをつけて、OKします。
PS部の作成(Xilinx SDK)
Vivado上のメニューバー -> File -> Launch SDK -> OKで、今までVivadoで作成したハードウェア用のソフトウェア開発環境が起動します。
SDK上のメニューバー -> New -> Application Project で、新しいソフトウェアプロジェクトを作成します。
- Project name: project_1
- OS Platform: standalone
- Hardware Platform: design_1_wrapper_hw_platform_0
- Processor: ps7_cortexa9_0
- Language: C
TemplatesにはHello Worldを使用します。
XilinxのAXI DMAのサンプルプログラムを読み込むため、system.mssのaxi_dma_0のImport Examplesをクリックして、xaxidma_example_sg_intrをチェックしてOKします。
プログラムの実行
ボードの準備
ZYBOのボード上でJP5のジャンパ接続をQSPIにします。ボード上のマイクロUSB端子(J12)にUSBケーブルを刺して、PCと接続します。ZYBOの電源をONにします。
PC側でTera Termを起動して、USB Serial Portに接続します。ボーレートは115200にします。
PLプログラムの書き込み
メニューバー -> Xilinx -> Program FPGAを実行してビットストリームファイルを書き込みます。
PSプログラム実行
Project Explorer上でAXI_DMA_bsp_xaxidma_example_sg_intr1を選択しておきます。
メニューバー -> Run As -> Launch on Hardware (System Debugger)を実行すると、ターミナル上に実行結果が表示されます。
参考
Discussion