下一节:AXI4总线-axi-full-master IP程序解析_北纬二六的博客-CSDN博客
axi4-full-slave总线接口IP创建
本次使用的是vivado2019.1版本作为演示学习。如果懒的话,结尾处也有工程提供下载。
新建IP过程如图1所示:
选择创建AXI互联接口:
配置如下所示,选择slave从机,选择full模式,数据总线为32Byte,缓存空间64Byte。本次只作为验证,后期这些根据自己的需求来改改变即可。
下面只需要勾选第三个即可,快速验证IP
接下来点击finish即可完成IP的生成,观察vivado的block design中可以看出,已经搭建好了如下图所示的模块化设计。
在目录下寻找到该文件并打开,我们查看AXIslave内部的接口控制代码:
首先看awready的信号拉高条件,在写之前检测到对方有效,都是会拉高的,主机写完最后一个数据后检测到输入WLAST就会拉低。
接下来是关于地址的变化,也就是写地址的变化,和之前的设置有关,可以看状态机内部代表的三种地址自增,保持,回归的三种模式。
// Implement axi_awaddr latching
// This process is used to latch the address when both
// S_AXI_AWVALID and S_AXI_WVALID are valid.
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_awaddr <= 0;
axi_awlen_cntr <= 0;
axi_awburst <= 0;
axi_awlen <= 0;
end
else
begin
if (~axi_awready && S_AXI_AWVALID && ~axi_awv_awr_flag)
begin
// address latching
axi_awaddr <= S_AXI_AWADDR[C_S_AXI_ADDR_WIDTH - 1:0];
axi_awburst <= S_AXI_AWBURST;
axi_awlen <= S_AXI_AWLEN;
// start address of transfer
axi_awlen_cntr <= 0;
end
else if((axi_awlen_cntr <= axi_awlen) && axi_wready && S_AXI_WVALID)
begin
axi_awlen_cntr <= axi_awlen_cntr + 1;
case (axi_awburst)
2'b00: // fixed burst
// The write address for all the beats in the transaction are fixed
begin
axi_awaddr <= axi_awaddr;
//for awsize = 4 bytes (010)
end
2'b01: //incremental burst
// The write address for all the beats in the transaction are increments by awsize
begin
axi_awaddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] <= axi_awaddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;
//awaddr aligned to 4 byte boundary
axi_awaddr[ADDR_LSB-1:0] <= {ADDR_LSB{1'b0}};
//for awsize = 4 bytes (010)
end
2'b10: //Wrapping burst
// The write address wraps when the address reaches wrap boundary
if (aw_wrap_en)
begin
axi_awaddr <= (axi_awaddr - aw_wrap_size);
end
else
begin
axi_awaddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] <= axi_awaddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;
axi_awaddr[ADDR_LSB-1:0] <= {ADDR_LSB{1'b0}};
end
default: //reserved (incremental burst for example)
begin
axi_awaddr <= axi_awaddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;
//for awsize = 4 bytes (010)
end
endcase
end
end
end
接下来看axi_wready,也就是从机返回给主机在写数据时候的准备好信号:
// 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 && axi_awv_awr_flag)
begin
// slave can accept the write data
axi_wready <= 1'b1;
end
//else if (~axi_awv_awr_flag)
else if (S_AXI_WLAST && axi_wready)
begin
axi_wready <= 1'b0;
end
end
end
主机写有效的时候才会将准备好信号拉高,并且WALID会持续一次突发有效的长度,并且在Wlast被从机检测到后,后续的wready就不在拉高。
后续是bvalid和bresp信号,这是从机反馈给主机的接收完毕信号,相当于应答信号。在接收完主机发送的最后一个数据后紧随其后发送一个bvalid高电平,bresp=2‘b00为“OK”。
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_bvalid <= 0;
axi_bresp <= 2'b0;
axi_buser <= 0;
end
else
begin
if (axi_awv_awr_flag && axi_wready && S_AXI_WVALID && ~axi_bvalid && S_AXI_WLAST )
begin
axi_bvalid <= 1'b1;
axi_bresp <= 2'b0;
// 'OKAY' response
end
else
begin
if (S_AXI_BREADY && axi_bvalid)
//check if bready is asserted while bvalid is high)
//(there is a possibility that bready is always asserted high)
begin
axi_bvalid <= 1'b0;
end
end
end
end
下图代码是主机向从机读地址控制信号时,从机反馈给主机的读控制信号准备接收标志arready的逻辑,和写数据的地址控制信号逻辑思想一样,都是检测对方的写地址有效信号,然后拉高自己的准备好信号。
// axi_arready is asserted for one S_AXI_ACLK clock cycle when
// S_AXI_ARVALID is asserted. axi_awready is
// de-asserted when reset (active low) is asserted.
// The read address is also latched when S_AXI_ARVALID is
// asserted. axi_araddr is reset to zero on reset assertion.
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_arready <= 1'b0;
axi_arv_arr_flag <= 1'b0;
end
else
begin
if (~axi_arready && S_AXI_ARVALID && ~axi_awv_awr_flag && ~axi_arv_arr_flag)
begin
axi_arready <= 1'b1;
axi_arv_arr_flag <= 1'b1;
end
else if (axi_rvalid && S_AXI_RREADY && axi_arlen_cntr == axi_arlen)
// preparing to accept next address after current read completion
begin
axi_arv_arr_flag <= 1'b0;
end
else
begin
axi_arready <= 1'b0;
end
end
end
下图所示为读地址的变化,可以看出和写地址变化是一样的具有三种模式就不在此赘述了。
//This process is used to latch the address when both
//S_AXI_ARVALID and S_AXI_RVALID are valid.
always @( posedge S_AXI_ACLK )
begin
if ( S_AXI_ARESETN == 1'b0 )
begin
axi_araddr <= 0;
axi_arlen_cntr <= 0;
axi_arburst <= 0;
axi_arlen <= 0;
axi_rlast <= 1'b0;
axi_ruser <= 0;
end
else
begin
if (~axi_arready && S_AXI_ARVALID && ~axi_arv_arr_flag)
begin
// address latching
axi_araddr <= S_AXI_ARADDR[C_S_AXI_ADDR_WIDTH - 1:0];
axi_arburst <= S_AXI_ARBURST;
axi_arlen <= S_AXI_ARLEN;
// start address of transfer
axi_arlen_cntr <= 0;
axi_rlast <= 1'b0;
end
else if((axi_arlen_cntr <= axi_arlen) && axi_rvalid && S_AXI_RREADY)
begin
axi_arlen_cntr <= axi_arlen_cntr + 1;
axi_rlast <= 1'b0;
case (axi_arburst)
2'b00: // fixed burst
// The read address for all the beats in the transaction are fixed
begin
axi_araddr <= axi_araddr;
//for arsize = 4 bytes (010)
end
2'b01: //incremental burst
// The read address for all the beats in the transaction are increments by awsize
begin
axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;
//araddr aligned to 4 byte boundary
axi_araddr[ADDR_LSB-1:0] <= {ADDR_LSB{1'b0}};
//for awsize = 4 bytes (010)
end
2'b10: //Wrapping burst
// The read address wraps when the address reaches wrap boundary
if (ar_wrap_en)
begin
axi_araddr <= (axi_araddr - ar_wrap_size);
end
else
begin
axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB] + 1;
//araddr aligned to 4 byte boundary
axi_araddr[ADDR_LSB-1:0] <= {ADDR_LSB{1'b0}};
end
default: //reserved (incremental burst for example)
begin
axi_araddr <= axi_araddr[C_S_AXI_ADDR_WIDTH - 1:ADDR_LSB]+1;
//for arsize = 4 bytes (010)
end
endcase
end
else if((axi_arlen_cntr == axi_arlen) && ~axi_rlast && axi_arv_arr_flag )
begin
axi_rlast <= 1'b1;
end
else if (S_AXI_RREADY)
begin
axi_rlast <= 1'b0;
end
end
end
接下来是从机给主机的读数据有效信号产生,此时在该信号下,测试数据会一起发送给主机。至至此从机受制于主机的读写操作均结束。和我们之前分析的接口时序是完全对上的
接下来为从机的写仿真结果:
从机写读仿真结果:
下载地址:https://download.csdn.net/download/weixin_39871104/87755171?spm=1001.2014.3001.5503