文章目錄
- 1 實驗任務
- 2 系統框圖
- 3 硬件設計
- 3.1 IP核配置
- 3.2 注意事項
- 4 軟件設計
- 4.1 注意事項
- 4.2 工程源碼
- 4.2.1 main.c文件
1 實驗任務
基于14.1,使用Xilinx TPG(Test Pattern Generator) IP提供視頻源,將視頻數據通過VDMA寫入PS側內存,然后再通過VDMA將視頻數據從PS側內存讀出來,最后通過HDMI接口發送出去,即實現視頻轉發的功能。
2 系統框圖
基于14.1,添加TPG IP核作為視頻源,連接到VDMA的寫通道,如下圖所示:
3 硬件設計
3.1 IP核配置
- 配置VDMA IP核
- (1)Basic頁面
- 1)Frame Buffers:選擇默認值3,即緩存3幀圖像數據
- 2)Enable Write Channel:勾選,使能寫通道
- 3)Write Burst Size:選擇256,最大化傳輸效率
- 4)Line Buffer Depth:選擇2048,圖像分辨率為1920x1080,能夠緩存一行像素數據
- (2)Advanced頁面
- 1)保持默認值,采用動態同步鎖相模式,寫通道為主,讀通道為從
- 1)保持默認值,采用動態同步鎖相模式,寫通道為主,讀通道為從
- (1)Basic頁面
- 配置TGP IP核
- (1)全部保持默認即可
- (1)全部保持默認即可
3.2 注意事項
為各個接口自動連線:必須手動指定主從接口和互聯模塊的時鐘
- 為VDMA的M_AXI_S2MM接口連線:從接口是PS的S_AXI_HP0接口
- 為TPG的s_axi_CTRL接口連線:主接口是PS的M_AXI_GP0接口,注意
- (1)TPG只有一個時鐘接口ap_clk,該時鐘是AXI4-Stream data interface和AXI4-Lite control interface共用,所以時鐘源選擇的是Clocking Wizard輸出的clk_out1時鐘,即視頻時鐘,使輸入視頻和輸出視頻同步
- (1)TPG只有一個時鐘接口ap_clk,該時鐘是AXI4-Stream data interface和AXI4-Lite control interface共用,所以時鐘源選擇的是Clocking Wizard輸出的clk_out1時鐘,即視頻時鐘,使輸入視頻和輸出視頻同步
- 將TPG和VDMA連接起來,為VDMA的s_axis_s2mm_aclk連線,自動識別為Clocking Wizard輸出的clk_out1時鐘,即視頻時鐘
4 軟件設計
4.1 注意事項
- TPG IP核生成一個背景為純白,疊加一個黑色移動小方塊的視頻
- 當VDMA寫通道停止時
- (1)VDMA寫通道暫停接收視頻數據,TPG暫停產生視頻數據
- (2)VDMA讀通道依然在發送數據
- 1)顯示器上小方塊停止移動
- 2)說明VDMA讀通道在重復發送同一幀視頻數據,該幀視頻數據是VDMA寫通道在停止前寫入的最后一幀
- 3)符合動態同步鎖相模式的工作機制,即讀通道(Dynamic Genlock Slave)會操作寫通道(Dynamic Genlock Master)上一個周期操作的幀
- 當VDMA寫通道重啟時
- (1)TPG恢復產生視頻數據
- (2)顯示器上小方塊繼續從停止的位置開始移動
4.2 工程源碼
4.2.1 main.c文件
/********************************************************************/#include "vdma/vdma_api.h"#include "xparameters.h"
#include "stdio.h"
#include "sleep.h"
#include "xv_tpg.h"/********************************************************************/#define TPG_DEVICE_ID XPAR_V_TPG_0_DEVICE_ID
#define VDMA_DEVICE_ID XPAR_AXIVDMA_0_DEVICE_ID
#define MEMORY_BASEADDR XPAR_PS7_DDR_0_S_AXI_BASEADDR#define IMAGE_WIDTH 1920
#define IMAGE_HEIGHT 1080/********************************************************************//********************************************************************/XV_tpg TpgInst;
XAxiVdma VdmaInst;int FrameBufferAddr = (MEMORY_BASEADDR + 0x02000000);/********************************************************************/int main()
{//int Status;u32 BackGndPatternId;u32 ForeGndPatternId;u32 BoxSize;u32 BoxColorRed;u32 BoxColorGreen;u32 BoxColorBlue;u32 MotionSpeed;//printf("Vdma Video Forward Test.\n");//Status = XV_tpg_Initialize(&TpgInst, TPG_DEVICE_ID);if (Status == XST_FAILURE) {printf("Error : video test pattern generator initialization failed.\n");return XST_FAILURE;}//BackGndPatternId = 0x8;ForeGndPatternId = 0x1;BoxSize = 0x20;BoxColorRed = 0x00;BoxColorGreen = 0x00;BoxColorBlue = 0x00;MotionSpeed = 0x2;XV_tpg_Set_width(&TpgInst, IMAGE_WIDTH);XV_tpg_Set_height(&TpgInst, IMAGE_HEIGHT);XV_tpg_Set_bckgndId(&TpgInst, BackGndPatternId);XV_tpg_Set_boxSize(&TpgInst, BoxSize);XV_tpg_Set_boxColorR(&TpgInst, BoxColorRed);XV_tpg_Set_boxColorG(&TpgInst, BoxColorGreen);XV_tpg_Set_boxColorB(&TpgInst, BoxColorBlue);XV_tpg_Set_motionSpeed(&TpgInst, MotionSpeed);XV_tpg_Set_ovrlayId(&TpgInst, ForeGndPatternId);XV_tpg_Start(&TpgInst);XV_tpg_EnableAutoRestart(&TpgInst);// 啟動VDMA讀寫操作Status = run_vdma_frame_buffer(&VdmaInst, VDMA_DEVICE_ID, IMAGE_WIDTH, IMAGE_HEIGHT, FrameBufferAddr, 0, 0, BOTH);if (Status == XST_FAILURE) {printf("Error : run vdma frame buffer failed.\n");return XST_FAILURE;}//while (1) {//sleep(10);printf("Stop vdma channel.\n");
// XAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_READ);XAxiVdma_DmaStop(&VdmaInst, XAXIVDMA_WRITE);//sleep(5);printf("Start vdma channel.\n");
// XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_READ);XAxiVdma_DmaStart(&VdmaInst, XAXIVDMA_WRITE);}//return XST_SUCCESS;
}/*****************************************************************************//*****************************************************************************/