ARM
FPGA
zynq

Zynq の ACP を使う時の AxCACHE 信号とAxUSER 信号の値

はじめに

Xilinx 社の ZYNQ において、PL(Programmable Logic)から PS(Processing System)へメモリアクセスする際、ACP(Accelerator Coherency Port)を使うと、ハードウェアによって CPU キャッシュとメインメモリとのコヒーレンシが保証されます。しかし、この ACP を有効に使うには AxCACHE 信号と AxUSER 信号に適切な値を入力しなければなりません。この記事では ACP を使う際の AxCACHE 信号と AxUSER 信号に関して説明します。

結論から先に言うと、AxUSER[0]=1、AxCACHE[3:0]=1111 または 1110 を入力するのが良いでしょう。

ブロック図

次図にZynq-7000 の PS の ACP 周りのブロック図を示します。

Fig.1 Zynq-7000 PS Block Diagram

Fig.1 Zynq-7000 PS Block Diagram


このブロック図のように、ACP は SCU(Snoop Control Unit)を通して、CPU の L1 Cache と L2 Cache に接続されています。そして L2 Cache の先に DDR Controller を介してメインメモリに繋がっています。

ACP インターフェース

『UG585 Zynq-7000 All Programmable SoC Technical Refernce Manual』には、ACP アクセスに対して次のように記述されています。

コヒーレントなACP読み出し要求

ARVALID とともに ARUSER[0]=1および ARCACHE[1] = 1 が送信された場合、ACP 読み出し要求はコヒーレントです。この場合、SCU はコヒーレンシを維持します。データがいずれかのCortex-A9 プロセッサにある場合、データはそのプロセッサから直接読み出されて ACP ポートに返されます。データがいずれの Cortex-A9 プロセッサにもない場合、すべての AXI パラメーター (ロック属性を除く) と共に読み出し要求がいずれか 1 つの SCU AXI マスターポー トに発行されます。

非コヒーレントなACP読み出し要求

ARVALID と共に ARUSER[0] = 0 ま たは ARCACHE[1] = 0 が送信された場合、ACP 読み出し要求は非コヒーレントです。この場合、SCU はコヒーレンシを維持せず、読み出し要求はいずれか 1 つの SCU AXI マスターポー ト L2 キャッシュコ ン トローラーまたは OCM へ直接転送されます。

コヒーレントなACP書き出し要求

AWVALID と共に AWUSER[0] = 1 および AWCACHE[1] = 1 が送信された場合、ACP 書き込み要求はコヒーレントです。この場合、SCU はコヒーレンシを維持します。データがいずれかのCortex-A9 プロセッサにある場合、最初にその CPU のデータをクリーニングして無効にします。データがいずれのCortex-A9 プロセッサにもない場合、または既にクリーニングと無効化が実行されている場合、対応するすべてのAXI パラメーター (ロック属性を除く) と共に書き込み要求がいずれか 1 つの SCU AXI マスターポー トに発行されます。

注記: 書き込みパラメーターの設定によっては、トランザクションを L2 キャッシュに割り当てることもできます。

非コヒーレントな ACP 書き込み要求

AWVALID と共に AWUSER[0] = 0 ま たは AWCACHE[1] = 0 が送信された場合、ACP 書き込み要求は非コヒーレントです。この場合、SCU はコヒーレンシを維持せず、書き込み要求はいずれか 1 つの SCU AXI マスターポートに直接転送されます。

L2 キャッシュインターフェース

前節の ACP の説明で、次の点が重要です。

  • コヒーレントなACP読み出し要求において、データがいずれの Cortex-A9 プロセッサにもない場合、すべての AXI パラメーター (ロック属性を除く) と共に読み出し要求がいずれか 1つの SCU AXI マスターポー トに発行されます。
  • コヒーレントなACP書き出し要求において、データがいずれのCortex-A9 プロセッサにもない場合、または既にクリーニングと無効化が実行されている場合、対応するすべてのAXI パラメーター (ロック属性を除く) と共に書き込み要求がいずれか 1 つの SCU AXI マスターポー トに発行されます。

つまり、CPUキャッシュにデータが無い場合は L2キャッシュに対してトランザクションが発生し、その時に ACP から入力された AxCACHE の値がそのまま L2 キャッシュコントローラーの AxCACHE に入力されるということです。

ここで『CoreLink Level 2 Cache Controller L2C-310 Technical Reference Manual』の 2.3.1 Cache attribute の項には次のようなテーブルがあります。

Table.1 AWCACHE and ARCACHE definitions

AxCACHE[3:0] AXI meaning ARMv6 and ARMv7 equivalent
WA RA C B
0 0 0 0 Non-cachable, non-bufferable Strongly ordered
0 0 0 1 Bufferable only Device
0 0 1 0 Cacheable but do not allocate Outer non-cacheable
0 0 1 1 Cacheable and bufferable, do not allocate Outer non-cacheable
0 1 1 0 Cacheable write-through, allocate on read Outer write-through, no allocate on write
0 1 1 1 Cacheable write-back, allocate on read Outer write-back, no allocate on write
1 0 1 0 Cacheable write-through, allocate on write -
1 0 1 1 Cacheable write-back, allocate on write -
1 1 1 0 Cacheable write-through, allocate on both read and write -
1 1 1 1 Cacheable write-back, allocate on both read and write Outer write-back, write allocate

これらのオペレーションに関して、もう少し詳しく説明すると次のようになります。

Non-cacheable and non-bufferable

  • キャッシュ不可、バッファ不可
  • AxCACHE : 0000
  • 読み出し : L2にはキャッシュされず、メモリへのアクセスが発生
  • 書き込み : バッファーには格納されず、メモリへのアクセスが発生

Bufferable only

  • バッファ可能のみ
  • AxCACHE : 0001
  • 読み出し : L2にはキャッシュされず、メモリへのアクセスが発生
  • 書き込み : ストアバッファには格納されるが、結合されず直ちにメモリへドレイン

Cacheable but do not allocate

  • キャッシュ可能、バッファ不可、割り当て無し
  • AxCACHE : 0010
  • 読み出し : L2にはキャッシュされず、メモリへのアクセスが発生
  • 書き込み : ストアバ ッ ファーに格納され、ストアバッファがドレインされるとメモリへ書き込まれる

Cacheable and bufferable, do not allocate

  • キャッシュ可能、バッファ可、割り当て無し
  • AxCACHE : 0011
  • 何故か『CoreLink Level 2 Cache Controller L2C-310 Technical Reference Manual』にこのオペレーションの記述が無い

Cacheable write-through, allocate on read

  • キャッシュ可能なライトスルー、読み出し割り当て
  • AxCACHE : 0110
  • 読み出しヒット時 : L2 から読み出し
  • 読み出しミス時 : L2 へのラインフィル
  • 書き込みヒット時 : ストアバッファに格納され、ストアバッファがドレインされると L2 およびメモリへ書き込まれる
  • 書き込みミス時 : ストアバッファに格納され、ストアバッファがドレインされるとメモリへ書き込まれる

Cacheable write-back, allocate on read

  • キャッシュ可能なライトバック、読み出し割り当て
  • AxCACHE : 0111
  • 読み出しヒット時 : L2 から読み出し
  • 読み出しミス時 : L2 へのラインフィル
  • 書き込みヒット時 : ストアバッファに格納され、ストアバッファがドレインされると L2 へ書き込み、ラインをダーティとマーク付け
  • 書き込みミス時 : ストアバッファに格納され、ストアバッファがドレインされると メモリへ書き込まれる

Cacheable write-through, allocate on write

  • キャッシュ可能なライトスルー、書き込み割り当て
  • AxCACHE : 1010
  • 読み出しヒット時 : L2 から読み出し
  • 読み出しミス時 : L2にはキャッシュせず、メモリへのアクセスが発生
  • 書き込みヒット時 : ストアバッファに格納され、ストアバッファがドレインされると L2 およびメモリへ書き込まれる
  • 書き込みミス時 : ストアバ ッファーへ格納。バッファがドレインされると、フルかどうかを確認。フルでなければバッファーをL2 に割り当てる前にメモリに対してワードまたはラインを要求。L2 へ割り当て。メモリへ書き込み。

Cacheable write-back, allocate on write

  • キャッシュ可能なライトバック、書き込み割り当て
  • AxCACHE : 1011
  • 読み出しヒット時 : L2 から読み出し
  • 読み出しミス時 : L2にはキャッシュせず、メモリへのアクセスが発生
  • 書き込みヒット時 : ストアバッファに格納され、ストアバッファがドレインされると L2 へ書き込み、ラインをダーティとマーク付け
  • 書き込みミス時 : ストアバッファへ格納。バッファをドレインする必要がある場合は、フルかどうかを確認。フルでなければバッファを L2 に割り当てる前にメモリに対してワードまたはラインを要求。L2 へ割り当て

Cacheable write-through, allocate on both read and write

  • キャッシュ可能なライトスルー、読み出し/書き込み割り当て
  • AxCACHE : 1110
  • 読み出しヒット時 : L2 から読み出し
  • 読み出しミス時 : L2 へのラインフィル
  • 書き込みヒット時 : ストアバッファに格納され、ストアバッファがドレインされると L2 およびメモリへ書き込まれる
  • 書き込みミス時 : ストアバッファへ格納。バッファをドレインする必要がある場合は、フルかどうかを確認。フルでなければバッファを L2 に割り当てる前にメモリに対してワードまたはラインを要求。L2 へ割り当て。メモリへ書き込み

Cacheable write-back, allocate on both read and write

  • キャッシュ可能なライトバック、読み出し/書き込み割り当て
  • AxCACHE : 1111
  • 読み出しヒット時 : L2 から読み出し
  • 読み出しミス時 : L2 へのラインフィル
  • 書き込みヒット時 : ストアバッファに格納され、ストアバッファがドレインされると L2 へ書き込み、ラインをダーティとマーク付け
  • 書き込みミス時 : ストアバッファへ格納。バッファをドレインする必要がある場合は、フルかどうかを確認。フルでなければバッファを L2 に割り当てる前にメモリに対してワードまたはラインを要求。L2 へ割り当て

まとめ

AxUSER[0]=1、AxCACHE[3:0]=1111 または 1110 を入力するのが良いでしょう。

余談

実はこの件は2017年12月2日のイベント『FPGA+SoC+Linux実践勉強会』にて筆者が「キャッシュのコヒーレンシのトラブルを避けるためにACPを使った方が簡単ですよ」なんて言ってしまったところ、「言われたとおりしたけどACPだとデータが化ける」という報告が数名の方からあって急遽調べた次第です。

『FPGA+SoC+LinuxでXilinx AXI DMAを試す』(ふがふが)

『FPGA+SoC+Linux実践勉強会での課題をやってみた3(Vivado 編2 ACPポートを使用)』(FPGAの部屋)

そこで、どうやら AxCACHE の値が Xilinx 推奨の 0011 だとACP でデータ化けすることが判りました。私は自前でDMAコントローラーを作っていて AxCACHE に 1111 を出力していたので気がつきませんでした。いい加減なことを言って申し訳ありません。

あと、Xilinx のフォーラムでもちょっと問題になっていたみたいです。

https://forums.xilinx.com/t5/Zynq-All-Programmable-SoC/Zynq-ACP-Cohereny-with-Linux-ioremap-cache/m-p/663555/highlight/true#M10942)

参考