【AXI总线专题】-AXI-LITE总线解读

【AXI总线专题】-AXI-LITE总线解读

参考手册
《3-2-03米联客2022版AXI4总线专题-20211123.pdf》
《IHI0022E_amba_axi_and_ace_protocol_spec.pdf》
内容已包含在下载文件中

1.axi-lite概述

AXI-LITE总线只支持单次突发,也就是说每次传输只能传一个数据。另外,传输的数据位宽只支持32bit或者64bit

2.信号定义

Write address channel


AWPORT一般默认为0,定义为:

output wire 2 : 0 M_AXI_AWPROT,

Write data channel

这里的WSTRB类似与掩码。如果总线位宽为32bit,则WSTRB3:0=4'b1111,表示32bit位宽的数据每一位都是有效的。

Write response channel

BRESP反馈信号的值,返回值为0表示OKAY;注意这里的valid的方向,是从机到主机,和上面的写地址通道以及写数据通道是反方向的。

Read address channel

Read data channel

3.测试

使用代码手动实现一个axi-lite-master的功能。用户可以通过该代码,对axi-lite-slave进行读写操作。

需要注意的是,该代码中使用了fifo对数据进行缓存。目的是axi-lite只支持单次突发,也就是一次只能传输一个数据。但是用户侧如果在执行写操作的时候,往往会一次性写入很多数据,这里就需要通过fifo执行缓存,数据先写入fifo,然后再慢慢通过axi-lite发送出去。

axi-lite-slave使用官方生成的代码。

仿真tb代码参考如下:

c 复制代码
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2025/05/07 15:25:31
// Design Name: 
// Module Name: sim_top_tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module sim_top_tb();

reg clk,rst;

initial begin
    rst = 0;
    #100;
    @(posedge clk)rst = 1;
end 

always begin
    clk = 0;
    #10;
    clk = 1;
    #10;
end

parameter                       P_ADDR_WIDTH = 32;
parameter                       P_DATA_WIDTH = 32;  
wire                           M_AXI_ACLK        ;
wire                           M_AXI_ARESETN     ;

wire  [P_ADDR_WIDTH - 1 : 0]   M_AXI_AWADDR      ;
wire  [2 :0]                   M_AXI_AWPROT      ;
wire                           M_AXI_AWVALID     ;
wire                           M_AXI_AWREADY     ;

wire  [P_DATA_WIDTH - 1   : 0] M_AXI_WDATA       ;
wire  [P_DATA_WIDTH/8 - 1 : 0] M_AXI_WSTRB       ;
wire                           M_AXI_WVALID      ;
wire                           M_AXI_WREADY      ;

wire  [1 :0]                   M_AXI_BRESP       ;
wire                           M_AXI_BVALID      ;
wire                           M_AXI_BREADY      ;

wire  [P_ADDR_WIDTH - 1 : 0]   M_AXI_ARADDR      ;
wire  [2 :0]                   M_AXI_ARPROT      ;
wire                           M_AXI_ARVALID     ;
wire                           M_AXI_ARREADY     ;

wire  [P_DATA_WIDTH - 1   : 0] M_AXI_RDATA       ;
wire  [1 :0]                   M_AXI_RRESP       ;
wire                           M_AXI_RVALID      ;
wire                           M_AXI_RREADY      ;
reg  [P_ADDR_WIDTH - 1:0]     ri_write_addr      ;
reg  [P_DATA_WIDTH - 1:0]     ri_write_data      ;
reg                           ri_write_valid     ;
reg  [P_ADDR_WIDTH - 1:0]     ri_read_addr       ;
reg                           ri_read_valid      ;
wire  [P_DATA_WIDTH - 1:0]    w_read_data        ;
wire                          w_read_data_valid  ;

assign  M_AXI_ACLK     =  clk;  
assign  M_AXI_ARESETN  =  rst;
//assign  M_AXI_WSTRB    =  1;

AXI_LITE_Master#(
    .P_ADDR_WIDTH        (P_ADDR_WIDTH     ) ,
    .P_DATA_WIDTH        (P_DATA_WIDTH     ) //axi-lite总线支持32bit和64bit两种位宽
)
AXI_LITE_Master_u0
(         
    /*----axi lite----*/ 
    .M_AXI_ACLK          (M_AXI_ACLK       ),
    .M_AXI_ARESETN       (M_AXI_ARESETN    ),  
    .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_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     ),     
    .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_RRESP         (M_AXI_RRESP      ),
    .M_AXI_RVALID        (M_AXI_RVALID     ),
    .M_AXI_RREADY        (M_AXI_RREADY     ),

    /*----user prot----*/
    /*为什么分axi接口和用()户接口。这里的是将用户自定义接口转成axi接口,这样就可以和axi接口的其他IP直接相连*/
    .i_write_addr        (ri_write_addr    ),
    .i_write_data        (ri_write_data    ),
    .i_write_valid       (ri_write_valid   ),     
    .i_read_addr         (ri_read_addr     ),
    .i_read_valid        (ri_read_valid    ),
    .o_read_data         (w_read_data      ),
    .o_read_data_valid   (w_read_data_valid)
);


axi_lite_slave_v1_0_S00_AXI #
	(
		.C_S_AXI_DATA_WIDTH	(P_DATA_WIDTH),
		.C_S_AXI_ADDR_WIDTH	(P_ADDR_WIDTH)
	)
axi_lite_slave_v1_0_S00_AXI_u0
	(
		.S_AXI_ACLK        (M_AXI_ACLK    ),
		.S_AXI_ARESETN     (M_AXI_ARESETN ),
		.S_AXI_AWADDR      (M_AXI_AWADDR  ),
		.S_AXI_AWPROT      (M_AXI_AWPROT  ),
		.S_AXI_AWVALID     (M_AXI_AWVALID ),
		.S_AXI_AWREADY     (M_AXI_AWREADY ),
		.S_AXI_WDATA       (M_AXI_WDATA   ),   
		.S_AXI_WSTRB       (M_AXI_WSTRB   ),
		.S_AXI_WVALID      (M_AXI_WVALID  ),
		.S_AXI_WREADY      (M_AXI_WREADY  ),
		.S_AXI_BRESP       (M_AXI_BRESP   ),
		.S_AXI_BVALID      (M_AXI_BVALID  ),
		.S_AXI_BREADY      (M_AXI_BREADY  ),
		.S_AXI_ARADDR      (M_AXI_ARADDR  ),
		.S_AXI_ARPROT      (M_AXI_ARPROT  ),
		.S_AXI_ARVALID     (M_AXI_ARVALID ),
		.S_AXI_ARREADY     (M_AXI_ARREADY ),
		.S_AXI_RDATA       (M_AXI_RDATA   ),
		.S_AXI_RRESP       (M_AXI_RRESP   ),
		.S_AXI_RVALID      (M_AXI_RVALID  ),
		.S_AXI_RREADY      (M_AXI_RREADY  )
	);


task write_data(input [31:0] addr,input [31:0]data);
begin:write_task
    ri_write_addr  <= 'd0;
    ri_write_data  <= 'd0;
    ri_write_valid <= 'd0;
    @(posedge clk);
    ri_write_addr  <= addr;
    ri_write_data  <= data;
    ri_write_valid <= 'd1;
    @(posedge clk);
    ri_write_addr  <= 'd0;
    ri_write_data  <= 'd0;
    ri_write_valid <= 'd0;
    @(posedge clk);
end
endtask

task read_data(input [31:0] addr);
begin:read_task
    ri_read_addr   <= 'd0;
    ri_read_valid  <= 'd0;
    @(posedge clk);
    ri_read_addr   <= addr;
    ri_read_valid  <= 'd1;
    @(posedge clk);
    ri_read_addr   <= 'd0;
    ri_read_valid  <= 'd0;
    @(posedge clk);
end
endtask

initial
begin
    ri_write_addr  = 0;
    ri_write_data  = 0;
    ri_write_valid = 0;
    ri_read_addr   = 0;
    ri_read_valid  = 0;
    wait(rst);//wait后面的括号中填的是退出等待的条件
    repeat(10);
    write_data(10,100);//这边的代码是顺序执行的,先写再读
    read_data(10);
    fork
        write_data(1,99);//使用fork需要注意的是,这两句代码是并行执行,不是顺序执行的
        read_data(1);//也就是同时执行写和读的操作
    join

end

endmodule

4.仿真波形

下图所示,是在tb中执行用户端口信号的操作

首先是往地址为10的空间写入数据100;然后再执行读地址100处的数据,这里就有先写后读的顺序

其次是往地址为1的空间写入数据99;同时执行读操作。这里的写和读就是同时进行的

用户侧的逻辑代码,到axi这里实现的效果如下。

在上面我们执行往地址1处写入数据99的操作,同时执行读操作。到axi这里就进行了仲裁,把原来同时进行的读写,这里进行了变换,可以看出,先往地址1上写入数据99;然后再执行了读的操作。

5.工程文件

基于axi-lite-master的逻辑代码实现与仿真

相关推荐
szxinmai主板定制专家7 小时前
基于 RK3588 + Xilinx Kintex-7 FPGA 异构工业主控板设计方案
arm开发·人工智能·嵌入式硬件·fpga开发·zynq
szxinmai主板定制专家3 天前
Zynq MPSoC实现半导体真空腔体状态监测|FPGA多传感器时序同步采集方案
fpga开发·zynq·控制器·mpsoc·半导体设备·fpga同步
szxinmai主板定制专家3 天前
Zynq MPSoC半导体高精度运动控制方案|FPGA硬件插补实现亚微米级伺服实时控制
人工智能·嵌入式硬件·fpga开发·zynq·运动控制·ethercat
jz_ddk4 天前
[学习] 深入理解 USB 通信与 FPGA 实现:从协议到逻辑设计
学习·fpga开发·xilinx·usb2.0
燕卫博5 天前
借助AI的力量,将 ZYNQ 开发板改造成一个虚拟专用网络网关
人工智能·串口·嵌入式·zynq·reasonix·ser2mcp
szxinmai主板定制专家10 天前
基于Zynq MPSoC的多路GMSL相机同步采集与低延迟图像预处理系统|车载视觉高速解决方案
人工智能·zynq·gmsl·rk3588+fpga·rk3576+fpga
szxinmai主板定制专家10 天前
ZYNQ高速数据采集卡设计:1M采样率实现IEPE传感器信号采集
人工智能·数据采集·zynq·rk3588+fpga·rk3576+fpga·振动采集
Echo_cy_21 天前
基于ZYNQ-7000的Ethernet驱动配置
linux·驱动开发·嵌入式硬件·fpga开发·ethernet·zynq
神电测控22 天前
新品发布:国产新型三合一多功能PG-ZYNQ7100 sbRIO板卡(PCIe+USB3.0+Ethernet+FMC+4个40pin扩展口)
fpga·zynq·crio·神电测控·王电令·sbrio·linuxrt
忆锦紫1 个月前
vivado报错及解决【十一】
fpga开发·fpga·vivado·xilinx