【AXI總線專題】-AXI-LITE總線解讀
- 1.axi-lite概述
- 2.信號定義
- Write address channel
- Write data channel
- Write response channel
- Read address channel
- Read data channel
- 3.測試
- 4.仿真波形
- 5.工程文件
參考手冊
《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 beginrst = 0;#100;@(posedge clk)rst = 1;
end always beginclk = 0;#10;clk = 1;#10;
endparameter 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_taskri_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
endtasktask read_data(input [31:0] addr);
begin:read_taskri_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
endtaskinitial
beginri_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);forkwrite_data(1,99);//使用fork需要注意的是,這兩句代碼是并行執行,不是順序執行的read_data(1);//也就是同時執行寫和讀的操作joinendendmodule
4.仿真波形
下圖所示,是在tb中執行用戶端口信號的操作
首先是往地址為10的空間寫入數據100;然后再執行讀地址100處的數據,這里就有先寫后讀的順序
其次是往地址為1的空間寫入數據99;同時執行讀操作。這里的寫和讀就是同時進行的
用戶側的邏輯代碼,到axi這里實現的效果如下。
在上面我們執行往地址1處寫入數據99的操作,同時執行讀操作。到axi這里就進行了仲裁,把原來同時進行的讀寫,這里進行了變換,可以看出,先往地址1上寫入數據99;然后再執行了讀的操作。
5.工程文件
基于axi-lite-master的邏輯代碼實現與仿真