目录
大家好,这里是程序员杰克。一名平平无奇的嵌入式软件工程师。
上篇主要是对axi4-lite_slave接口信号的时序代码进行分析,在本篇推送中,杰克将继续对axi4-Lite总线协议的master接口信号的时序代码进行分析。
Xilinx 提供了axi4-lite_master的模板,对于初学者而言,是一个很好的学习资料,但杰克认为其接口信号的时序代码并不是最优解,因此杰克重新编写和封装了一个axi4-lite_master,并以此作为本次master接口的代码分析内容。
下面正式进入本章推送的内容。
01 axi4_lite_master写事务代码分析
上篇推送对Xilinx提供的slave模板分析中我们知道:写地址通道、写数据通道同时握手成功才执行写事务传输。那么axi4-lite_master接口也必须配合slave接口对信号进行设计。axi4-lite_master接口写事务主要是实现如下时序:
- 写地址通道握手信号AWVALID的时序控制
- 写数据通道握手信号WVALID的时序控制
- 写响应通道BREADY信号的时序控制
AXI4-Lite 写事务仿真逻辑时序如下图所示:
写事务开始信号边沿检测
前面有提过,杰克重新封装了一个axi4-lite_master,该接口以开始信号作为驱动,因此杰克这里对开始信号边沿进行了检测,检测代码如下:
input wire write_start;
...
//write_start edge detected logic
reg write_start_tmp1;
reg write_start_tmp2;
wire write_start_rise = write_start_tmp2 & (~write_start_tmp1);
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
write_start_tmp1 <= 1'b0;
write_start_tmp2 <= 1'b0;
end
else begin
write_start_tmp1 <= write_start_tmp2;
write_start_tmp2 <= write_start;
end
end
关注信号 | 描述 |
write_start | 外部驱动输入信号,用于表征写事务开始. |
write_start_rise (默认为0) | 对write_start上升沿打一拍的信号,作为axi4-lite_master写事务真正开始信号. |
AWVALID时序控制代码分析
reg axi_awvalid;
assign M_AXI_AWVALID = axi_awvalid;
...
//M_AXI_AWVALID signnal control logic
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_awvalid <= 1'b0;
end
else begin
if(write_start_rise) begin
axi_awvalid <= 1'b1;
end
else if(M_AXI_AWREADY && axi_awvalid) begin
axi_awvalid <= 1'b0;
end
else begin
axi_awvalid <= axi_awvalid;
end
end
end
关注信号 | 条件 | 描述 |
axi_awvalid (默认为0) | 置高 | 当wirte_start_rise为高,该信号置高,表示写事务开始,与axi_wvalid同时置高,即写地址通道、写数据通道同时握手 |
置低 | 当M_AXI_AWREADY&&本身为高时,置低,即说明axi_awvalid在传输过程中是一个脉冲信号 |
WVALID时序控制代码分析
reg axi_wvalid;
assign M_AXI_WVALID = axi_wvalid;
...
//M_AXI_WVALID signnal control logic
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_wvalid <= 1'b0;
end
else begin
if(write_start_rise) begin
axi_wvalid <= 1'b1;
end
else if(M_AXI_WREADY && axi_wvalid) begin
axi_wvalid <= 1'b0;
end
else begin
axi_wvalid <= axi_wvalid;
end
end
end
关注信号 | 条件 | 描述 |
axi_wvalid (默认为0) | 置高 | 当wirte_start_rise为高,该信号置高;与axi_awvalid同时置高,即写地址通道、写数据通道同时握手 |
置低 | 当M_AXI_WREADY&&本身为高时,置低,即说明axi_wvalid在传输过程中是一个脉冲信号 |
BREADY时序控制代码分析
reg axi_bready;
assign M_AXI_BREADY = axi_bready;
...
//M_AXI_BREADY signnal control logic
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_bready <= 1'b0;
end
else if(axi_awvalid && ~axi_bready) begin
axi_bready <= 1'b1;
end
else if(M_AXI_BVALID) begin
axi_bready <= 1'b0;
end
else begin
axi_bready <= axi_bready;
end
end
关注信号 | 条件 | 描述 |
axi_bready (默认为0) | 置高 | 当axi_awvalid为高、信号本身为低时,置高;该信号保持高,一直到slave的M_AXI_BVALID响应;表征当传输开始后,master一直等待slave写响应. |
置低 | 当slave写响应通道信号M_AXI_BVALID为高时,握手成功后置低. |
02 axi4_lite_master读事务代码分析
对于AXI4-Lite总线读事务而言,axi4-lite_master接口主要是实现如下时序:
- 读地址通道握手信号ARVALID的时序控制
- 读数据通道握手信号RREADY的时序控制
- 读数据通道RDATA的寄存控制
AXI4-Lite读事务仿真逻辑时序如下图所示:
读事务开始信号边沿检测
前面有提过,杰克重新封装了一个axi4-lite_master,该接口以开始信号作为驱动,因此杰克这里对开始信号边沿进行了检测,检测代码如下:
input wire read_start;
...
//read_start edge detected logic
reg read_start_tmp1;
reg read_start_tmp2;
wire read_start_rise = read_start_tmp2 & (~read_start_tmp1);
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
read_start_tmp1 <= 1'b0;
read_start_tmp2 <= 1'b0;
end
else begin
read_start_tmp1 <= read_start_tmp2;
read_start_tmp2 <= read_start;
end
end
关注信号 | 描述 |
read_start | 外部驱动输入信号,用于表征读事务开始. |
read_start_rise (默认为0) | 对read_start上升沿打一拍的信号,作为axi4-lite_master读事务真正开始信号. |
ARVALID时序控制代码分析
reg axi_arvalid;
assign M_AXI_ARVALID = axi_arvalid;
...
//M_AXI_ARVALID signnal control logic
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_arvalid <= 1'b0;
end
else begin
if(read_start_rise) begin
axi_arvalid <= 1'b1;
end
else if(M_AXI_ARREADY && axi_arvalid) begin
axi_arvalid <= 1'b0;
end
else begin
axi_arvalid <= axi_arvalid;
end
end
end
关注信号 | 条件 | 描述 |
axi_arvalid (默认为0) | 置高 | 当read_start_rise为高,该信号置高,表示读事务开始,写地址通道握手开始. |
置低 | 当M_AXI_AREADY&&本身为高时,置低,即说明axi_arvalid在传输过程中是一个脉冲信号 |
RREADY时序控制代码分析
reg axi_rready;
assign M_AXI_RREADY = axi_rready;
...
//M_AXI_RREADY signnal control logic
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_rready <= 1'b0;
end
else if(axi_arvalid && ~axi_rready) begin
axi_rready <= 1'b1;
end
else if(M_AXI_RVALID) begin
axi_rready <= 1'b0;
end
else begin
axi_rready <= axi_rready;
end
end
关注信号 | 条件 | 描述 |
axi_rready (默认为0) | 置高 | 当axi_arvalid为高、信号本身为低时,置高;该信号保持高,一直到slave的M_AXI_RVALID响应;表征当读传输开始后,master一直等待slave写响应. |
置低 | 当M_AXI_BVALID为高时,握手成功后置低. |
RDATA寄存控制
parameter integer C_M_AXI_DATA_WIDTH = 32;
output wire [C_M_AXI_DATA_WIDTH-1 : 0] rdata;
...
assign rdata = (M_AXI_RVALID && axi_rready) ? M_AXI_RDATA : rdata;
关注信号 | 描述 |
rdata | M_AXI_RVALID、axi_rready同时为高时,此时M_AXI_RDATA的数据便是要读取的数据. |
03 文章总结
axi4-lite总线接口时序算比较简单,对于PL与PS一些寄存器操作,axi4-lite有着占用逻辑小、效率高的特点。axi4-lite是axi4-full总线协议的精简,学习axi4-lite对于理解axi4-full总线有一定的帮助。
当然,因为篇幅、个人理解不一致,对于学习axi4-lite总线而言,可以借鉴别人的思想,但最终还是得自己下功夫去啃,毕竟啃下来的才是自己收获的。
axi4-lite总线协议以及master/slave接口总结分享到此就结束了。从下篇开始,开始总结分享axi4-full总线的内容。