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

发布于:2025-05-09 ⋅ 阅读:(19) ⋅ 点赞:(0)


参考手册
《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,则WSTRB[3: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代码参考如下:

`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的逻辑代码实现与仿真


网站公告

今日签到

点亮在社区的每一天
去签到