本ブログは英語版のAXI-Basics Blogを翻訳したものです。
概要
AXI インターフェイスで発生するトランザクションをモニターすると役立つ場合があります。このブログでは、特定のアドレスで発生するトランザクションの読み出しおよび書き込みをカウントする基本的な AXI4-Lite Sniffer IP を作成する方法を紹介します。
HDL (Verilog) コードを記述した後に、コードを IP としてパッケージし、この IP を IP インテグレーター ブロック デザイン (BD) に追加します。
AXI Sniffer IP には、AXI4-Lite リンク 1 つと出力 2 つをモニターする AXI4-Lite 入力インターフェイス 1 つを含めて、特定アドレス (GUI で指定可能) で発生した読み出しおよび書き込み数をカウントします。

Vivado IP インテグレーターで使用する AXI Sniffer IP の作成 (チュートリアル)
- このブログに添付されているデザイン ファイルをダウンロードします。
- Vivado 2019.2 を開きます。
- [Tcl Console] ウィンドウで、cd コマンドを使用して (cd AXI_Basics_5)、ZIP 解凍ディレクトリに移動します。
- [Tcl Console] ウィンドウで source ./create_proj.tcl を使用して tcl スクリプトを実行します。
これで AXI4-Lite マスターとして設定した AXI VIP および AXI GPIO IP から構成された BD を使用した Vivado プロジェクトが作成されます。このデザインは、ブログ記事: AXI の基礎 3 で作成した最終デザインと類似しています。

このプロジェクトでは、AXI Sniffer IP を作成し、この IP を AXI VIP IP と AXI GPIO IP 間の AXI4-Lite インターフェイスに接続します。
まず、AXI Sniffer IP の HDL (Verilog) コードを記述します。
- [Sources] ウィンドウで AXI_Sniffer.v ファイルをダブルクリックしてテキスト エディターで開きます。

まず、IP のポートを宣言する必要があります。AXI4-Lite インターフェイスが 1 つ必要です。AMBA® AXI™ および ACE™ プロトコル仕様は Arm のウェブサイト (リンク) から入手可能です。これらの信号が AXI4-Lite インターフェイスに必要です。

またポートを 2 個 (read_accesses および write_accesses) 追加して、IP が監視しているアドレスへの読み込み/書き込みアクセス数をカウントする必要があります。
- 次のコードを追加して、必要な信号をすべて宣言します。
module AXI_Sniffer
(
input aclk,
input aresetn,
input s_axi_arvalid,
input s_axi_arready,
input [31:0] s_axi_araddr,
input [2:0] s_axi_arprot,
input s_axi_rvalid,
input s_axi_rready,
input [31:0] s_axi_rdata,
input [1:0] s_axi_rresp,
input s_axi_awvalid,
input s_axi_awready,
input [31:0] s_axi_awaddr,
input [2:0] s_axi_awprot,
input s_axi_wvalid,
input s_axi_wready,
input [31:0] s_axi_wdata,
input [3:0] s_axi_wstrb,
input s_axi_bready,
input s_axi_bvalid,
input [1:0] s_axi_bresp,
output [31:0] read_accesses,
output [31:0] write_accesses
);
注記: IP による動作は AXI4-Lite インターフェイスで実行されず、インターフェイスのトラフィックが監視されるのみなので、すべての AXI4-Lite 信号が入力として設定されます。
次に、監視するアドレスを設定するパラメーターを IP に追加する必要があります。
- 次のコードを追加します。
module AXI_Sniffer
#(
parameter SLAVE_BASE_ADDR = 32'h40000000
)
(
最後に、アドレスへのアクセス数をカウントするロジックを追加する必要があります。次のコードでは、監視するアドレスが設定されているときに tready と tvalid が high になるとカウンターが増加します。
- 次のコードを追加します。
reg [31:0] read_accesses_cnt;
reg [31:0] write_accesses_cnt;
assign read_accesses = read_accesses_cnt;
assign write_accesses = write_accesses_cnt;
//Check the Read Address Channel
always @(posedge aclk)
begin
if(aresetn == 0)
begin
read_accesses_cnt = 0;
end
else if (s_axi_arready && s_axi_arvalid && s_axi_araddr == SLAVE_BASE_ADDR)
begin
read_accesses_cnt = read_accesses_cnt + 1;
end
else
read_accesses_cnt = read_accesses_cnt;
end
//Check the Write Address Channel
always @(posedge aclk)
begin
if(aresetn == 0)
begin
write_accesses_cnt = 0;
end
else if (s_axi_awready && s_axi_awvalid && s_axi_awaddr == SLAVE_BASE_ADDR)
begin
write_accesses_cnt = write_accesses_cnt + 1;
end
else
write_accesses_cnt = write_accesses_cnt;
end
endmodule
- AXI_Sniffer.v ファイルを保存します。
IP インテグレーターで BD に HDL ファイルをインポートします。
- BD を右クリックし、[Add Module] をクリックします。

s_axi_* 信号がまとめられて、インターフェイス s_axi が 1 つ作成されることがわかります。ただし、このインターフェイスを AXI VIP と AXI GPIO 間の既存の接続に接続することはできません。
- [Tools] → [Create and Package New IP] をクリックします。
- Create and Package New IP ウィザードの 2 ページ目で、[Package a specified directory] を選択して [Next] をクリックします。
- AXI_Basics_5/src/hdl/AXI_Sniffer ディレクトリを選択して、デフォルト設定のままで [Next] → [Next] → [Finish] をクリックします。
これで IP パッケージャー プロジェクトが作成されます。[Package IP] タブで、[Ports and Interfaces] セクションをクリックします。

ここでも、ツールにより s_axi_* 信号が 1 つの s_axi インターフェイスにまとめられていることを確認できます。ここでもこのインターフェイスがスレーブとして設定されています。既存の AXI バスに接続するには、ツールでこのインターフェイスの設定をスレーブの代わりに監視 ([monitor]) に設定する必要があります。
- s_axi インターフェイスを右クリックして、[Edit Interface] をクリックします。

- [Edit Interface] ウィンドウの [General] タブで、[Mode] の値を [monitor] に変更します。

- 次に、[Port Mapping] タブをクリックして、[Hide Mapped Ports] をオンにします。

- 名前が s_axi_* の IP の物理ポート ([IP's Physical Ports]) それぞれに該当するインターフェイスの論理ポート ([Interface's Logical Ports]) を識別し、[Map Ports] をクリックしてマップします。

- すべての s_axi_* IP ポートのマップが終了したら [OK] をクリックし、[Edit Interface] ウィンドウを閉じます。
- s_axi インターフェイスを右クリックし、[Associate Clocks] をクリックします。

- 次のウィンドウで、[aclk] がオンになっているはずです。[OK] をクリックします。

- [Review and Package] をクリックして[Package IP] をクリックします。

IP パッケージャー プロジェクトが閉じます。
- 最初のプロジェクトの BD から AXI_Sniffer IP を削除します。
- 最初プロジェクトの BD を右クリックして [Add IP] をクリックします。IP カタログに自動で追加されているはずの AXI Sniffer IP を検索し、BD に追加します。

- AXI Sniffer IP の s_axi インターフェイスを AXI VIP と AXI GPIO 間に接続してみてください。今回は接続できるはずです。

- カスタム IP の aclk と aresetn 入力ポートを対応する BD ポートに接続します。
- BD デザインを検証します。エラーやクリティカル警告メッセージは表示されないはずです。BD を保存します。
最後にシミュレーションで IP が正しく動作するかを確認できます。
- シミュレーションを起動して、AXI_Sniffer IP の read_accesses ポートおよび write_accesses ポートを波形ウィンドウに追加します。

- シミュレーションを再起動して 3 us 間実行します。

シミュレーション波形で、書き込みと読み出しのトランザクションが 2 回ずつ発生していることがわかります。ただし、IP では書き込みが 2 回と読み出しが 1 回のみカウントされます。

各トランザクションのアドレスを確認して出力が正しいかを確認します。2 回の書き込みトランザクションは、IP で監視しているアドレス 0x4000_0000 で発生しています。

読み出しトランザクションの方は、1 つのトランザクションのみがアドレス 0x4000_0000 で発生しており、もう 1 つのトランザクションではアドレス 0x4000_0008 が読み出されています。このため、IP は正しく動作していることがわかります。

この記事では、AXI Sniffer IP の使用例を 1 つ紹介しましたが、この Verilog コードを編集して別の機能を追加することもできます。