在之前的博客中对AXI4总线进行了介绍(FPGA-AXI4接口协议概述),在这篇博客中,实现用户端与axi4_lite之间的交互逻辑。
一, AXI4
1.1 AXI4 介绍
对AXI4总线简单介绍(具体可见FPGA-AXI4接口协议概述)
①AXI4是ARM公司提出的是一种高性能、高带宽、低延迟的片内总线
②主要描述了主设备和从设备之间的数据传输方式
③分类:AXI4_FULL、AXI4_LITE、AXI4_STREAM
AXI4_LITE 不支持突发传输。常用与数据量较小的传输,可以理解为轻量级 的AXI4_FULL。
AXI4_FULL 又被称为AXI4,支持突发传输,突发长度为1~256。
AXI4_STREAM 丢弃了地址项,常用于高速数据传输。
1.2 什么是片内、片外
AXI4 用途:
① FPGA内部两个模块的数据传输
② ZYNQ中PS与PL交互
二、AXI_LITE通道介绍
AXI协议中,有5条读写通道:
2条有关读的通道
· read address 读地址
· read data 读数据(与读响应合并)
3 条有关写的通道
· write address 写地址
· write data 写数据
· write response 写响应
总结: ① 读写分离。 ② 读没有读响应通道。
三,握手机制
五个通道想要进行数据交互首先需要进行双向握手,握手时,传输源(发送方)会产生 VALID 信号来指明此时的数据或控制信号是否有效,目的源(接收方)会产生 READY 信号来告诉传输源,是否已经准备好接收数据或控制信号了。只有当这两个信号都为高时,才算握手成功,传输源会在握手成功时的时钟上升沿进行一次数据传输。
这种双向流控机制使得发送与接收双方都有能力控制传输速率,通过控制 VALID 和 READY 的高低电平来控制传输的时机以及速度。
既然是握手机制,自然也就跟我们平时握手时一样,会有个先后顺序, VALID 和 READY 在握手时共有三种关系
1. VALID 信号先拉高, READY 信号后拉高
此时握手信号与数据以及时钟的关系如下:
此时握手信号与数据以及时钟的关系如下:
这里的 ACLK 为 AXI4的全局时钟,INFORMATION 为待传输的内容, VALID/READY 为握手信号。从图中可以看到,VALID 信号在 T1 信号之后到来 (拉高),与其一起来的还有数据、地址或者控制信号。而 READY 信号则是在 T2之后被拉高,因为错过了上升沿,直到T3时刻才被检测到,此时握手成功, 内容得以被传输。
AXI4 协议中规定,VALID 信号一旦拉高,在握手成功之前不能被拉低,因 此,VALID 信号会一直等待,直到在上升沿时刻检测到 READY 为高后 VALID 才能被拉低。
2. READY 信号先拉高,VALID 信号后拉高
此时握手信号与数据以及时钟的关系如下:
可以看到,T1 时刻之后 READY 信号拉高,而 VALID 信号则是在 T2 时刻 之后拉高,因为错过了时钟上升沿,所以在 T3 时刻才握手成功,此时, INFORMATION 中的信息被传输。
实际上,即使 READY 信号被拉高,只要 VALID 信号没有被拉高,接收方也可以拉低 READY 信号。例如,接收方置高 READY后,发现自己还有传输需 要完成,而此时发送方还没准备好数据(未置高VALID),这时候接收方便能够拉低 READY信号,转去处理其他传输,传输完成后再回来拉高 READY等待接 收数据。
3. VALID 信号和 READY 信号一起拉高
这种情况下就比较简单,READY 信号与 VALID 信号同时拉高,在下一个 时钟上升沿也就是 T2 被检测到,此时握手成功,INFORMATION 得以传输。
五个通道都有自己的握手信号对,对应的名称如下:
四、AXI_LITE端口信号及其功能
1. AXI_LITE 传输数据的位宽仅支持32位或64位的数据总线宽度,也就是WDATA和RDATA只能为32bit或者64bit。
2. WSTRB信号:
一般在使用中,wstrb信号全为1。
3. AWPORT、ARPORT信号
AWPORT信号,官方文档解释为:
写通道保护类型。该信号指示事务的特权和安全级别,以及事务是数据访问还是指令访问。
默认为3’b000即可。
4. BRESP和RRESP信号
其中,axi_lite 不支持 EXOKAY。
五,axi4_lite 读写过程
5.1 写过程
1、主机发送写地址和写数据的顺序关系:
主机可以先发送写地址,后发送写数据;
主机可以先发送写数据,后发送写地址;
主机可以同时发送写地址和写数据;
2、从机接收写地址和写数据的顺序关系:
从机可以先接收写地址,后接收写数据;
从机可以先接收写数据,后接收写地址;
从机可以同时接收写地址和写数据;
常用的模式为:
5.2 读过程
5.3 axi4_lite 读写过程框架图
根据读写过程分析:
用户写时,将写地址存放到wr_cmd_fifo中,将写数据存放到wr_data_fifo中,FIFO的dout传输到axi4_lite_master中。
用户读时,将读地址存放到rd_cmd_fifo中,从wr_data_fifo中读数据。
代码编写(顶层模块):
// -----------------------------------------------------------------------------
// Author : RLG
// File : axi4lite_master.v
// -----------------------------------------------------------------------------
`timescale 1ns / 1ps
module axi4lite_master#(
parameter USER_WR_DATA_WIDTH = 32,
parameter AXI_DATA_WIDTH = 32, //注意AXI4的数据位宽只有32bit或者64bit
parameter AXI_ADDR_WIDTH = 32,
parameter USER_RD_DATA_WIDTH = 32
)(
input user_wr_clk ,
input user_rd_clk ,
input axi_clk ,
input reset ,
input wire user_wr_we ,
input wire [USER_WR_DATA_WIDTH-1:0] user_wr_data ,
input wire [AXI_ADDR_WIDTH-1 :0] user_wr_addr ,
output wire user_wr_ready ,
input wire user_rd_en ,
input wire [AXI_ADDR_WIDTH-1 :0] user_rd_addr ,
output wire [USER_RD_DATA_WIDTH-1:0] user_rd_data ,
output wire user_rd_ready ,
output wire user_rd_vaild ,
output wire [AXI_ADDR_WIDTH-1:0] m_axi_awaddr ,
output wire [2:0] m_axi_awprot ,
output wire m_axi_awvalid ,
input wire m_axi_awready ,
output wire [AXI_DATA_WIDTH-1 :0] m_axi_wdata ,
output wire [AXI_DATA_WIDTH/8-1:0] m_axi_wstrb ,
output wire m_axi_wvalid ,
input wire m_axi_wready ,
input wire [1:0] m_axi_bresp , //wirte response channel
input wire m_axi_bvalid ,
output wire m_axi_bready ,
output wire [AXI_ADDR_WIDTH-1:0] m_axi_araddr ,
output wire [2:0] m_axi_arprot ,
output wire m_axi_arvalid ,
input wire m_axi_arready ,
input wire [AXI_DATA_WIDTH-1 :0] m_axi_rdata ,
input wire m_axi_rvalid ,
input wire [1:0] m_axi_rresp ,
output wire m_axi_rready
);
wire wr_data_fifo_err;
wire wr_cmd_fifo_err ;
wire rd_data_fifo_err;
wire rd_cmd_fifo_err ;
axi4lite_wr_channel #(
.USER_WR_DATA_WIDTH(USER_WR_DATA_WIDTH),
.AXI_DATA_WIDTH(AXI_DATA_WIDTH),
.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH)
) axi4lite_wr_channel (
.clk (user_wr_clk),
.axi_clk (axi_clk),
.reset (reset),
.user_wr_we (user_wr_we),
.user_wr_data (user_wr_data),
.user_wr_addr (user_wr_addr),
.user_wr_ready (user_wr_ready),
.m_axi_awaddr (m_axi_awaddr),
.m_axi_awprot (m_axi_awprot),
.m_axi_awvalid (m_axi_awvalid),
.m_axi_awready (m_axi_awready),
.m_axi_wdata (m_axi_wdata),
.m_axi_wstrb (m_axi_wstrb),
.m_axi_wvalid (m_axi_wvalid),
.m_axi_wready (m_axi_wready),
.m_axi_bresp (m_axi_bresp),
.m_axi_bvalid (m_axi_bvalid),
.m_axi_bready (m_axi_bready),
.wr_data_fifo_err (wr_data_fifo_err),
.wr_cmd_fifo_err (wr_cmd_fifo_err)
);
axi4lite_rd_channel #(
.USER_RD_DATA_WIDTH(USER_RD_DATA_WIDTH),
.AXI_DATA_WIDTH(AXI_DATA_WIDTH),
.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH)
) axi4lite_rd_channel (
.clk (user_rd_clk),
.axi_clk (axi_clk),
.reset (reset),
.user_rd_en (user_rd_en),
.user_rd_addr (user_rd_addr),
.user_rd_data (user_rd_data),
.user_rd_ready (user_rd_ready),
.user_rd_vaild (user_rd_vaild),
.m_axi_araddr (m_axi_araddr),
.m_axi_arprot (m_axi_arprot),
.m_axi_arvalid (m_axi_arvalid),
.m_axi_arready (m_axi_arready),
.m_axi_rdata (m_axi_rdata),
.m_axi_rvalid (m_axi_rvalid),
.m_axi_rresp (m_axi_rresp),
.m_axi_rready (m_axi_rready),
.rd_data_fifo_err (rd_data_fifo_err),
.rd_cmd_fifo_err (rd_cmd_fifo_err)
);
endmodule
仿真波形: