ZynqMP ACP と AXI をつなぐアダプタ







# はじめに


この記事では、ZynqMP のAccelerator Coherency Port(ACP) を普通のAXI マスターが接続できるようにするためのアダプタについて説明します。 


## ZynqMP ACP とは


ZynqMP には Processing System(以下PS) と Programmable Logic(以下PL) を接続するインターフェースが幾つかあります(下図参照)。

![Fig.1 ZynqMP PS-PL Interface](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/efb15059-4cf3-fd23-2983-6378681a2f58.jpeg "Fig.1 ZynqMP PS-PL Interface")

Fig.1 ZynqMP PS-PL Interface

<br />



 Accelerator Coherency Port(以下ACP) はそのうちの一つで、以下の特徴を持っています。



*  Application Proccessing Unit(以下APU)のキャッシュとコヒーレンシを維持しつつ Memory Subsystemに対してリードライト出来ます。
*  ACP は 16-byte(Data Widthの128bit)単位、または アライメントされた64-byte(APUのキャッシュラインサイズ)単位でしかアクセス出来ません。それ以外でアクセスした場合、SLVERR が返ってきます。
*  ACP は APUの ACP I/F を介して直接 APU と接続しています。そのため AXI HPC portと異なりInner Share 領域にあるので、 boot.bin に小細工をする必要がありません。 ([『UltraZed 向け Debian GNU/Linux で AXI HPC port を使う (基礎編)』](https://qiita.com/ikwzm/items/82f98bfa76922073e610)参照)


## ZynqMP ACP アダプタとは


ACP は前節で説明したように 16-byte(Data Widthの128bit)単位、または アライメントされた64-byte(APUのキャッシュラインサイズ)単位でしかアクセス出来ません。したがって通常の DMA などの AXI マスターを接続するときは、AXI マスターのほうでトランザクションサイズを調整する必要があります。

ZynqMP ACP アダプタは、ACP の転送サイズに対応していない AXI マスターをZynqMP の ACP に接続するためのものです。具体的には AXI マスターと ZynqMP の ACP の間に入り、AXI マスターからのトランザクションを ACP のトランザクションサイズに分割します。


![Fig.2 Sample Design](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/3448ed72-0fc7-086e-c758-61ec578ea8aa.png "Fig.2 Sample Design")

Fig.2 Sample Design

<br />

例えば、AXI から転送開始アドレスが0xXX-XXXX-X024で転送サイズが183Byte のアクセスがあった場合、ZynqMP ACP アダプタは下図のように6つの ACPトランザクションに分割します。  

![Fig.3 AXI Transaction to ACP Transactions](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/354de62a-7d5d-9b45-8a29-8b8bafa240ca.jpeg "Fig.3 AXI Transaction to ACP Transactions")

Fig.3 AXI Transaction to ACP Transactions

<br />



ZyqnMP ACP アダプタは以下の URL で公開しています。

*  https://github.com/ikwzm/ZynqMP-ACP-Adapter


# ZynqMP ACP アダプタの構造



## リードアダプタの構造


ZynqMP ACP リードアダプタは AXI からのリードトランザクション要求を ACPに対して中継します。その際、ACP の制限事項であるトランザクションに分割します。リードトランザクションの中継はライトトランザクションの中継と異なり、比較的簡単に行えます。

下図に ZynqMP ACP リードアダプタの構造を示します。


![Fig.4 リードアダプタの構造](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/dbc9d24a-e4a9-e8fd-9384-88a048b7a328.jpeg "Fig.4 リードアダプタの構造")

Fig.4 リードアダプタの構造

<br />

FSM (Finite State Machine 有限状態機械) は、リードアダプタ全体の制御を行います。具体的には、AXI からのリードトランザクション要求信号(AXI_RVALID信号)を受け取り、AXI_ARADDR 信号のアドレス情報と AXI_ARLEN 信号のバースト長信号から ACP へのトランザクション単位に分割して ACP_ARADDR 信号と ACP_ARLEN 信号を生成して、ACP に対してリードトランザクションを要求します(ACP_ARVALID 信号を High にします)。

ACP へのリードトランザクション要求が受け付けられる(ACP_ARREADY 信号がHigh になる) と、その旨をレスポンスキューに通知します。レスポンスキューは ACP が受け付けたリードトランザクションの数をカウントして、リードデータパスに通知します。

リードデータパスは、レスポンスキューからトランザクションの数を受け取り、ACP からのリードデータ数(ACP_RLASTがHighになった数)を数えて、最後のデータの時にAXI_RLAST 信号を High にします。


## ライトアダプタの構造


ZynqMP ACP ライトアダプタは AXI からのライトトランザクション要求を ACPに対して中継します。その際、ACP の制限事項であるトランザクションに分割します。

下図に ZynqMP ACP ライトアダプタの構造を示します。


![Fig.5 ライトアダプタの構造](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/db3aa4a1-1d30-706d-6d1a-2fb94775c367.jpeg "Fig.5 ライトアダプタの構造")


Fig.5 ライトアダプタの構造

<br />



ライトアダプタはリードアダプタに比べて少しだけ複雑です。何故なら、AXI の仕様上、AXI_WLEN信号によるバースト長だけでは正味のデータ転送量がわからないからです。(私見ですが、私はこれがAXI の最大の欠点だと思ってます。）というのも、AXI のライトデータチャネルには WSTRB 信号というのがあって、このWSTRB 信号は WDATA 信号と供に送られてきて、WDATA 信号のどのバイトレーンが有効かを示します。この WSTRB 信号を受け取って初めて正味のデータ転送量が判明します。

ACP は アライメントされた64-byte(APUのキャッシュラインサイズ)単位でアクセスする場合はそのトランザクション中の WSTRB はすべて High でなければなりません。そうでない場合は、64-byte単位でアクセスすることはできず、16-byte(1バースト長)単位でアクセスしなければなりません。

つまり、ACP のトランザクションが 64-Byte(4バースト)になるか16-Byte(1バースト)になるかは、AXI_WSTRB 信号を(最悪の場合)4バースト分ためてからでないと分からないのです。

これは、AXIからACPへのライトトランザクションのレイテンシー(遅延)が最悪４サイクル増加することを意味します。ライトアダプタを使う際は、この点に留意する必要があります。

下図にライトデータパスの構造を示します。


![Fig.6 ライトデータパスの構造](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/b0a6666f-358f-e20e-d7cd-d2fe9f2042b4.jpeg "Fig.6 ライトデータパスの構造")

Fig.6 ライトデータパスの構造

<br />



ライトデータパスには、WDATA と WSTRB を格納するための FIFO の他に、WVALID信号とWLAST 信号とWSTRB=0xFFFFであることを示すフラグを格納するためのキューがあります。このキューは先頭の４ワード分の情報が同時に取り出せる構造になっていて、この４ワード分の情報をもとにライトトランザクションのバースト長を決定します。


# タイミング図



## リードタイミングの例


下図に転送開始アドレスが0xXX-XXXX-X024で転送サイズが183Byteの例(Fig.3 の例)でのリードタイミングを示します。


![Fig.7 リードタイミング例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/2a5e24f8-13b9-8038-2086-aeb0a4df275c.jpeg "Fig.7 リードタイミング例")

Fig.7 リードタイミング例

<br />


## ライトタイミングの例


下図に転送開始アドレスが0xXX-XXXX-X024で転送サイズが183Byteの例(Fig.3 の例)でのライトタイミングを示します。


![Fig.8 ライトタイミング例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/7e8d3f61-fd01-4534-d6c2-8fb25af58c83.jpeg "Fig.8 ライトタイミング例")

Fig.8 ライトタイミング例

<br />


## マルチトランザクション


AXI プロトコルには AXI ID トランザクション識別子信号があります。AXI マスターはこの識別信号を使用して、順番に返される必要がある個別のトランザクションを識別できます。特定の AXI ID 値を持つすべてのトランザクションは順序を維持する必要があります。しかし異なる AXI ID 値を持つトランザクションの順序に制限はありません。これは単一の物理的なポートが複数の論理的なポートとして機能するためのものです。

ZynqMP ACP アダプタは、一応、マルチトランザクションに対応しています。同一の AXI ID を持つトランザクションが連続する場合は、前のトランザクションが完了する前に次のトランザクションを発行します。しかし、別々の AXI ID を持つトランザクションが連続する場合は、前のトランザクションが完了してから次のトランザクションを発行します。


![Fig.9 マルチトランザクション(同一ID)の例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/779e45ca-01a2-e6c6-62e1-24359140e7ea.jpeg "Fig.9 マルチトランザクション(同一ID)の例")

Fig.9 マルチトランザクション(同一ID)の例

<br />


![Fig.10 マルチトランザクション(別ID)の例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/6ce98224-17eb-b271-8743-714c981d239d.jpeg "Fig.10 マルチトランザクション(別ID)の例")

Fig.10 マルチトランザクション(別ID)の例

<br />



別々の AXI ID を持つトランザクションが連続する場合に前のトランザクションが完了を待ってから次のトランザクションを発行する理由は、次の図のように前のトランザクションの最中に次のトランザクションが割り込んでくる可能性があるからです。トランザクション毎に別々のバッファを持てばこのような場合に対処することが出来ます。しかし、トランザクション毎にバッファを持つのはリソース上の負担が大きいと判断して、その代わりにトランザクションの完了を待つ実装にしています。


![Fig.11 マルチトランザクション(別ID)で困ったことが起こる可能性](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/24935fed-4890-7c8a-b406-480cd5fcb206.jpeg "Fig.11 マルチトランザクション(別ID)で困ったことが起こる可能性")

Fig.11 マルチトランザクション(別ID)で困ったことが起こる可能性

<br />




# ZynqMP ACP の実測波形



## リードトランザクションの実測波形


リードトランザクション時のZynqMP ACP アダプタの AXI 側と ACP 側の波形を Integrated Logic Analyzer (ILA) で実測した結果を下図に示します。


![Fig.12 ZynqMP ACP のリードトランザクション実測波形](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/3fd36636-a4ef-6250-986e-7f8ca406dc73.png "Fig.12 ZynqMP ACP のリードトランザクション実測波形")

Fig.12 ZynqMP ACP のリードトランザクション実測波形

<br />



この波形は、AXI 側からのAddr=0x00_7010_6400、バースト長=160ワードのリードトランザクションを ZynqMP ACP アダプタが ZynqMP の ACP に対して４ワード×40回のリードトランザクションに分割して発行しているところを計測したものです。（周波数は250MHzです。）

この波形より、ZynqMP ACP はリードトランザクション要求(ACP_ARVALID=1 and ACP_ARREADY=1) から 8クロック後に最初のリードデータが出力された後、ノーウェイトで残りのワードのリードデータが出力されていることがわかります。

AXI 側のリードトランザクションは172クロックで完了しています。160ワード分(2560Byte)のリードトランザクションが688nsec(4nsec×172clock)で完了していることから、転送レートはおよそ3.7GByte/sec であることがわかります。


## ライトトランザクションの実測波形


ライトトランザクション時のZynqMP ACP アダプタの AXI 側と ACP 側の波形を Integrated Logic Analyzer (ILA) で実測した結果を下図に示します。


![Fig.13 ZynqMP ACP のライトトランザクション実測波形](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24981/66f3c5f0-d8e1-223d-d900-5564c6b34f2e.png "Fig.13 ZynqMP ACP のライトトランザクション実測波形")

Fig.13 ZynqMP ACP のライトトランザクション実測波形

<br />



この波形は、AXI 側からのAddr=0x00_7050_C800、バースト長=128ワードのライトトランザクションと Addr=0x00_7050_D000、バースト長256ワードのライトトランザクションを連続で行い、それらを ZynqMP ACP アダプタが ZynqMP の ACP に対して４ワード×96回(32回+64回)のライトトランザクションとに分割して発行しているところを計測したものです。（周波数は250MHzです。）

この波形で注目すべき点は、ZynqMP の ACP から出力されている ACP_WREADY 信号のパターンです。ACP_WREADY 信号は ZynqMP の ACP がライトデータを受け付けることが出来るときは1 に、受け付けられないときは 0 になります。この波形を見る限り、ACP_WREADY 信号は 4ワードのデータを受け取った後(ACP_WREADY=1になった後)、6クロックのウェイト(ACP_WREADY=0)が入っています。したがって、ライトトランザクションの転送レートは1.6GByte/sec にとどまっています。


# 参考


*  https://github.com/ikwzm/ZynqMP-ACP-Adapter
*  [『UltraZed 向け Debian GNU/Linux で AXI HPC port を使う (基礎編)』 @Qiita](https://qiita.com/ikwzm/items/82f98bfa76922073e610)