本篇文章來自 FPGA 大神、Ardiuvo & Hackster.IO 知名博主 Adam Taylor。在這里感謝 Adam Taylor 對 ALINX 產品的關注與測試。為了讓文章更易閱讀,我們在原文的基礎上作了一些靈活的調整,包括對一些專業名詞進行了補充解釋,便于初學者快速理解。原文鏈接已貼在文章底部。歡迎大家在評論區友好互動。
最近,我在辦公室里搞了一塊ALINX VD100。
這是一塊基于AMD Versal Edge AI平臺的開發板,功能特別強大,可以用來做圖像處理、人工智能等各種高階應用。
為了方便隨時開發,我把它連到了公司局域網,遠程就能連接,由此開始了我的折騰之旅。
這次,我最想探索的是:怎么在這塊板子上跑圖像處理的應用。
VD100不僅帶了兩個 MIPI 攝像頭接口,還能直接連上LCD屏幕,基本滿足了圖像應用開發的需求。
第一步:讓屏幕先亮起來!
搞攝像頭太復雜,我決定先從屏幕入手——先通過測試圖案生成器(Test Pattern Generator)驗證 LCD 屏幕圖像顯示鏈路的有效性。
ALINX VD100開發板支持的 LCD 屏幕,分辨率是1280×720(WXGA 標準)。
數據傳輸采用的是VESA 標準的 LVDS 接口。
這里稍微解釋一下:
LVDS(低壓差分信號)是一種高速又抗干擾的數據傳輸方式,特別適合屏幕傳輸高速畫面。
VESA 和 JEIDA 是常見的兩種 LVDS 傳輸標準,咱們用的是 VESA。VESA 更國際通用,JEIDA 常見于日本廠商。
在 VESA 標準下使用 RG888 格式時,屏幕的每一幀圖像數據和控制信號(如同步信號 hsync、vsync)會被打包進 4 條數據通道里,同時還有第 5 條通道專門傳時鐘(Clock),方便接收端正確還原數據。
每次時鐘跳動時,每條數據通道都會同步傳7 位數據。
聽起來有點復雜?簡單說就是:用 4+1 條小路,高速搬運屏幕畫面。
開發流程:搭建系統設計
為了讓板子順利傳屏幕數據,我們需要在 Vivado(AMD/Xilinx 的開發工具)里做一套設計,包括:
CIPS
→ 配置 VD100 平臺上的 V100 SoM。
NOC
→ 配置 DDRMC,并開兩條 MAXI 輸出,提供數據存取支持。
視頻測試圖生成器 (Video Test Pattern Generator, TPG)
→ 通過 AXI Lite 總線連接到 NOC,生成標準圖像(比如彩條、棋盤格)。
視頻時序生成器 (Video Timing Controller, VTC)
→ 通過 AXI Lite 總線連接到 NOC,生成 LCD 顯示需要的同步信號(如 hsync、vsync)。
AXI4-Stream to Video Out
→ 與上述兩個生成器相連,把測試圖和時序信息組織成并行視頻流(RGB888格式)。
LCD_LVDS IP核
→ 把并行視頻信號轉成符合 LVDS 規范的數據流。
Advanced IO Wizard
→ 負責真正的串行化操作,把數據以 LVDS 標準發出去(包括 4 路數據+ 1 路時鐘)。
最終 LCD 屏幕接收到 LVDS 信號并顯示圖像。
這套設計(可以在我的 GitHub 上找到)如下所示:
通過這個系統,我們可以使用 CIPS 內置的處理器來控制測試圖案,從而驗證各顏色通道是否正常。
設置和驅動 LCD 顯示器的 CIPS 端代碼也非常簡單,如下所示:
#include #include "platform.h" #include "xil_printf.h" #include "xvtc.h" #include "xparameters.h" #include "xv_tpg.h" #include "xvidc.h" #include"vga.h" XV_tpg tpg; XVtc VtcInst; VideoMode video; XVtc_Config *vtc_config ; int main() { XVtc_SourceSelect SourceSelect; XVtc_Timing vtcTiming; u32 height,width,status; init_platform(); print("Setting up Timingnr"); vtc_config = XVtc_LookupConfig(XPAR_XVTC_0_BASEADDR); XVtc_CfgInitialize(&VtcInst,vtc_config ,XPAR_XVTC_0_BASEADDR); print("Setting up Videonr"); video = VMODE_1280x720 ; vtcTiming.HActiveVideo = video.width; vtcTiming.HFrontPorch = video.hps - video.width; vtcTiming.HSyncWidth = video.hpe - video.hps; vtcTiming.HBackPorch = video.hmax - video.hpe + 1; vtcTiming.HSyncPolarity = video.hpol; vtcTiming.VActiveVideo = video.height; vtcTiming.V0FrontPorch = video.vps - video.height; vtcTiming.V0SyncWidth = video.vpe - video.vps; vtcTiming.V0BackPorch = video.vmax - video.vpe + 1;; vtcTiming.V1FrontPorch = video.vps - video.height; vtcTiming.V1SyncWidth = video.vpe - video.vps; vtcTiming.V1BackPorch = video.vmax - video.vpe + 1; vtcTiming.VSyncPolarity = video.vpol; vtcTiming.Interlaced = 0; print("Setting up TPGnr"); XV_tpg_Initialize(&tpg,XPAR_XV_TPG_0_BASEADDR ); status = XV_tpg_IsIdle(&tpg); XV_tpg_Set_height(&tpg, (u32) video.height); XV_tpg_Set_width(&tpg, (u32) video.width); height = XV_tpg_Get_height(&tpg); width = XV_tpg_Get_width(&tpg); XV_tpg_Set_colorFormat(&tpg,XVIDC_CSF_RGB); XV_tpg_Set_bckgndId(&tpg,XTPG_BKGND_TARTAN_COLOR_BARS); XV_tpg_Set_maskId(&tpg, 0x0); XV_tpg_Set_motionSpeed(&tpg, 0x4); XV_tpg_EnableAutoRestart(&tpg); XV_tpg_Start(&tpg); print("Setting up Sourcenr"); memset((void *)&SourceSelect, 0, sizeof(XVtc_SourceSelect)); SourceSelect.VBlankPolSrc = 1; SourceSelect.VSyncPolSrc = 1; SourceSelect.HBlankPolSrc = 1; SourceSelect.HSyncPolSrc = 1; SourceSelect.ActiveVideoPolSrc = 1; SourceSelect.ActiveChromaPolSrc= 1; SourceSelect.VChromaSrc = 1; SourceSelect.VActiveSrc = 1; SourceSelect.VBackPorchSrc = 1; SourceSelect.VSyncSrc = 1; SourceSelect.VFrontPorchSrc = 1; SourceSelect.VTotalSrc = 1; SourceSelect.HActiveSrc = 1; SourceSelect.HBackPorchSrc = 1; SourceSelect.HSyncSrc = 1; SourceSelect.HFrontPorchSrc = 1; SourceSelect.HTotalSrc = 1; print("Run Timing Gennr"); XVtc_SetGeneratorTiming(&VtcInst, &vtcTiming); XVtc_SetSource(&VtcInst, &SourceSelect); XVtc_EnableGenerator(&VtcInst); XVtc_RegUpdateEnable(&VtcInst); XVtc_Enable(&VtcInst); while(1){ }; cleanup_platform(); return 0; }
LCD_LVDS 這個模塊,我是直接從 ALINX 的 GitHub 倉庫上下載的。
下載好后,把它加到 Vivado 里面,就能像拼積木一樣拖進設計里。
LCD_LVDS 下載鏈接:https://github.com/alinxalinx/VD100_2023.2/tree/master/Demo/course_s1
寫好所有程序后,我們讓開發板運行,屏幕上果然顯示出了測試圖案,色彩鮮明,說明各個顏色通道都正常了。開發板和屏幕之間的溝通,算是正式打通了!
不過,這里面有個很有意思的事情。
Advanced IO Wizard 這個模塊,默認是按 8 位一組來打包數據發出去的。
而我們的 VESA LVDS 傳輸,要求 7 位一組。這咋辦?
我用到了一個叫做 Gearbox 的小模塊,把 7 位數據轉換成 4 位數據輸出。
然后,用 Advanced IO Wizard 把 4 位數據高速串行發出去。
這樣就實現了 7 位序列化,雖然中間多了一步變換,但整體還是很高效的。
不過,其實只要手動配置一下,Advanced IO Wizard 也是可以支持直接 7 位打包發送的,只是這次參考了 AMD 的官方應用筆記(參考代碼叫 tx_piso_7to1),所以先用了 Gearbox 的方式。
未來有機會的話,我想試著優化一下,直接用 7 位串行模式,把系統做得更簡潔高效!
接下來要做的
現在圖像輸出環節已經搞定了,接下來就是更刺激的前端部分:
通過 MIPI 接口接入攝像頭,把真實拍到的圖像,實時顯示到屏幕上。
真正的圖像處理任務,馬上就要開始啦!
(未完待續)
審核編輯 黃宇
-
FPGA
+關注
關注
1643文章
21944瀏覽量
613423 -
amd
+關注
關注
25文章
5555瀏覽量
135766 -
圖像處理
+關注
關注
27文章
1324瀏覽量
57643
發布評論請先 登錄
【ALINX 技術分享】AMD Versal AI Edge 自適應計算加速平臺之 Versal 介紹(2)

在Vivado中構建AMD Versal可擴展嵌入式平臺示例設計流程

Adam Taylor玩轉MicroZed系列第80部分

Adam Taylor玩轉MicroZed系列,第79部分
有哪些小技巧可以改進圖像處理開發
ALINX VERSAL SOM產品介紹
ALINX FPGA+GPU異架構視頻圖像處理開發平臺介紹
AMD推出第二代Versal Premium系列
ALINX 發布 AXVU13P:AMD Virtex UltraScale+ 高端 FPGA PCle 3.0 綜合開發平臺

面向AI與機器學習應用的開發平臺 AMD/Xilinx Versal? AI Edge VEK280

評論