20210801:AXI-Lite总线逻辑与关键源码分析
作者:互联网
AXI-lite协议源码细读
AXI主从机交互模式
AXI和AXI-lite均包含五个不同的通道(允许同时读写、双向通信)。
- 读地址通道
- 写地址通道
- 读数据通道
- 写数据通道
- 写响应通道
读交易交互图
写交易交互图
源码实现细节
简单概括上面两个图。
读交易过程如上图,主端发送要读的地址,从端把这些地址的数据反馈给主端。
写交易过程见1-2,主端发送要写的地址和数据,完成之后从端发送完成响应。
具体的实现细节,我们以源码进行分析仿真,结合官方提供的一系列文档进行说明。最终达到深入理解AXI-lite的交互过程。
always @(posedge M_AXI_ACLK)
begin
//Only VALID signals must be deasserted during reset per AXI spec
//Consider inverting then registering active-low reset for higher fmax
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
begin
axi_awvalid <= 1'b0;
end
//Signal a new address/data command is available by user logic
else
begin
if (start_single_write)
begin
axi_awvalid <= 1'b1;
end
//Address accepted by interconnect/slave (issue of M_AXI_AWREADY by slave)
else if (M_AXI_AWREADY && axi_awvalid)
begin
axi_awvalid <= 1'b0;
end
end
end
//--------------------
//Write Data Channel
//--------------------
//The write data channel is for transfering the actual data.
//The data generation is speific to the example design, and
//so only the WVALID/WREADY handshake is shown here
always @(posedge M_AXI_ACLK)
begin
if (M_AXI_ARESETN == 0 || init_txn_pulse == 1'b1)
begin
axi_wvalid <= 1'b0;
end
//Signal a new address/data command is available by user logic
else if (start_single_write)
begin
axi_wvalid <= 1'b1;
end
//Data accepted by interconnect/slave (issue of M_AXI_WREADY by slave)
else if (M_AXI_WREADY && axi_wvalid)
begin
axi_wvalid <= 1'b0;
end
end
注意到主端口的源码中,start_single_write拉高时axi_awvalid和axi_wvalid同时拉高。即写地址和写数据通道有效的信号。
写完之后从端口会反馈响应信号M_AXI_WREADY和M_AXI_AWREADY表示地址写入和数据写入完成。而在从端口源码中也提到了类似的信号S_AXI_WREADY和S_AXI_AWREADY的产生逻辑如下:
// Implement axi_awready generation
// axi_awready is asserted for one S_AXI_ACLK clock cycle when both
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
// de-asserted when reset is low.
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_awready <= 1'b0;
aw_en <= 1'b1;
end
else
begin
if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID && aw_en)
begin
// slave is ready to accept write address when
// there is a valid write address and write data
// on the write address and data bus. This design
// expects no outstanding transactions.
axi_awready <= 1'b1;
aw_en <= 1'b0;
end
else if (S_AXI_BREADY && axi_bvalid)
begin
aw_en <= 1'b1;
axi_awready <= 1'b0;
end
else
begin
axi_awready <= 1'b0;
end
end
end
// Implement axi_wready generation
// axi_wready is asserted for one S_AXI_ACLK clock cycle when both
// S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is
// de-asserted when reset is low.
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_wready <= 1'b0;
end
else
begin
if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID && aw_en )
begin
// slave is ready to accept write data when
// there is a valid write address and write data
// on the write address and data bus. This design
// expects no outstanding transactions.
axi_wready <= 1'b1;
end
else
begin
axi_wready <= 1'b0;
end
end
end
我们可以在tb中将主从端口全部都输入相同的源信号,然后给与主端口的信号发送开始脉冲,即可启动整个交互过程。
交互的关键tb代码如下:
initial begin
sys_clk_i = 1;
sys_rst_n = 0;
m_axi_init_axi_txn = 0;
#40 sys_rst_n = 1'b1;
#20 m_axi_init_axi_txn = 1;
#20 m_axi_init_axi_txn = 0;
end
.m00_axi_init_axi_txn(m_axi_init_axi_txn),
注意到我们启动时会需要一个脉冲起始位,连接到主端口来进行启动。使用block_board直观显示如图。
可以很明显的看到主设备端口比从设备端口多出的几个接口设计。也能体现最开始图中出现的AXI读写逻辑。
到此我们再根据tb仿真图可以看到更加清晰的读写逻辑,如下图所示:
可以清晰的看到先写后读的数据交互过程,从而对AXI-Lite总线协议有个更加深刻的理解。
参考文件(百度直接搜索即可下载)
- ug1037-vivado-axi-reference-guide
- IHI0022E_amba_axi_and_ace_protocol_spec
写在最后
不必再相信不该相信的人,努力前行就好。
标签:txn,axi,端口,20210801,init,源码,Lite,AXI 来源: https://blog.csdn.net/qq_36828395/article/details/119305757