AXI 總線/接口/協議
總線是一組傳輸通道,是各種邏輯器件構成的傳輸數據的通道,一般由由數據線、地址線、控制線等構成。
接口是一種連接標準,又常常被稱之爲物理接口。
協議就是傳輸數據的規則。
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 總線和 AXI4-Lite 總線的信號也有他的命名特點讀地址信號都是以 AR 開頭(A:address;R:read)寫地址信號都是以 AW 開頭(A:address;W:write)讀數據信號都是以 R 開頭(R:read)寫數據信號都是以 W 開頭(W:write)應答型號都是以 B 開頭(B:back(answer back))
AXI4-Stream 總線的組成有:
(1)ACLK 信號:總線時鐘,上升沿有效;
(2)ARESETN 信號:總線復位,低電平有效
(3)TREADY 信號:從機告訴主機做好傳輸準備;
(4)TDATA 信號:數據,可選寬度 32,64,128,256bit
(5)TSTRB 信號:每一 bit 對應 TDATA 的一個有效字節,寬度爲 TDATA/8
(6)TLAST 信號:主機告訴從機該次傳輸爲突發傳輸的結尾;
(7)TVALID 信號:主機告訴從機數據本次傳輸有效;
(8)TUSER 信號 :用戶定義信號,寬度爲 128bit。
對於 AXI4-Stream 總線命名而言,除了總線時鐘和總線復位,其他的信號線都是以 T 字母開頭,後面跟上一個有意義的單詞,看清這一點後,能幫助讀者記憶每個信號線的意義。如 TVALID = T+ 單詞 Valid(有效),那麼讀者就應該立刻反應該信號的作用。每個信號的具體作用,在後面分析源碼時再做分析
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 接口。
AXI 協議
協議和總線關係密切,協議要在總線的結構上制定。雖然說 AXI4,AXI4-Lite,AXI4-Stream 都 是 AXI4 協議,但是各自細節上還是不同的。 總的來說,AXI 總線協議的兩端可以分爲分爲主(master)、從(slave)兩端,他們之間一般 需要通過一個AXI Interconnect 相連接,作用是提供將一個或多個 AXI主設備連接到一個或多個 AXI 從設備的一種交換機制。當我們添加了 zynq 以及帶 AXI 的 IP 後再進行自動連線時,vivado 會自動幫我們添加上這個 IP
AXI Interconnect 的主要作用是,當存在多個主機以及從機器時,AXI Interconnect 負責將它們 聯繫並管理起來。由於 AXI 支持亂序發送,亂序發送需要主機的 ID 信號支撐,而不同的主機發送 的 ID 可能相同,而 AXI Interconnect 解決了這一問題,他會對不同主機的 ID 信號進行處理讓 ID 變 得唯一。
AXI 協議將讀地址通道,讀數據通道,寫地址通道,寫數據通道,寫響應通道分開,各自通道 都有自己的握手協議。每個通道互不干擾卻又彼此依賴。這也是 AXI 高效的原因之一。
AXI 協議之握手協議
AXI4 所採用的是一種 READY,VALID 握手通信機制,簡單來說主從雙方進行數據通信前, 有一個握手的過程。
發送方置高 VALID 信號表示發送方已經將數據,地址或者控制信息放到的寫總線上,並保持。
接收方置高 READY 信號表示接收方已經做好接收的準備。
所謂的雙向流控機制,指的是發送方通過 VALID 信號置起控制發送速度的同時,接收方也可以通過 READY 信號的置起與否控制接收速度,反壓發送方的發送速度。
當雙方的信息同時爲高,時鐘上升沿到達後,一次數據傳輸完成,在 1 到 n 次時鐘上升沿後,雙方傳完了要傳的信息後,兩信號同時拉低。
VALID 和 READY 信號的出現先後分爲三種情況:
1.VALID 信號先到達
發送方 VALID 信號早早就到了,這時還不到 T2 時刻,並帶來了新鮮的數據(數據通道),地址或者控制信息(地址通道)。
但過了 T2 也沒見到接收方的 READY 信號。原來是接收方還忙着,可能上一次的數據還沒存完,還堵在數據通路上,忙過了 T2 纔來。好吧,那也行,T3 時刻傳輸完成。在這種情況下,接收方通過 READY 信號控制了傳輸速度,反壓了發送速度。
協議規定:VALID 信號一旦置起就不能拉低,直到此次傳輸完成。對於接收方編程來說,檢測到 VALID 信號置起,如果系統正忙,完全可以讓發送方等待,發送方在完成傳輸之前都不會置低 VALID 信號,不需要考慮發送方撤銷傳輸的可能。
協議另外規定:發送方不能在置起 VALID 信號之前就光等待 READY 信號。
這句閱讀理解有點難,原文爲:
作者個人從總線接口編程的角度理解,READY 信號可能先到達,如下圖的情況。但是發送方編程時,不能依賴 READY 信號先到達的情況。不能將 READY 信號置高作爲置高 VALID 的條件,比如將 READY 信號通過組合邏輯生成 VALID 信號。
換句話說,發送方準備發送,置起 VALID 信號是完全主動的過程。接收方按照協議可以依賴發送方,但如果此時發送方也依賴接收方,就會造成死鎖的情況,所以協議在這裏規定了 VALID 信號的主動性。
2.READY 信號先到達
READY 信號很自由,可以等待 VALID 信號到來再做響應,但也完全可以在 VALID 信號到來前就置高,表示接收端已經做好準備了。
READY 信號與 VALID 不同,接收方可以置起 READY 之後發現:其實我好像還挺忙,然後拉低 READY 信號。只要此時 VALID 信號沒有置起,這種操作是完全可以。
3.同時到達
同時到達就很簡單,等到下一個時鐘上升沿 T2,傳輸就這麼輕鬆愉快地完成了,一個時鐘週期裏就完成了。
五個獨立通道
AXI4 總線的一大特徵是它有 5 個獨立的傳輸通道,這些通道都只支持單向傳輸。作爲類比,SPI 總線有 2 條傳輸通道:MISO, MOSI。SPI 輸入輸出的數據,大路朝天,各走一條;而作爲對比, IIC 協議則只有 SDA 一條通道,輸入輸出數據只能在這一條通道上分時雙向傳輸。
單向傳輸的通道意味着通道兩端的終端節點是有身份差距的,好比水只能從上游流到下流。在 AXI 總線傳輸中,通道兩端分爲 Master 主機與 Slave 從機,主機總是發起讀寫請求的一方,而我們五大通道的讀/寫定義就都是根據主機來定義的。
那麼五個通道都有誰呢:
- 讀地址 read address
- 讀數據 read data
- 寫地址 write address
- 寫數據 write data
- 寫回復 write response
5 個是不是很奇怪,你看讀/寫怎麼也得是個 2 的倍數不是,那爲什麼不是 6 條,爲什麼沒有讀響應?其實,讀響應借用了讀數據通道。至於爲什麼沒有獨立的讀回覆通道,我們之後再講。
五個獨立通道在讀寫操作中的角色
首先是寫操作,主機在寫地址通道上寫地址和控制信息。
在寫地址操作結束之後,即主機確保從機已經獲得了此次傳輸的地址和控制信息後,纔開始在寫數據通道上寫數據。
從機在寫回復通道上,將此次寫傳輸的狀態回覆給主機。
一般來說,寫數據都發生在寫地址操作之後,但也不是絕對的,在有些情況下,可以先寫數據。但是,所有情況下,寫回復必然是在寫數據之後,是對此次寫數據的狀態回覆。
接下來看讀操作:
讀操作只涉及兩個通道,首先主機在讀地址通道上寫入想要讀取的數據的地址以及控制信息。
從機在接收到地址後,將該地址上的數據通過讀數據通道發送給主機。
有兩點值得注意:一是 AXI 總線支持突發傳輸,主機可以寫入起始地址以及突發傳輸的字節數,從機將發送起始地址開始,突發傳輸個數的多個連續地址上的數據。
二是雖然名字爲讀地址通道,但實際上仍由主機寫入地址,只不過是寫入要讀取數據的地址。讀地址通道,這個名字確實有點歧義,主機讀操作地址通道表達得更貼切一些。
讀地址通道與寫地址通道:
在這兩條通道上傳輸地址和控制信息,讀寫操作都擁有各自的地址通道。地址位寬一般限制爲32位。
讀數據通道:
讀數據通道上包括從機發送給主機的讀數據以及讀操作完成狀態回覆,具體的讀操作狀態回覆情況會在之後討論。數據的寬度可以是8,16,64,128,256,512 或者是 1024 比特。
寫數據通道:
寫數據的寬度和讀數據通道的數據位寬相同,寫通道有一點讀通道所不具有的特性是有 STROBE 信號,用於標識寫數據中有效的傳輸字節,即有些無效的數據,出於減少主機工作量的目的,或者在讀寫寬度不對稱時,被放到寫數據通道上和有效數據一起發送。而 STROBE 的信號的作用就是標識出這些無用的數據,告知從機不需要接收無用數據。(Master:我太懶,以至於把所有信號都送過來了)
寫回復通道:
用於從機將寫完成情況回覆給主機。所有的寫傳輸操作都需要在寫回復通道上接收此次寫傳輸操作的完成情況。值得注意的是寫回復是針對一次突發傳輸的,而不是針對每一次的寫數據操作的。(一次突發傳輸包括了多次寫操作)
那麼問題來了,爲什麼只有寫回復通道而沒有讀回覆通道呢?
這個問題可以從數據流向看出來,主機在讀取數據時,數據在讀通道上傳輸,流向爲從機到主機。而讀回覆由從機向主機報告讀操作的情況,信號的數據流向也是從機到主機,所以讀回覆可以合併在讀數據通道中。
但寫回復通道的數據流向就和寫數據相反。寫數據是從主機到從機,而寫回復爲從機報告寫操作的完成情況,流向爲從機到主機,無法合併到寫數據通道中,另一方面,寫回復又是不可或缺的,所以就有了一條獨立的寫回復通道。
通道上的信號們
全局信號
AXI 總線中有兩個全局信號:ACLK,全局的時鐘信號,所有的傳輸操作都發生在 ACLK 的上升沿。ARESETn,全局復位信號,低電平有效。在復位問題上,AXI 規定了一些細節,會在後續的文章中討論。
寫地址通道
寫地址通道的信號可以分爲 3 部分:經常用到的基礎信號,突發傳輸有關的信號以及和內存訪問相關以及其他的在基礎階段不是很常用的信號。
基礎信號即 AWADDR:你想要寫入的地址,AWVALID 以及 AWREADY:所有通道都使用的握手信號。
突發傳輸指的是傳輸一次起始地址後,進行多次地址上連續的讀寫操作。突發傳輸有關的操作包括:AWLEN:突發傳輸的長度,即在一次突發傳輸中數據傳輸的個數。AWSIZE:每次突發傳輸中的數據傳輸的位寬。AWBURST:突發傳輸的類型。
其他信號包括和內存原子操作有關的 AWLOCK,AWCACHE,AWPROT 以及用於用戶自定義的 AWUSER 信號,都將在以後的文章涉及。(等我自己先用到再說)
讀地址通道
讀地址通道和寫地址通道的信號十分類似,就不再從 specification 中截圖以及介紹了。
寫數據通道
值得注意的是 AXI4 不再支持 WID 信號,這和 AXI4 的亂序機制有關,AXI4 規定所有數據通道的數據必須順序發送。
WDATA 與常見的握手信號不再贅述,WDATA 的可使用位寬可以見上文。WSTRB 信號用於標記傳輸數據中有效的字節,每個 WSTRB 位對應一個字節的位寬,比如數據位寬爲 64 位,那麼 WSTRB 信號的位寬就是 1 個字節,共 8 位。(感謝評論區糾正)
WLAST 標識一次突發傳輸中最後一次數據傳輸,如果沒有正確的 WLAST 的信號,就會造成寫入地址的混亂,導致從機無法正確接收寫數據,從而造成從機不再拉高 READY 信號的現象。
寫回復通道
與寫數據通道不同,寫回復通道支持 BID,即支持亂序的寫回復,關於亂序的問題,我們稍後再談。BRESP 回覆上一次的寫狀態。
讀數據通道
讀數據通道與寫數據通道類似,區別有兩點:一,支持 RID 信號。二,因爲讀回覆信息在讀數據通道上傳遞,所以集成了 RRESP 信號,用於返回讀狀態,值得注意的是讀回覆信號和讀數據一樣,發送方(source)爲從機(slave)。
AXI4 總線突發傳輸機制
AXI 總線的突發傳輸機制( burst ),在 AXI 總線中的突發傳輸是指,在地址總線上進行一次地址傳輸後,進行多次數據傳輸( transfer,這個有點搞,突發傳輸 and 傳輸?)。第一次地址傳輸中的地址作爲起始地址,根據突發傳輸類型的不同,後續數據的存儲地址在起始地址的基礎上遞增(INCR 模式);或者首先遞增,到達上限地址後回到起始地址,繼續遞增(WRAP 模式);又或者後續數據都將不斷寫入起始地址,刷新起始地址上的數據。(FIXED 模式)
突發傳輸類型,在前文中提及,共有 3 種,分別爲 FIXED,INCR 以及 WRAP。使用 2 位二進制表示。
FIXED 類型適合對某個固定地址進行數據更新,比如向一個 almost full 的 fifo 更新數據。
INCR 類型最爲常用,後續的數據的存儲地址在初始地址的基礎上,以突發傳輸寬度進行遞增,適合對於 RAM 等 mapped memory 存儲介質進行讀寫操作。
WRAP 模式比較特殊,除了初始地址外,還有最高地址的界限。在最大地址以下,WRAP 與 INCR 類型完全相同,地址遞增,但達到最高地址後,地址直接回到起始地址,再進行遞增,就這樣循環往復。數據手冊上表示,WRAP 適合對 cache 的訪問,我這方面經驗還不多,不是很能理解這種模式的精妙之處。
突發傳輸長度 (burst length),突發傳輸長度是指在一次突發傳輸中所進行的傳輸(transfer)次數,在傳輸完初始地址後,進行的數據傳輸次數就是突發傳輸長度,假設數據位寬是 32 位,即進行 32 * N bit 的數據傳輸。在 AXI4 中,INCR 類型最大支持長度爲 256,其他類型最大長度爲 16。當然你的突發長度最少爲 1,不然也就沒有傳輸發生了。協議中的 burst length 從零開始,實際的長度值爲長度字段加1。傳輸長度使用 8 位二進制表示。
突發傳輸長度有一些限制,包括:
- 對於 WRAP 模式,突發傳輸長度僅能爲2,4,8,16
- 在一次突發傳輸中,地址不能跨越一個 4KB 分區
- 一次突發傳輸不能在未達到傳輸長度的情況下提前結束。
突發傳輸寬度(burst size),突發傳輸寬度是每指一次傳輸(transfer)中的最大數據寬度,突發傳輸數據寬度不能超過數據線本身的寬度。當數據線本身寬度大於突發傳輸寬度時,將根據協議的相關規定製定數據在部分數據線上傳輸。突發傳輸寬度共 3 個二進制位,表示爲:
讀寫操作信號
Vivado 爲我們生成的 AXI-Lite 的操作源碼,是一個模板,我們只需要讀懂它,然後稍加修改,就
可以在實際工程使用。