解決策にはさまざまなバリエーションがあるため、かなり複雑な問題です。この部分は ug871 の第 2 章で説明されていますが、残念ながら Vivado ではなく EDK が使用されています。ただし、Vivado HLS の概念は同じです。xapp890もご覧ください。
基本的に、Zynq は AXI ポートを使用して PL に接続します。AXI ポートは従来のアドレス + データ バスです。AXIには、スタンダードとライトの2種類があります。ライト バージョンはバーストをサポートせず、パフォーマンスを犠牲にしてより少ない領域を使用することに重点を置いており、通常はレジスタ インターフェイスに使用されます。標準の AXI は非常に高性能で、バーストをサポートします。通常、これを使用して DDR メモリに接続します。
Zynq には、マスターとスレーブの両方として複数の AXI ポートがあります。スレーブ ポートにより、IP は Zynq のメモリ空間に読み書きできます。マスター ポートにより、Zynq はコアのメモリ空間に対して読み取り/書き込みを行うことができます。いくつかのポートはパフォーマンスが異なります。GP は低パフォーマンスの AXI-Lite に使用する必要があり、HP から IP へは Zynq DDR メモリにより直接アクセスする必要があります。
IP を接続する最も簡単な方法は、AXI-lite を使用することです。Vivado HLS では、レジスタ a をアドレス 0 に、レジスタ b をアドレス 4 に、レジスタ c (答え) をアドレス d に定義します。関数 add は次のようになります。
int add(int a, int b)
{
volatile int *my_ipaddr = MY_IP_BASEADDR; // Address is configured in Vivado block design
*(my_ipaddr+0) = a;
*(my_ipaddr+1) = b;
return *(my_ipaddr+2);
}
Vivado HLS を使用していないため、その方法がわかりません。しかし、ug871 をざっと読むと、AXI-Lite レジスタ インターフェイスがカバーされています。
AXI の 3 番目のタイプは、AXI-Stream と呼ばれます。これはアドレスのない通信バスであり、ストリームを同期するためのいくつかのフラグを持つデータのみが存在します。通常、アドレスをあまり気にしないコア間または AXI-DMA エンジンで使用されます。主な問題は、AXI-Stream を Zynq に直接接続できないことです。
サンプル アプリケーションは xapp890 ですが、ビデオ アプリケーションであるため Video-DMA コアを使用しています。より高性能なソリューションを提供します。あなたの例では、a/b を受信する入力スレーブ AXI-Stream と、c を返す出力マスター AXI-Stream があります。コアを AXI-DMA IP コアに接続すると、擬似コードは次のようになります。
void add(int *ab, int *c, unsigned int length)
{
XAxi_Dma_Start_Transfer((void *)ab, length, CHANNEL_MM2S); // Not actual function, MM2S stands for memory to stream
XAxi_Dma_Start_Transfer((void *)c, length, CHANNEL_S2MM); // S2MM = stream to memory
while(XAxi_Dma_Transfer_Done == 0) {} // Wait end of transfer
}
これは多くの情報ですが、アプリケーション ノートを理解するのに役立つことを願っています。要約すると、IP は、Zynq AXI ポートに接続するデータを交換するための AXI (Lite、Standard of Stream) インターフェイスを提供する必要があります。さらに、IP は割り込み信号を持つこともできます。