BY Florent Werbrouck
注意:本论坛博客所有内容皆来源于Xilinx工程师,如需转载,请写明出处作者及赛灵思论坛链接并发邮件至cncrc@xilinx.com,未经Xilinx及著作权人许可,禁止用作商业用途
引言
在某些情况下,通过嗅探 AXI 接口来分析其中正在发生的传输事务是很有用的。在本文中,我将为大家演示如何创建基本 AXI4-Lite Sniffer IP 以对特定地址上正在发生的读写传输事务进行计数。
我们将创建包含 AXI4-Lite 输入接口的 AXI Sniffer 用于嗅探 AXI4-Lite 链接,并包含 2 项输出以提供在特定地址上发生的读写传输事务的数量(地址可通过 GUI 配置)。
首先,编写 HDL (Verilog) 代码,然后将其封装为 IP,最后将此 IP 添加到 IP Integrator Block Design (BD) 中。
创建 AXI Sniffer IP 以在 Vivado IP Integrator 中使用(教程)
在此工程中,我们将创建 AXI Sniffer IP,然后尝试将其连接到位于 AXI VIP 和 AXI GPIO IP 之间的 AXI4-Lite 接口。
首先,让我们来编写适用于 AXI Sniffer IP 的 HDL (Verilog) 代码。5. 双击“源 (Sources)”窗口中的 AXI_Sniffer.v 文件以在文本编辑器中将其打开
首先,需要声明 IP 端口。我们需要 1 个 AXI4-Lite 接口。根据 ARM 网站上提供的 AMBA® AXI™ 和 ACE™ 协议规范(链接),AXI4-Lite 接口上所需信号如下。
我们还需要添加 2 个端口(read_accesses 和 write_accesses),用于输出监测地址的读写访问次数。
6. 添加以下代码以声明所有必需的信号。
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
);
注:在本例中,所有 AXI4-Lite 信号均设置为输入,因为 IP 不应对 AXI4-Lite 接口执行任何操作,仅限于监测其中的流量。
然后,IP 需要 1 个参数用于设置要监测的地址。
7. 添加以下代码以添加用于监测地址的参数
module AXI_Sniffer
#(
parameter SLAVE_BASE_ADDR = 32'h40000000
)
(
最后,我们需要添加用于对地址访问次数进行计数的逻辑。监测地址出现在 axi 总线上时,每次 r/wready 和 r/wvalid 处于高位时,此代码都会将计数增加 1。
8. 请将以下代码添加到此文件中
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
9. 保存 AXI_Sniffer.v 文件
在 IP Integrator 中,提供了一项允许用户将 HDL 文件导入 BD 的功能。
10. 右键单击 BD,然后单击“添加模块 (Add Module)”
可以看到,该工具将所有 s_axi_* 信号组合为接口 s_axi。但如果我们尝试将此接口连接到 AXI VIP 与 AXI GPIO 之间的现有连接上,该工具将会禁止此操作。
这是因为导入模块工具已将 s_axi 接口设置为从接口,而 Vivado 仅允许每个主接口连接到一个从接口。
要创建监测 IP,我们需要将代码封装为 IP,这将为我们提供更多接口选项。
11. 单击“工具 (Tools) > 创建并封装新 IP (Create and Package New IP.)
12. 在“Create and Package New IP”的第 2 个页面上,选择“封装指定目录 (Package a specified directory)”,然后单击“下一步 (Next)”
13. 选中 AXI_Basics_5/src/hdl/AXI_Sniffer 目录,然后单击“Next > Next(保留默认设置) > 完成 (Finish)”
这样将创建 IP Packager 工程 。在“封装 IP (Package IP)”选项卡中,单击“端口和接口 (Ports and Interface)”部分。
可以看到,工具又一次将 s_axi_* 信号分组构成 s_axi 接口。但此接口仍设置为从接口。要连接到现有 AXI 总线,我们需要告知该工具,此接口并非从接口,而是监测接口。
14. 右键单击 s_axi 接口,然后单击“编辑接口 (Edit Interface)”
15. 在“Edit Interface”窗口的“常规 (General)”选项卡中,将“模式 (Mode)”更改为“monitor”
16. 然后单击“端口映射 (Port Mapping)”选项卡,并启用“隐藏已映射的端口 (Hide Mapped Port)”
17. 对于 IP 的每个名为 s_axi_* 的物理端口,查找接口的匹配“逻辑端口 (Logical Ports)”,然后单击“映射端口 (Map Ports)”
18. 完成所有 s_axi_* 端口映射后,单击“确定 (OK)”,以关闭“编辑接口 (Edit Interface)”窗口
19. 再次右键单击 s_axi 接口,然后单击“关联时钟 (Associate Clocks)”
20. 在下一个窗口中,应已自动选中 aclk。单击“OK”
21. 单击“复查并封装 (Review and Package)”部分,然后单击“封装 IP (Package IP)”。
这样将关闭 IP Packager 工程。
22. 从初始工程的 BD 中移除先前的 AXI_Sniffer IP
23. 右键单击初始工程的 BD,然后单击“添加 IP (Add IP)”。找到 AXI Sniffer IP(应已自动添加到 IP 目录中),并将其添加到 BD
24. 尝试将新 AXI Sniffer IP 的 s_axi 接口连接到 AXI VIP 与 AXI GPIO 之间的总线。现在,此操作已可行
25. 将定制 IP 的 aclk 和 aresetn 输入端口连接到对应的 BD 端口
26. 验证 BD 设计。确保其中不存在任何严重警告或错误。保存 BD。
最后,我们可在仿真中验证此 IP 是否有效。
27. 启动仿真,将 AXI_Sniffer IP 的端口 read_accesses 和 write_accesses 添加到波形窗口中
28. 重新启动仿真,保持运行 3us
在仿真波形中可以看到,正在执行 2 项读取和 2 项写入传输事务。但我们的 IP 计数仅显示 2 项写入传输事务和 1 项读取传输事务
我们可以观察每项传输事务的地址,查看输出是否正确。在 IP 监测的地址 0x4000_0000 上正在发生 2 项写入传输事务
但只有 1 项读取传输事务目标为地址 0x4000_0000(另一项读取传输事务目标为 0x4000_0008),因此 IP 行为正确
本文仅展示了 1 个利用 AXI Sniffer(或者称为 Monitor)IP 可实现的操作的示例。您可编辑 Verilog 代码以添加自己的功能。
只有注册用户才能在此添加评论。 如果您已经注册,请登录。 如果您还没有注册,请注册并登录。