FPGA實現AXI4總線的讀寫_如何寫axi4邏輯
一、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突發類型為1256次傳輸,對于其他的傳輸類型依然保持116次突發傳輸(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
原文鏈接:
https://tencentcloud.csdn.net/678a0c64edd0904849a660e1.html
-
FPGA
+關注
關注
1630文章
21785瀏覽量
605052 -
接口
+關注
關注
33文章
8685瀏覽量
151643 -
時序
+關注
關注
5文章
392瀏覽量
37380 -
AXI4總線
+關注
關注
0文章
9瀏覽量
1412
原文標題:FPGA實現AXI4總線的讀寫_如何寫axi4邏輯
文章出處:【微信號:gh_9d70b445f494,微信公眾號:FPGA設計論壇】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論