Zynq學習筆記之zynq_AXI4_Lite總線詳解

1,AXI總線與AXI接口以及AXI協議

總線,接口和協議,總線是一組傳輸通道,是各種邏輯器件構成的傳輸數據的通道,一般由數據線,地址線,控制線等組成。接口是一種連接標準,有常常被稱之爲物理接口。協議就是傳輸數據的規則。

1.1 AXI總線概述

在ZYNQ中支持三種AXI總線,擁有三種AXI接口,當然用的都是AXI協議。其中三種AXI總線分別爲:

AXI4:(For high-performance memory-mapped requirements)主要面向高性能地址映射通信的需求,是面向地址映射的接口,允許最大256輪的數據突發傳輸;

AXI4-Lite:(For simple,low-throughput memory-mapped communication)是一個輕量級的地址映射單此傳輸接口,佔用很少的邏輯單元。

AXI4-Stream:(For high-speed streaming data)面向高速流數據傳輸;去掉了地址項,允許無限制的數據突發傳輸規模。

首先說AXI4總線和AXI4-Lite總線具有相同的組成部分:

(1)讀地址通道,包含ARVALID,ARADDR,ARREADY信號;

(2)讀數據通道,包含RVALID,RDATA,RREADY,RRESP信號;

(3)寫地址通道,包含AWVALID,AWADDR,AWREADY信號;

(4)寫數據通道,包含WVALID,WDATA,WSTRB,WREADY信號;

(5)寫應答通道,包含BVALID,BRESP,BREADY信號;

(6)系統通道,包含ACLK,ARESETN信號。

AXI4-Stream總線的組成有:

(1),ACL信號:總線時鐘,上升沿有效;

(2),ARESETN信號:總線復位,低電平有效;

(3),TREADY信號:從機告訴主機做好傳輸準備了;

(4),TDATA信號:數據,可選寬度爲32,64,128,256bit;

(5),TSTRB信號:每一位Bit對應TDATA的一個有效字節,寬度爲TDATA/8;

(6),TLAST信號:主機告訴從機該次傳輸爲突發傳輸的結尾;

(7),TVALID信號:主機告訴從機數據本次傳輸有效;

(8),TUSER信號:用戶定義信號,寬度爲128bit

1.2 AXI接口介紹三種AXI接口分別是:

AXI-GP接口(4個):是通用的AXI接口,包括兩個32位主設備接口和兩個32位從設備接口,用該接口可以訪問PS中的片內外設。

AXI-HP接口(4個):是高性能/帶寬的標準的接口,PL模塊作爲主設備連接。主要用於PL訪問PS上的存儲器(DDR和on-chip ram)

AXI-ACP接口(1個):是ARM多核架構下定義的一種接口,中文翻譯爲加速器一致性端口,用來管理DMA之類的不帶緩存的AXI外設,PS端是Slave接口。

   我們可以雙擊查看ZYNQ的IP核的內部配置,就能發現上述的三種接口,圖中已用紅色方框標記出來,我們可以清楚的看出接口連接與總線的走向:

                              

1.3 AXI協議概述

AXI總線協議的兩端可以分爲主(master),從(slave)兩端,他們之間一般需要通過一個AXI Interconnect相連接,作用是提供將一個或多個AXI主設備連接到一個或多個AXI從設備的一種交換機制。當存在多個主機以及從機時,AXI Interconnect負責將它們聯繫並管理起來。由於AXI支持亂序傳送,亂序傳送需要主機的ID信號支撐,而不同的主機發送的ID可能不同,而AXI Interconnect解決了這一問題,他會對不同主機的ID信號進行處理讓ID變得唯一。

                                                              

AXI協議將讀地址通道,讀數據通道,寫地址通道,寫數據通道,寫響應通道分開,各自通道都有自己的握手協議。每個通道互不干擾卻又彼此依賴。這也是AXI高效的原因之一。

1.4 AXI協議之握手協議

AXI4所採用的是一種READY,VALID握手通信機制,簡單來說主從雙方進行數據通信前,有一個握手的過程。傳輸源產生VALID信號來指明何時數據或控制信息有效。而目的源產生READY信號來指明已經準備好接受數據或控制信息。傳輸發生在VALID和READY信號同時爲高的時候。VALID和READY信號的出現有三種關係。

(1)VALID先變高READY後變高。時序圖如下:

                               

(2)READY先變高VALID後變高。時序圖如下:

                                      

(3)VALID和READY信號同時變高。時序圖如下:

                                           

1.5 突發式讀寫

1,突發式讀的時序圖如下:

                              

當地址出現在地址總線後,傳輸的數據將出現在讀數據通道上。設備保持VALID爲低直到讀數據有效。爲了表明一次突發式讀寫的完成,設備用RLAST信號來表示最後一個被傳輸的數據。

2,突發式寫的時序如下:

                               

這一過程的開始,主機發送地址和控制信息到寫地址通道中,然後主機發送每一個寫數據到寫數據通道中。當主機發送最後一個數據時,WLAST信號就變爲高。當設備接受完所有數據之後他將一個寫響應發送回主機來表明寫事務完成。

2 AXI4-Lite詳解

2.1 AXI4-Lite源碼查看

Step1:要看到AXI-Lite的源碼,我們先要自定義一個AXI-Lite的IP,新建工程之後,選擇,菜單欄->Tools->Creat and Package IP:

                                                         

Step2:選擇Next

                                       

Step3:選擇Create AXI4 Peripheral,然後Next:

                                           

Step4:默認,選擇Next

                                         

Step5:注意這裏接口類型選擇Lite,選擇Next:

                                        

Step6:選擇Edit IP,點擊Finish:

                                        

Step7:此後,Vivado會新建一個工程,專門編輯該IP,通過該工程,我們就可以看到Vivado爲我們生成的AXI-Lite的操作源碼:

                             

2.2 AXI-Lite源碼分析

當打開頂層文件的時,映入眼簾的是一堆AXI的信號,這些信號是否似曾相識?

                             

                             

                             

我們先來看一段WDATA相關的代碼:

                             

                                 

這段程序的作用是,當PS那邊向AXI4-Lite總線寫數據時,PS這邊負責將數據接收到寄存器slv_reg。而slv_reg寄存器有0~3共4個。至於賦值給哪一個由axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB]決定,根據宏定義其實就是由

axi_awaddr[3:2] (寫地址中不僅包含地址,而且包含了控制位,這裏的[3:2]就是控制位)決定賦值給哪個slv_reg。

PS調用寫函數時,如果不做地址偏移的話,axi_awaddr[3:2]的值默認是爲0的,舉個例子,如果我們自定義的IP的地址被映射爲0x43C00000,那麼我們Xil_Out32(0x43C00000,Value)寫的就是slv_reg0的值。如果地址偏移4位,如Xil_Out32(0x43C00000 + 4,Value) 寫的就是slv_reg1的值,依次類推。分析時只關注slv_reg0(其他結構上也是一模一樣的):

                               

其中,C_S_AXI_DATA_WIDTH的宏定義的值爲32,也就是數據位寬,S_AXI_WSTRB就是寫選通信號,S_AXI_WDATA就是寫數據信號。

存在於for循環中的最關鍵的一句:slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];

當byte_index = 0的時候這句話就等價於:slv_reg0[7:0] <= S_AXI_WDATA[7:0];

當byte_index = 1的時候這句話就等價於:slv_reg0[15:8] <= S_AXI_WDATA[15:8];

當byte_index = 2的時候這句話就等價於:slv_reg0[23:16] <= S_AXI_WDATA[23:16];

當byte_index = 3的時候這句話就等價於:slv_reg0[31:24] <= S_AXI_WDATA[31:24];

也就是說,只有當寫選通信號爲1時,它所對應S_AXI_WDATA的字節纔會被讀取。

讀懂了這段話之後,我們就知道了,如果我們想得到PS寫到總線上的數據,我們只

需要讀取slv_reg0的值即可。

那如果,我們想寫數據到總線讓PS讀取該數據,我們該怎麼做呢?我們繼續來看有

關RADTA讀數據代碼:

                                          

觀察可知,當PS讀取數據時,程序會把reg_data_out複製給axi_rdata(RADTA讀數據)。我們繼續追蹤reg_data_out:

                                            

和前面分析的一樣此時通過判斷axi_awaddr[3:2]的值來判斷將那個值給reg_data_out上,同樣當PS調用讀取函數時,這裏axi_awaddr[3:2]默認是0,所以我們只需要把slv_reg0替換成我們自己數據,就可以讓PS通過總線讀到我們提供的數據。

                                       

寫應答,主要是回覆主機你這個寫過程是沒有問題的,那讀爲什麼不需要這個過程呢?

                                     

這時因爲主機在讀取數據時,從機可以直接通過讀數據通道給主機反饋信息,因此就沒有必要再來開闢一個單獨的應答通道了。

小結:

如果我們想讀AXI4_Lite總線上的數據時,只需關注slv_reg的數據,我們可自行添加一段代碼,如:

                                              

如果我們想對AXI4_Lite信號寫數據時,我們只需修改對reg_data_out的賦值,如:

                                             

                                            

 

最後強調下如果我們自定義的IP的地址被映射爲0x43C00000,那麼我們Xil_Out32(0x43C00000,Value)寫的就是slv_reg0的值。如果地址偏移4位,如Xil_Out32(0x43C00000 + 4,Value) 寫的就是slv_reg1的值,依次類推。

目前這裏只有4個寄存器,那是因爲之前選擇的是4個,其實我們可以定義的更多:

                                      

在ps的頭文件裏可以看到我們自定義的IP的地址是有個範圍的

理論上只要基地址 + 偏移量不要超過HIGHADDR即可。

總結:

    在ZYNQ中,支持AXI4-Lite,AXI4和AXI4-Stream三種總線協議,然而PS與PL之間的接口(AXI-GP接口,AXI-HP接口以及AXI-ACP接口)卻只支持AXI-Lite和AXI協議這兩種總線協議。也就是說PL這邊的AXI-Stream的接口是不能直接與PS對接的,需要經過AXI4或者AXI4-Lite的轉換。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章