当前位置:网站首页>FPGA实现AXI4总线的读写
FPGA实现AXI4总线的读写
2022-07-24 06:28:00 【庸医~】
一、AXI4 接口描述
通道 | 信号 | 源 | 信号描述 |
全局信号 | aclk | 主机 | 全局时钟 |
aresetn | 主机 | 全局复位,低有效 | |
写通道地址与控制信号通道 | M_AXI_WR_awid[3:0] | 主机 | 写地址ID,用来标志一组写信号 |
M_AXI_WR_awaddr[31:0] | 主机 | 写地址,给出一次写突发传输的写地址 | |
M_AXI_WR_awlen[7:0] | 主机 | 突发长度,给出突发传输的次数 | |
M_AXI_WR_awsize[2:0] | 主机 | 突发大小,给出每次突发传输的字节数 | |
M_AXI_WR_awburst[1:0] | 主机 | 突发类型 | |
M_AXI_WR_awlock | 主机 | 总线锁信号,可提供操作的原子性 | |
M_AXI_WR_awcache[3:0] | 主机 | 内存类型,表明一次传输是怎样通过系统的 | |
M_AXI_WR_awprot[2:0] | 主机 | 保护类型,表明一次传输的特权级及安全等级 | |
M_AXI_WR_awqos[3:0] | 主机 | 质量服务QoS | |
M_AXI_WR_awvalid | 主机 | 有效信号,表明此通道的地址控制信号有效 | |
M_AXI_WR_awready | 从机 | 表明“从”可以接收地址和对应的控制信号 | |
写通道数据通道 | M_AXI_WR_wdata[63:0] | 主机 | 写数据 |
M_AXI_WR_wstrb[7:0] | 主机 | 写数据有效的字节线,用来表明哪8bits数据是有效的 | |
M_AXI_WR_wlast | 主机 | 表明此次传输是最后一个突发传输 | |
M_AXI_WR_wvalid | 主机 | 写有效,表明此次写有效 | |
M_AXI_WR_wready | 从机 | 表明从机可以接收写数据 | |
写通道响应通道 | M_AXI_WR_bid[3:0] | 从机 | 写响应ID TAG |
M_AXI_WR_bresp[1:0] | 从机 | 写响应,表明写传输的状态 | |
M_AXI_WR_bvalid | 从机 | 写响应有效 | |
M_AXI_WR_bready | 主机 | 表明主机能够接收写响应 | |
读通道地址与控制信号通道 | M_AXI_RD_arid[3:0] | 主机 | 读地址ID,用来标志一组写信号 |
M_AXI_RD_araddr[31:0] | 主机 | 读地址,给出一次写突发传输的读地址 | |
M_AXI_RD_arlen[7:0] | 主机 | 突发长度,给出突发传输的次数 | |
M_AXI_RD_arsize[2:0] | 主机 | 突发大小,给出每次突发传输的字节数 | |
M_AXI_RD_arburst[1:0] | 主机 | 突发类型 | |
M_AXI_RD_arlock[1:0] | 主机 | 总线锁信号,可提供操作的原子性 | |
M_AXI_RD_arcache[3:0] | 主机 | 内存类型,表明一次传输是怎样通过系统的 | |
M_AXI_RD_arprot[2:0] | 主机 | 保护类型,表明一次传输的特权级及安全等级 | |
M_AXI_RD_arqos[3:0] | 主机 | 质量服务QOS | |
M_AXI_RD_arvalid | 主机 | 有效信号,表明此通道的地址控制信号有效 | |
M_AXI_RD_arready | 从机 | 表明“从”可以接收地址和对应的控制信号 | |
读通道数据通道 | M_AXI_RD_rid[3:0] | 从机 | 读IDtag |
M_AXI_RD_rdata[63:0] | 从机 | 读数据 | |
M_AXI_RD_rresp[1:0] | 从机 | 读响应,表明读传输的状态 | |
M_AXI_RD_rlast | 从机 | 表明读突发的最后一次传输 | |
M_AXI_RD_rvalid | 从机 | 表明此通道信号有效 | |
M_AXI_RD_rready | 主机 | 表明主机能够接收读数据和响应信息 |
二、地址通道的控制信号与地址描述
1、地址ID
AWID[3:0]与ARID[3:0]:对于只有一个主机从机设备,该值可设置为任意
2、地址结构
AWADDR[31:0]与ARADDR[31:0]:AXI协议是基于burst(突发)的,主机只给出突发传输的第一个字节的地址,从机必须计算突发传输后续的地址。突发传输不能跨4KB边界(防止突发跨越两个从机的边界,也限制了从机所需支持的地址自增数
3、突发长度
AWLEN[7:0]与ARLEN[7:0]:ARLEN[7:0]决定读传输的突发长度,AWLEN[7:0]决定写传输的突发长度。AXI4扩展突发长度支持INCR突发类型为1~256次传输,对于其他的传输类型依然保持1~16次突发传输(Burst_Length=AxLEN[7:0]+1)
4、突发大小
ARSIZE[2:0],读突发传输;AWSIZE[2:0],写突发传输。
AxSIZE[2:0] | 传输字节大小 |
3'b000 | 1 |
3'b001 | 2 |
3'b010 | 4 |
3'b011 | 8 |
3'b100 | 16 |
3'b101 | 32 |
3'b110 | 64 |
3'b111 | 128 |
5、突发类型
AWBURST[1:0]与ARBURST[1:0]:
AxBURST[1:0] | 突发类型 |
2'b00 | FIXED |
2'b01 | INCR |
2'b10 | WRAP |
2'b11 | Reserved |
FIXED:突发传输过程中地址固定,用于FIFO访问
INCR:增量突发,传输过程中,地址递增。增加量取决AxSIZE的值
WRAP:回环突发,和增量突发类似,但会在特定高地址的边界处回到低地址处。回环突发的长度只能是2,4,8,16次传输,传输首地址和每次传输的大小对齐。最低的地址整个传输的数据大小对齐。回环边界等于(AxSIZE*AxLEN)
三、数据通道信号描述
1、WDATA与RDATA:写与读数据线信号
WSTRB:有效字节,WSTRB[n:0]对应于对应的写字节,WSTRB[n]对应WDATA[8n+7:8n],也就是对于的数据宽度的字节数是否有效。WVALID为低时,WSTRB可以为任意值,WVALID为高时,WSTRB为高的字节线必须指示有效的数据。对于一般应用,将WSTRB全部置1即可,保证全部数据有效。读通道无该信号。
2、WLAST与RLAST
写与读最后一个字节,拉高表示传输最后一个字节,也意味着传输结束
3、burst[1:0]
描述读写相应结构
burst[1:0] | |
00 | 常规访问成功 |
01 | 独占访问成功 |
10 | 从机错误 |
11 | 解码错误 |
四、突发写时序:
AXI4突发写可以分为7个状态,写空闲,写通道写地址等待,写通道写地址,写数据等待,写数据循环,接受写应答,写结束这7种状态。之所以划分为7个状态是为了后续写程序的状态机做准备。
7种状态
1、写空闲:等待触发突发信号
2、写通道写地址等待:准备好写地址AWADDR,然后拉高AWVALID。
3、写通道写地址:从机接受到AWVALID,发出AWREADY。
4、写数据等待:准备好数据WDATA,拉高WVALID。
5、写数据循环:从机接受WVALID,确认数据WDATA有效并且接受,发出WREADY,AXI是突发传输:循环该操作到接受到WLAST最后一个数据标志位。
6、接受写应答:接受到从机发出的BVALID,主机发出BREADY。
7、写结束:拉低未拉低的信号,进入写空闲

五、突发读时序
AXI4突发读可以分为6个状态,读空闲,读通道写地址等待,读通道写地址,读数据等待,读数据循环,读结束这6种状态。之所以划分为6个状态是为了后续写程序的状态机做准备。
6种状态
1、读空闲:等待触发突发信号。
2、读通道写地址等待:准备好写地址ARADDR,然后拉高ARVALID。
3、读通道写地址:从机接受到ARVALID,发出ARREADY。
4、读数据等待:从机准备好数据WDATA,从机拉高RVALID。
5、读数据循环:主机接受RVALID,确认数据RDATA有效并且接受,发出RREADY给从机,AXI是突发传输:循环该操作到接受到RLAST最后一个数据标志位
6、读结束:拉低未拉低的信号,进入读空闲

注:
1、读数据必须总是跟在与其数据相关联的地址之后。
2、写响应必须总是跟在与其相关联的写事务的最后出现。
六、写时序状态机

七、写时序代码
module axi4_write(
input clk ,
input resetn ,
input enable_write , //写使能
input [31:0] w_addr , //地址
input [63:0] w_data , //数据
output reg write_done , //写完成
output reg write_data , //表示数据写入,突发模式下可用于切换数据的指示信号
//axi4写通道地址通道
output [3:0] m_axi_awid , //写地址ID,用来标志一组写信号
output reg[31:0] m_axi_awaddr ,//写地址,给出一次写突发传输的写地址
output [7:0] m_axi_awlen , //突发长度,给出突发传输的次数
output [2:0] m_axi_awsize , //突发大小,给出每次突发传输的字节数
output [1:0] m_axi_awburst , //突发类型
output m_axi_awlock , //总线锁信号,可提供操作的原子性
output [3:0] m_axi_awcache , //内存类型,表明一次传输是怎样通过系统的
output [2:0] m_axi_awprot , //保护类型,表明一次传输的特权级及安全等级
output [3:0] m_axi_awqos , //质量服务QoS
output reg m_axi_awvalid , //有效信号,表明此通道的地址控制信号有效
input m_axi_awready , //表明“从”可以接收地址和对应的控制信号
//axi4写通道数据通道
output reg[63:0] m_axi_wdata , //写数据
output [7:0] m_axi_wstrb , //写数据有效的字节线
output reg m_axi_wlast , //表明此次传输是最后一个突发传输
output reg m_axi_wvalid , //写有效,表明此次写有效
input m_axi_wready , //表明从机可以接收写数据
//axi4写通道应答通道
input [3:0] m_axi_bid , //写响应ID TAG
input [1:0] m_axi_bresp , //写响应,表明写传输的状态
input m_axi_bvalid , //写响应有效
output reg m_axi_bready //表明主机能够接收写响应
);
//*******************参数*****************************
localparam W_IDLEW = 3'b001 ; //空闲等待
localparam W_DRIVEW = 3'b011 ; //准备、取地址
localparam W_HANDS = 3'b010 ; //握手
localparam W_WSTBR = 3'b110 ; //突发
localparam W_WAIT = 3'b111 ; //等待结束的信息
localparam W_END = 3'b101 ; //写数据阶段
parameter LEN_NUM = 1 ;
parameter AWID = 0 ;
//*********内部信号******************************
reg [2:0] state , next_state ;
reg wready_over ;
reg [7:0] len ;
assign m_axi_awid = AWID[3:0] ; // [3:0] //写地址ID,用来标志一组写信号
assign m_axi_awlen = LEN_NUM-1 ; // [7:0] //突发长度,给出突发传输的次数
assign m_axi_awsize = 3'b011 ; // [2:0] //突发大小,给出每次突发传输的字节数
assign m_axi_awburst = 2'b10 ; // [1:0] //突发类型
assign m_axi_awlock = 1'b0 ; // //总线锁信号,可提供操作的原子性
assign m_axi_awcache = 4'b0010 ; // [3:0] //内存类型,表明一次传输是怎样通过系统的
assign m_axi_awprot = 3'b000 ; // [2:0] //保护类型,表明一次传输的特权级及安全等级
assign m_axi_awqos = 4'b0000 ; // [3:0] //质量服务QoS
assign m_axi_wstrb = 8'hff ;
//状态机
always @(*) begin
state = next_state ;
end
always @(posedge clk or negedge resetn) begin
if(!resetn) begin
wready_over<=0;
end
else if(state==W_IDLEW || state==W_END )
wready_over<=0;
else if(m_axi_wready)
wready_over<=1;
end
always @(posedge clk or negedge resetn) begin
if(!resetn) begin
next_state <= W_IDLEW ;
len <=0 ;
end
else case(state)
W_IDLEW : if(enable_write) next_state <= W_DRIVEW ; else next_state<=W_IDLEW ;
W_DRIVEW: if(m_axi_awready) begin
next_state <= W_HANDS ;
len<=LEN_NUM-1 ;
end
else next_state<=W_DRIVEW ;
W_HANDS : if(wready_over && len==0)
next_state <= W_WAIT ;
else if(wready_over ) next_state <= W_WSTBR ;
else next_state<=W_HANDS ;
W_WSTBR : if(len==1) next_state <= W_WAIT ;
else begin
next_state <= W_WSTBR ;
len <=len-1 ;
end
W_WAIT : next_state<=W_END ;
W_END : if(m_axi_bvalid)next_state <= W_IDLEW ; else next_state<=W_END ;
default : next_state<=W_IDLEW ;
endcase
end
// 组合逻辑输出
always @(* ) begin
case(state)
W_IDLEW : begin
m_axi_wlast = 0 ;
m_axi_awaddr = 0 ;
m_axi_awvalid = 0 ;
m_axi_wdata = 0 ;
m_axi_wvalid = 0 ;
m_axi_bready = 0 ;
write_done = 0 ;
write_data = 0 ;
end
W_DRIVEW: begin
m_axi_wlast = 0 ;
m_axi_awaddr = w_addr ;
m_axi_awvalid = 1 ;
m_axi_wdata = 0 ;
m_axi_wvalid = 0 ;
m_axi_bready = 0 ;
write_done = 0 ;
write_data = 0 ;
end
W_HANDS : begin
m_axi_wlast = 0 ;
m_axi_awaddr = 0 ;
m_axi_awvalid = 0 ;
m_axi_wdata = 0 ;
m_axi_wvalid = 0 ;
m_axi_bready = 0 ;
write_done = 0 ;
write_data = 0 ;
end
W_WSTBR : begin
m_axi_wlast = 0 ;
m_axi_awaddr = 0 ;
m_axi_awvalid = 0 ;
m_axi_wdata = w_data ;
m_axi_wvalid = 1 ;
m_axi_bready = 0 ;
write_done = 0 ;
write_data = 1 ;
end
W_WAIT : begin
m_axi_wlast = 1 ;
m_axi_awaddr = 0 ;
m_axi_awvalid = 0 ;
m_axi_wdata = w_data ;
m_axi_wvalid = 1 ;
m_axi_bready = 0 ;
write_done = 1 ;
write_data = 1 ;
end
W_END : begin
m_axi_wlast = 0 ;
m_axi_awaddr = 0 ;
m_axi_awvalid = 0 ;
m_axi_wdata = 0 ;
m_axi_wvalid = 0 ;
m_axi_bready = 1 ;
write_done = 0 ;
write_data = 0 ;
end
default : begin
m_axi_wlast = 0 ;
m_axi_awaddr = 0 ;
m_axi_awvalid = 0 ;
m_axi_wdata = 0 ;
m_axi_wvalid = 0 ;
m_axi_bready = 0 ;
write_done = 0 ;
write_data = 0 ;
end
endcase
end
endmodule八、读时序状态机

九、读时序代码
module axi4_read(
input resetn ,//axi复位
input clk , //axi时钟
input enable_read ,
output read_data ,
output read_done ,
input [31:0] r_addr ,
output reg [63:0] r_data ,
//axi读通道写地址
output [3:0] m_axi_arid , //读地址ID,用来标志一组写信号
output reg [31:0] m_axi_araddr , //读地址,给出一次写突发传输的读地址
output [7:0] m_axi_arlen , //突发长度,给出突发传输的次数
output [2:0] m_axi_arsize , //突发大小,给出每次突发传输的字节数
output [1:0] m_axi_arburst , //突发类型
output [1:0] m_axi_arlock , //总线锁信号,可提供操作的原子性
output [3:0] m_axi_arcache , //内存类型,表明一次传输是怎样通过系统的
output [2:0] m_axi_arprot , //保护类型,表明一次传输的特权级及安全等级
output [3:0] m_axi_arqos , //质量服务QOS
output reg m_axi_arvalid , //有效信号,表明此通道的地址控制信号有效
input m_axi_arready , //表明“从”可以接收地址和对应的控制信号
//axi读通道读数据
input [3:0] m_axi_rid , //读ID tag
input [63:0] m_axi_rdata , //读数据
input [1:0] m_axi_rresp , //读响应,表明读传输的状态
input m_axi_rlast , //表明读突发的最后一次传输
input m_axi_rvalid , //表明此通道信号有效
output reg m_axi_rready //表明主机能够接收读数据和响应信息
);
//
localparam [2:0] R_IDLER = 3'b001 ;
localparam [2:0] R_WAIT = 3'b011 ;
localparam [2:0] R_BURST = 3'b010 ;
localparam [2:0] R_END = 3'b110 ;
parameter ARID = 0 ;
parameter RD_LEN = 1 ;
//
reg [2:0] state , next_state ;
reg rvalid_over ;
//
assign m_axi_arid = ARID[3:0] ;//地址id
assign m_axi_arlen = RD_LEN-32'd1 ;//突发长度
assign m_axi_arsize = 3'b011 ;//表示AXI总线每个数据宽度是8字节,64位
assign m_axi_arburst = 2'b01 ;//地址递增方式传输
assign m_axi_arlock = 1'b0 ;
assign m_axi_arcache = 4'b0010 ;
assign m_axi_arprot = 3'b000 ;
assign m_axi_arqos = 4'b0000 ;
assign read_data = m_axi_rvalid ;
assign read_done = m_axi_rlast ;
//axi读状态机
always @(*) begin
state = next_state ;
end
//
always @(posedge clk or negedge resetn) begin
if(!resetn) begin
rvalid_over <=0 ;
end
else if(state==R_IDLER) begin
rvalid_over <=0 ;
end
else if(m_axi_rvalid)begin
rvalid_over <= 1 ;
end
end
always @(posedge clk or negedge resetn) begin
if(!resetn)
next_state <= R_IDLER;
else case(state)
R_IDLER : if(enable_read) next_state <= R_WAIT ;else next_state<=R_IDLER ;
R_WAIT : if(m_axi_arready) next_state<=R_BURST ;else next_state<=R_WAIT ;
R_BURST : if(m_axi_rlast) next_state<=R_END ;else next_state <= R_BURST ;
R_END : if(rvalid_over) next_state<=R_IDLER;else next_state<=R_END ;
default : next_state<=R_IDLER ;
endcase
end
//
always @(*) begin
case(state)
R_IDLER : begin
m_axi_araddr = 0 ;
m_axi_arvalid = 0 ;
m_axi_rready = 0 ;
r_data = 0 ;
end
R_WAIT : begin
m_axi_araddr = r_addr ;
m_axi_arvalid = 1 ;
m_axi_rready = 0 ;
r_data = 0 ;
end
R_BURST : begin
m_axi_araddr = 0 ;
m_axi_arvalid = 0 ;
m_axi_rready = 1 ;
r_data = m_axi_rdata ;
end
R_END : begin
m_axi_araddr = 0 ;
m_axi_arvalid = 0 ;
m_axi_rready = 1 ;
r_data = 0 ;
end
default : begin
m_axi_araddr = 0 ;
m_axi_arvalid = 0 ;
m_axi_rready = 0 ;
r_data = 0 ;
end
endcase
end
endmodule边栏推荐
- MySQL gets the self incrementing line mark (different from MySQL version)
- 华为专家自述:如何成为优秀的工程师
- You are you, and no one can replace you
- reflex
- 自己的人生无须浪费在别人的标准中
- Don't compare with anyone, just be yourself
- Libc.so.6/glibc cross compilation
- Day (0~6) represents the starting position of the first day of each month, stop represents the number of days of each month, and there are two blank spaces between each day. Input different days and s
- Libevent and multithreading
- 你不可能让每个人都满意!
猜你喜欢

Introduction to pyqt5 - student management system

tensorflow einsum函数

UE4/5 无法打开文件“xxx.generated.h”(Cannot open file xxx.generated.h)的解决方法总结

Redis 持久化

Thinking of data analysis -- analyzing the retail industry as a whole -- an all-round and multifaceted detailed analysis

Sparksql core usage, 220724,

上传excel文件

变量和数据类型(04)完结

OWASP TOP10 penetration test

tensorflow scatter_ Nd function
随机推荐
Three level classification / menu query tree structure
一日一书:机器学习及实践——从零开始通往kaggle竞赛之路
[wechat applet] understand conditional rendering, list rendering and wxss template style
[USB voltmeter and ammeter] Based on stm32f103c8t6 for Arduino
Penetration learning - SQL injection - shooting range - installation and bypass experiment of safety dog (it will be updated later)
Job search memo
(note sorting is not completed) [graph theory: find the shortest path of single source]
One book a day: machine learning and practice -- the road to the kaggle competition from scratch
C language to achieve three chess? Gobang? No, it's n-chess
MySql的DDL和DML和DQL的基本语法
(笔记整理未完成)【图论:求单源最短路径】
metaRTC5.0实现君正的纯C的webrtc版IPC
Lambda expressions sort list objects in multiple fields
10分钟就能写出来的——25~30K的国外企业招聘面试考题,这不是轻轻松松吗~
HashSet to array
Design a function print to print the string. If only the string parameter s is passed, the string length is compared with 10, greater than 10, print the first 10 characters, less than 10, and output a
【C语言】操作符详解(深入理解+整理归类)
Don't care too much about what others think of you
Vs2019 configuration running open3d example
MGR_ mysqlsh_ Keepalive high availability architecture deployment document