上一篇《通过状态机来对axi_lite总线读写操作》中,分享网友的代码。
本工程为VIVADO 2017.04版本,先自定义AXI_LITE slave IP,源码部分未作修改,顶层文件调用该IP,并编写testbench,配合顶层状态机对该从器件先进行写操作,再进行读操作,观察仿真波形,看数据是否一致。工程下载链接在文末给出。
以下摘出状态机中时序输出部分代码及其注释:
always @(posedge clk_100M or posedge rst)
begin
if (rst)
begin
s_axi_awvalid <= 1'b0;
s_axi_wvalid <= 1'b0;
s_axi_arvalid <= 1'b0;
s_axi_rready <= 1'b0;
s_axi_bready <= 1'b0;
s_axi_awaddr <= 0;
s_axi_araddr <= 0;
s_axi_wdata <= 0;
m_axi_rdata <= 0;
ipc_ack_r <= 1'b0;
end
else
begin
s_axi_awvalid <= 1'b0;
s_axi_wvalid <= 1'b0;
s_axi_arvalid <= 1'b0;
s_axi_rready <= 1'b0;
s_axi_bready <= 1'b0;
ipc_ack_r <= 1'b0;
case(next_state)
//IDLE:
WRITE_START: //不需要跳转条件,即写状态只需要消耗一个时钟周期,然后自动跳转到下一个状态
begin //首先准备好访问地址,和需要写入的数据;同时给出地址有效,数据有效,bready信号
s_axi_awaddr <= ipc_waddr[6:0];
s_axi_wdata <= ipc_wdata;
s_axi_awvalid <= 1'b1;
s_axi_wvalid <= 1'b1;
s_axi_bready <= 1'b1;
end
WRITE_VALID: //检测是否接收到slave端的地址ready和数据ready信号
begin
s_axi_awvalid <= 1'b1;
s_axi_wvalid <= 1'b1;
s_axi_bready <= 1'b1;
end
WRITE_READY: //等待slave端的bvalid信号到来,表示一次写完成了,即slave端的一个写反馈过程
begin
s_axi_bready <= 1'b1;
end
//WRITE_BREADY: //WRITE_BREADY 状态不需要状态跳转条件,只需要消耗一个时钟周期,同时在这个状态中,m_axi_bready <= 1'b1,此状态输出与前一状态相同,此处可省略
WRITE_END:
begin
ipc_ack_r <= 1'b1;
end
READ_START: //首先准备好访问地址,和地址有效信号先拉高
begin
s_axi_araddr <= ipc_raddr[6:0];
s_axi_arvalid <= 1'b1;
end
READ_VALID: //接收到slave端的地址ready信号后,表示可以进行下一次读操作了
begin
s_axi_arvalid <= 1'b1;
end
//READ_READY: //当slave端传回来读数据有效信号后,状态机跳转进read_finish状态。没有相关信号需要输出。此状态输出与前一状态相同,此处可省略
READ_FINISH:
begin
m_axi_rdata <= s_axi_rdata;
s_axi_rready <= 1'b1;
end
READ_END:
begin
ipc_ack_r <= 1'b1;
end
default:
begin
s_axi_awvalid <= 1'b0;
s_axi_wvalid <= 1'b0;
s_axi_arvalid <= 1'b0;
s_axi_rready <= 1'b0;
s_axi_bready <= 1'b0;
ipc_ack_r <= 1'b0;
end
endcase
end
end
testbench文件很简单,复位完成后,先写入四个数据,然后读取四个数据,重复两次:
整体波形:(注意此处贴图有两处错误:1.读写操作时是以32位进行,因此testbench中给出地址不应该以1递增,而应该以4递增;2.顶层文件中s_axi_wstrb信号并未关联其他信号,axi4_lite源码中 if ( S_AXI_WSTRB[byte_index] == 1 ) 判断条件不成立,因此实际上写数据并未真正写入从器件,导致读出来的数据为dafault值0。这两处错误在上传的工程中已做修改,前期的截图未作修改)
1
写时序局部波形
读时序局部波形:
另外,由截图可见,(由于没有给s_axi_wstrb赋值,数据没有真正写入)读数据为默认的0,且最初axi_lite源码未做修改,默认为0。后续s_axi_wstrb保持为4'b1111,testbench中读写地址也是以4递增后,整体仿真波形如下:
可以看见,读取的值与先写入的值一致,即状态机对AXI4_LITE slave IP读写成功。
工程下载链接:https://download.csdn.net/download/keilzc/11264842。