該項目介紹了如何在 PL 中的 HDL 與 FPGA 中的處理器上運行的嵌入式 C 之間傳輸數(shù)據(jù)的基本結(jié)構(gòu)。
介紹
鑒于機器學習和人工智能等應用的 FPGA 設計中硬件加速的興起,現(xiàn)在是剝開幾層“云霧”并討論 HDL 之間來回傳遞數(shù)據(jù)(主要指FPGA 的可編程邏輯 (PL) 中運行的代碼以及 FPGA 中的硬核或軟核處理器上運行的相應軟件之間傳輸數(shù)據(jù))的基礎知識的好時機。
硬件加速可以總結(jié)為在硬件(也稱為 FPGA 的可編程邏輯)中實現(xiàn)某些功能的基本思想,這些功能之前在位于主機 PC 上或在 FPGA 上處理器(軟核或者硬核)運行的軟件。因此,要成為一名高效的設計人員,就必須掌握如何在硬件和軟件之間來回傳遞數(shù)據(jù)的技巧。
在本例中,使用的是 Zynq SoC(片上系統(tǒng))FPGA,它具有硬核 ARM 處理器。該 ARM 核心和外設稱為處理系統(tǒng)或 PS。
雖然有幾種不同的方法可以完成 PL 和 PS 之間的數(shù)據(jù)傳輸,包括編寫自己的自定義接口,但我認為最常見的機制是通過直接內(nèi)存訪問 (DMA) 傳輸。這是因為 DMA 允許 ARM 內(nèi)核的 CPU 簡單地啟動自身與 DDR 之間的數(shù)據(jù)傳輸,而 CPU 無需等待傳輸完成后再執(zhí)行任何其他任務。DMA 還允許 CPU 啟動外部設備和 DDR 之間的傳輸。
在此項目中,將通過使用 Xilinx DMA IP 演示 DMA 的功能,該IP可通過 AXIS 總線將內(nèi)存映射接口轉(zhuǎn)換為stream接口。將 32 字節(jié)寫入嵌入式 C 中的內(nèi)存,然后通過內(nèi)存映射將其傳輸?shù)?PL 到流 (MM2S) AXIS,通過寄存器處理每個值,然后通過流將數(shù)據(jù)傳輸回內(nèi)存DMA IP 的內(nèi)存映射 (S2MM) 端口。
雖然這個示例對于重型硬件加速應用來說過于簡單,但當剛接觸 FPGA 時,這種高速數(shù)據(jù)傳輸水平可能會變得非常復雜/難以學習。該項目重點介紹 DMA 的使用及其行為。雖然打算讓這個項目更多地關(guān)注數(shù)據(jù)處理方面,但在 DMA 事務實現(xiàn)中發(fā)現(xiàn)了很多小“陷阱”,因此不得不將數(shù)據(jù)處理重點留給另一個項目。
使用 AXI DMA 控制 PL 中的 HDL 與 PS 中的 C 代碼之間的數(shù)據(jù)傳輸有兩個主要層:
Memory Map to Stream (MM2S) 和 Stream to Memory Map (S2MM) 通道上 PL 的 HDL 代碼中的 AXI 流握手信號(DMA 的控制通道是使用普通 AXI 寫入的,但這就是全部由 Vivado 自動處理,因此在這里只關(guān)注 AXI stream接口)。
PS 的 C 代碼中寄存器讀/寫 DMA 的順序。
Verilog 中的 AXI-Stream握手
AXI stream接口使用一組簡單的握手信號機制,用于嵌入式設計中的數(shù)據(jù)交換。AXI stream接口中有許多可選信號,但與 DMA MM2S 和 S2MM 數(shù)據(jù)交換相關(guān)且必需的信號是 tdata、tvalid、tready、tlast 和 tkeep。AXI stream中發(fā)送數(shù)據(jù)為主接口,接收數(shù)據(jù)為從接口。
tdata:數(shù)據(jù)總線
tvalid:當放置在 tdata 總線上的數(shù)據(jù)有效時,由主接口置位
tredy:當從機處于準備接收 tdata 總線上的數(shù)據(jù)的狀態(tài)時,由從機置位
tlast:由主設備在 tdata 總線上流中最后一個數(shù)據(jù)包的持續(xù)時間內(nèi)斷言,以告訴從設備該數(shù)據(jù)包之后不會有數(shù)據(jù)
tkeep:由主設備設置的 tdata 總線上數(shù)據(jù)包的二次驗證,指示數(shù)據(jù)包是否是流的一部分
AXI DMA IP 究竟如何實現(xiàn)此握手接口將數(shù)據(jù)傳輸出內(nèi)存 (MM2S) 并傳輸?shù)絻?nèi)存 (S2MM),這一點非常變化無常,尤其是在 S2MM 方面……
然而,我們首先需要了解的是有關(guān) AXI DMA 的 S2MM 事務的信息,大部分可以總結(jié)為一句話:必須設置 S2MM 事務,并且在嘗試向 DMA 發(fā)送任何數(shù)據(jù)之前,以適當?shù)捻樞驅(qū)懭?DMA 中的適當控制寄存器來啟動事務,一旦 S2MM 通道看到 tlast 信號,它就會停止事務。
數(shù)據(jù)傳輸發(fā)生在每個時鐘周期的 S2MM 和 MM2S 事務中的 tdata 總線上,其中tready 和 tvalid 均被置位(true)。因此,當負責斷言 tvalid 時,在 AXI 接口的主端必須小心,當從從機傳入的 trety 信號也為 tvalid 斷言時,不要讓 tvalid 斷言超過一個時鐘周期。否則,從設備將在同一個數(shù)據(jù)包計時兩次,作為兩個單獨的數(shù)據(jù)包。并且因為必須在控制寄存器中指定傳輸中有多少字節(jié),所以 DMA 通道(在本例中為 S2MM)會在看到提供 tlast 信號之前認為交換已結(jié)束,因為計數(shù)已關(guān)閉。
我用 Verilog 編寫了一個簡單的狀態(tài)機,它實現(xiàn)了一個從 AXI stream接口來從 DMA 的 MM2S 通道接收數(shù)據(jù),通過寄存器傳遞stream中的每個數(shù)據(jù)包,然后實現(xiàn)一個主 AXI strean接口來將數(shù)據(jù)流發(fā)回到S2MM通道。來自 tdata 總線的數(shù)據(jù)通過的寄存器旨在充當占位符,用于為硬件加速進行任何自定義數(shù)據(jù)處理。
從 Vivado 中的 ILA 中截取了一張屏幕截圖,顯示使用狀態(tài)機實現(xiàn)的時序圖。頂部是 MM2S 側(cè),底部是 S2MM 側(cè)。
這是 Verilog 狀態(tài)機的流程圖,實際文件附在本文末尾。值得注意的是,流程圖中的主/從接口是從 Verilog 狀態(tài)機的角度來看的。
對于 DMA IP 的具體設置,因為在直接寄存器模式下使用 DMA,所以未選中分散收集選項。然后,將其他所有設置保留為默認設置,并選中允許未對齊傳輸?shù)倪x項,我發(fā)現(xiàn)在將自定義 AXI 流接口寫入 DMA 時,這給了更多的自由空間。
為了將 Verilog 狀態(tài)機添加到模塊設計中,我右鍵單擊模塊設計的空白區(qū)域,然后選擇“添加模塊...”選項,該選項將顯示 Vivado 可以在設計源中找到的所有有效 Verilog 模塊在BD中使用的文件。
值得注意的是,信號命名約定分別遵循從接口和主接口的“s_axis”和“m_axis”標準。
DMA 寄存器讀/寫控制序列
以下是裸機使用 DMA 時更簡單的順序:
1.通過將 1 寫入 MM2S(偏移量 0x00)和 S2MM(偏移量 0x30)控制寄存器的位 2 來復位 DMA。
2.將 S2MM 通道要寫入數(shù)據(jù)的 DDR 中位置的目標地址寫入 S2MM DMA 目標地址寄存器(偏移量 0x48)。
3.通過將 1 寫入 S2MM 控制寄存器(偏移量 0x30)的位 0 來啟動 DMA S2MM 通道。
4.通過將 S2MM 通道上要讀入內(nèi)存的總字節(jié)數(shù)值寫入 S2MM 緩沖區(qū)長度寄存器(偏移量 0x58),寫入 S2MM 通道緩沖區(qū)的長度。這將啟動 S2MM 傳輸,以便 DMA 準備好從 FPGA 邏輯中的設備接收數(shù)據(jù)流(直到實際饋送數(shù)據(jù)并且 AXI 流總線上的 tvalid 由 FPGA 邏輯中的設備斷言后,該過程才會真正啟動)邏輯)。
5.將 MM2S 通道要讀取的數(shù)據(jù)的 DDR 中的源地址寫入 MM2S DMA 源地址寄存器(偏移量 0x18)。
6.通過將 1 寫入 MM2S 控制寄存器的位 0(偏移量 0x00)來啟動 DMA MM2S 通道。
7.通過將要發(fā)送的總字節(jié)數(shù)值寫入 MM2S 傳輸長度寄存器(偏移量 0x28),寫入 MM2S 通道的傳輸長度。這將啟動從 DMA 到 FPGA 邏輯中的接收設備的 MM2S 傳輸。
還記得之前提到過,在 PL 中的設備嘗試向 S2MM 通道發(fā)送數(shù)據(jù)之前,必須啟動并運行 S2MM 通道嗎?嗯,這就是為什么要按順序執(zhí)行上述步驟。步驟 2 - 4 配置并啟動 S2MM 通道,步驟 5 - 7 配置并啟動 MM2S 通道。
在步驟 4 和 5 之間發(fā)生一些其他進程是可以的,但步驟 2 - 4 必須在步驟 5 - 7 之前發(fā)生。執(zhí)行步驟 4 后,S2MM AXI 流通道將斷言其 Tready 信號,此時 HDL 代碼可以開始向其發(fā)送數(shù)據(jù)。
這也解釋了當我第一次開始使用 DMA 時,在 SDK/Vitis 中的示例 DMA 項目中注意到的一些事情??偸钦J為示例代碼似乎是在使用 MM2S - XAXIDMA_DMA_TO_DEVICE 傳輸從 DDR 中寫入任何內(nèi)容之前嘗試將數(shù)據(jù)拉入 DDR(通過首先執(zhí)行 S2MM - XAXIDMA_DEVICE_TO_DMA 傳輸)。然而,S2MM 通道必須準備好并等待接收數(shù)據(jù)才能正常工作并且不會鎖定。
在 FPGA 設計中,DMA 似乎是一種棘手的入門方法,但一旦你弄清楚它就會非常有幫助。
審核編輯:劉清
-
FPGA
+關(guān)注
關(guān)注
1646文章
22054瀏覽量
618810 -
嵌入式
+關(guān)注
關(guān)注
5152文章
19678瀏覽量
317788 -
HDL
+關(guān)注
關(guān)注
8文章
330瀏覽量
48077 -
片上系統(tǒng)
+關(guān)注
關(guān)注
0文章
188瀏覽量
27301 -
dma
+關(guān)注
關(guān)注
3文章
576瀏覽量
103309
原文標題:使用 DMA 在 FPGA 中的 HDL 和嵌入式 C 之間傳輸數(shù)據(jù)
文章出處:【微信號:Open_FPGA,微信公眾號:OpenFPGA】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
基于 DSP-dMAX 的嵌入式 FIFO 數(shù)據(jù)傳輸系統(tǒng)設計
FPGA與嵌入式系統(tǒng)的區(qū)別
FPGA是嵌入式系統(tǒng)設計的理想選擇
為什么說在嵌入式系統(tǒng)設計采用FPGA是理想的選擇?
如何設計嵌入式FIFO數(shù)據(jù)傳輸系統(tǒng)?
淺析MATLAB和Simulink嵌入式視覺應用
淺析嵌入式FPGA與HDL硬件描述語言
嵌入式GPRS數(shù)據(jù)傳輸終端設計

在嵌入式系統(tǒng)中使用FPGA時的常見問題及對策
嵌入式FIFO數(shù)據(jù)傳輸系統(tǒng)詳解

評論