【ZYNQ-7000開發之九】使用VDMA在PL和PS之間傳輸視頻流數據
理論部分
VDMA可以把AXI4-Stream 類型的視頻流通過S2MM,寫入到DDR3中,反之也可以通過MM2S讀入到VDMA接口的外設中。通過內嵌FPGA邏輯分析儀進行觀察數據。
本文所使用的開發板是Miz702(兼容zedboard)
PC 開發環境版本:Vivado Design Suite 2015.2
硬件系統工程
新建一個zedboard工程
建好工程后,再新建一個Block Design
點擊ADD IP,添加ZYNQ PS
點擊Run Block Automation,在彈出的對話框點擊OK
雙擊ZYNQ圖標,去掉不用的外設
使能一個HP接口,PL和PS通過VDMA傳輸數據做准備
設置好后,點擊OK
添加VDMA IP Core
點擊Run Connection Automation
在彈出的對話框的左上角選擇All…,點擊OK
再次點擊Run Connection Automation
在彈出的對話框的左上角選擇All…,點擊OK,然后重新生成布局
添加TPG IP Core
雙擊剛剛生成的TPG圖標,作如下設置
按照如圖所示連接
按照如圖所示連接時鍾線
同上把VDMA的m_axis_mm2s_aclk以及s_axis_s2mm_aclk和上述時鍾線連在一起
把TPG的aresrtn按照如圖所示連接
重新生成布局后,如圖所示(右擊可以查看高清大圖)
添加ILA IP Core(方法很多,這里未必是最好的)
把ila_0的SLOT_0_AXI和VDMA的M_AXI_MM2SS連接在一起
把ila_0的clk和VDMA的aclk連在一起
在添加一個ILA IP Core
把ila_1的SLOT_0_AXI和VDMA的M_AXI_S2MM連接在一起
把ila_1的clk和VDMA的aclk連在一起
完整的硬件結構框圖如下(右擊可查看高清大圖)
右擊Bolock design,選擇Create HDL Wrapper
再次右擊Bolock design,選擇Generate output Prouducts
完成點擊Run Synthesisi
完成后,點擊Generate bitstream(耐心等待下吧,可以去吃個飯,睡會覺或者瀏覽下論壇的帖子,發幾個評論……)
然后再選擇,Tools -> set Up Debug
最后,File->Export->Export Hardware —-File ->Launch SDK
軟件工程
SDK啟動后,新建一個Hello World工程
把helloworld.c里的代碼修改如下:
#include <stdio.h> #include "platform.h" #include "xil_io.h" int main() { init_platform(); xil_printf("----------The test is start......----------\n\r"); Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x4); //reset S2MM VDMA Control Register Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x8); //genlock Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, 0x08000000);//S2MM Start Addresses Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC+4, 0x0A000000); Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC+8, 0x09000000); Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 1920*3);//S2MM Horizontal Size Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, 0x01002000);//S2MM Frame Delay and Stride Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x30, 0x3);//S2MM VDMA Control Register Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 1080);//S2MM Vertical Size start an S2MM transfer //AXI VDMA1 Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x0, 0x4); //reset MM2S VDMA Control Register Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x0, 0x8); //gen-lock Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C, 0x08000000); //MM2S Start Addresses Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C+4, 0x0A000000); Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C+8, 0x09000000); Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x54, 1920*3);//MM2S HSIZE Register Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x58, 0x01002000);//S2MM FRMDELAY_STRIDE Register 1920*3=5760 對齊之后為8192=0x2000 Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x0, 0x03);//MM2S VDMA Control Register Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x50, 1080);//MM2S_VSIZE 啟動傳輸 cleanup_platform(); return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
按照如下配置配置軟件Debug
設置好之后,開發板上電,點擊Debug
打開vivado->open hardware->program device
成功后,vivado會自動打開硬件調試界面,如圖所示
添加觸發信號
在hw_ila_1里添加axi_vdma_0_M_AXI_MM2S_ARVALID信號,如圖所示:
同上在hw_ila_2里添加axi_vdma_0_M_AXI_S2MM_AWVALID信號
把waveform里不相關的信號去掉
可以單步調試運行或者直接運行
VDMA啟動兩個通道啟動后,wavefom里的波形如下所示:
S2MM
MM2S
這里大家可能會注意到有個問題,就是MM2S只傳輸了一次就停止了,這是問什么呢?大家可以思考下!
總結,在本篇文章我們實現了用VDMA的洗數據,把stream類型的數據轉為Memory Map類型的存到內存中,然后用VDMA的讀數據把MM的數據轉為Stream型。最后還留了個小問題(PS:其實有一步我忘了做了),大家可以思考下!
轉載:http://blog.csdn.net/rzjmpb/article/details/50516181