1.DMA
我們的整體VGA顯示分為幾步:比如先導入VIDEO TIMING CONTROL來做對輸入數據的時序“對齊”,這里開源騷客寫的很詳細,先用了一個虛擬IO(VIO)來作為輸入,導入了一個簡單的RTL模塊(當VTL的使能信號有效時,RGB_DATA_OUT就接收來自VIO的RGB_DATA_IN);
接著,我們要把VIO替換掉為DMA+PS端的模塊(即輸入數據變成了PS端處理過后的,被DMA讀取)
DMA 有兩個 AXI 流端口。一個是 AXI 主流 (M_AXIS_MM2S),對應于?READ?通道。數據將通過 M_AXI_MM2S 端口從內存中讀取,并發送到 M_AXIS_MM2S 端口(并發送到連接到此端口的 IP)。
以下是對VDMA的通俗解釋(來自AI):
VDMA就是視頻數據的"快遞專車",它直接在攝像頭(PL端)和內存(PS端)之間建立一條專用高速公路,讓視頻幀數據不經過CPU就能直達目的地。
寫的很詳細的教程:Tutorial: PYNQ DMA (Part 1: Hardware design) - Learn - PYNQ
另一個對DMA很通俗的解釋視頻:10行代碼,就能讓你真正理解DMA!你用的可能很少,但是在單片機中非常重要!_嗶哩嗶哩_bilibili
2.AXI接口之讀寫DDR
-
AXI4主控制器:模塊(axi4_rw)作為AXI總線的主設備,主動發起讀寫請求。
-
DDR訪問:通過HP接口連接到Zynq(從機)的DDR控制器,實現對DDR內存的讀寫。
-
控制接口:提供啟動信號(
init_axi_txn
)、完成標志(txn_done
)和錯誤指示(error
)。 -
無用戶信號:
AWUSER/ARUSER/WUSER
等寬度為0,簡化設計。
用戶信號是什么?
在AXI協議中,用戶信號(如
AWUSER
,?ARUSER
,?WUSER
等)是可選的擴展信號,用于在標準AXI通道中傳遞額外的自定義信息。它們不屬于AXI核心協議規范,而是提供給設計者的"擴展槽"。——內容由AI生成
對著野火的PS文檔直接復現,一個問題是警告:
你把 AXI 接口的 RUSER_WIDTH
和 WUSER_WIDTH
設成了 1 位,但這不符合 AXI 規范,因為數據總線是 32 位(4 字節),而用戶信號寬度必須是“每字節整數倍”的位數。但其實這里我們根本不需要什么用戶位寬,雙擊axi4_rw的ip把后面五個位寬全部修改成0即可解決:
所有m00_axi_*
信號連接到Zynq的HP0/HP1等AXI從端口。
當外部邏輯拉高(也就是對應的按鍵消抖模塊的flag有效),m00_axi_init_axi_txn拉高
,觸發模塊開始讀寫操作。
總結:axi4_rw模塊是FPGA與Zynq DDR通信的“橋梁”,通過標準化AXI4協議實現高效突發傳輸。編寫者只需觸發init_axi_txn
,模塊自動完成地址分配、突發控制、握手響應等復雜操作,極大簡化了DDR交互邏輯設計。
3.ip核配置
對于GP M口,PS端是主;對于HP ,PS端是從。
信號名稱 | 總線類型 | 協議特點 | 典型連接對象 |
---|---|---|---|
M_AXI_MM2S | AXI4-Full | 存儲器映射,含地址/控制信號 | DDR內存控制器 |
M_AXIS_MM2S | AXI4-Stream | 純數據流,無地址信號 | 流處理IP核 |
S就是Stream的縮寫,表示"流式數據傳輸";攝像頭采集的視頻就是沒有地址的視頻流,CPU無法直接解析無地址的流數據,我們要使用VDMA;
在野火的第17個例程DMA環回讀寫實驗中,由于數據經過DMA之后變成了數據流,與之打交道的也應該是帶有 ?Stream 接口的高速的 AD 或 DA IP 核(比如AXI4_STREAM TO VIDEO OUT),這里我們方便起見選擇了AXI4 ?Stream Data FIFO IP 核來充當這類 IP,這個FIFO起到? 將AXI-Full 總線轉換為 AXI-Stream 總線? ,并且充當一個“流數據池”的作用。其S_AXIS與DMA的M_AXIS_MM2S相連,M_AXIS與DMA的S_AXIS_S2MM相連,非常類似于正負極的連接。
AXI DMA 的 MM2S/S2MM 兩個通道 → 通過 fabric 中斷號 → 接到 PS 的 GIC → 由 TxIntr_Handler / RxIntr_Handler 處理完成/錯誤事件 → 把全局標志 Tx_Done / Rx_Done / Error 置位 → 主循環里根據標志位做后續動作。
#define RX_INTR_ID XPAR_FABRIC_AXIDMA_0_S2MM_INTROUT_VEC_ID
#define TX_INTR_ID XPAR_FABRIC_AXIDMA_0_MM2MM_INTROUT_VEC_ID
GIC給中斷源分配了中斷號,這兩個宏就是 BSP 在 xparameters.h
里根據我們的硬件設計自動生成的;在 Vivado 里把 AXI-DMA 的 mm2s_introut / s2mm_introut
信號拉到 PS 的 IRQ_F2P[x]
引腳的那一刻,就已經決定了它的中斷號;之后 Vivado 導出 HDF,SDK/Vitis 根據 HDF 生成 xparameters.h
,把連線結果翻譯成宏值,軟件直接用即可。