該項目將大家一起使用Basys3板創(chuàng)建一個簡單的示波器,花費時間約4小時。
硬件組件
Digilent Basys 3
軟件應用程序和在線服務
Xilinx Vivado 設計套件
Xilinx Vitis 統(tǒng)一軟件平臺
項目介紹
Digilent Basys3 板是一款功能強大的板,可用于開始開發(fā) FPGA 項目。它為用戶提供了一個 Artix 35T 設備、USB-UART、四個 Pmod——包括一個為 XADC 配置的 Pmod、12 位 VGA 和開關、LED 和七段顯示器。
該項目旨在演示 Basys3 板的功能,為此我們將創(chuàng)建一個簡單的示波器,它可以使用 XDAC Pmod 輸入通道和 VGA 顯示器來顯示波形。
為此,我們將使用 MicroBlaze 控制器來運行應用程序并控制 XADC 的測量,并確定在 VGA 屏幕上繪制數(shù)據(jù)的位置。
VGA 顯示器將是 640 x 480,12 位 RGB 在軟件內(nèi)存中渲染需要 3、686、400 位。這超過了 FPGA 中可用的 1、800、000 位 BRAM。處理器也無法以能夠達到所需幀速率所需的速度運行。
我們將通過使用處理器來確定數(shù)據(jù)點圖來解決這個問題,同時邏輯渲染幀以實時顯示。為此,我們將使用我們首先創(chuàng)建的高級綜合核心。
高級綜合核心
開始時要重新創(chuàng)建一個 HLS 核心,它可以在 VGA 顯示器中繪制多達 10 個樣本(當然,您可以稍后更改)。HLS 內(nèi)核將生成一個 640 像素 x 480 行的 AXI 流。為了更新每一幀的顯示,將有定義樣本數(shù)據(jù)位置的 sample_x / _y 寄存器、定義數(shù)據(jù)點大小的寄存器和定義數(shù)據(jù)點顏色的最終寄存器。
創(chuàng)建 HLS 流需要使用 ap_fixed.h 和 hls_video.h 庫進行簡單定義。
我們將有一個 32 位像素,其中包括每個 RGB 的 8 位,還有一個用于混合的 8 位 alpha 通道。
hud.h 文件包括以下幾行
#include "hls_video.h" #include #include "string.h" #define WIDTH 32 //32 as alpha channel typedef ap_uint<8> pixel_type; typedef hls::stream typedef ap_axiu void hud_gen(axis& op, int row, int column, int plot_x_1, int plot_y_1, int plot_x_2, int plot_y_2, int plot_x_3, int plot_y_3, int plot_x_4, int plot_y_4, int plot_x_5, int plot_y_5, int plot_x_6, int plot_y_6, int plot_x_7, int plot_y_7, int plot_x_8, int plot_y_8, int plot_x_9, int plot_y_9, int plot_x_10, int plot_y_10, int plot_x_11, int plot_y_11, int plot_x_12, int plot_y_12, int plot_x_13, int plot_y_13, int plot_x_14, int plot_y_14, int plot_x_15, int plot_y_15, int plot_x_16, int plot_y_16, int plot_x_17, int plot_y_17, int plot_x_18, int plot_y_18, int plot_x_19, int plot_y_19, int plot_x_20, int plot_y_20, int plot_size, uint32_t plot_colour ) ; |
雖然代碼的主體看起來像
#include "hud.h" //#include "char.h" void hud_gen(axis& op, int row, int column, int plot_x_1, int plot_y_1, int plot_x_2, int plot_y_2, int plot_x_3, int plot_y_3, int plot_x_4, int plot_y_4, int plot_x_5, int plot_y_5, int plot_x_6, int plot_y_6, int plot_x_7, int plot_y_7, int plot_x_8, int plot_y_8, int plot_x_9, int plot_y_9, int plot_x_10, int plot_y_10, int plot_x_11, int plot_y_11, int plot_x_12, int plot_y_12, int plot_x_13, int plot_y_13, int plot_x_14, int plot_y_14, int plot_x_15, int plot_y_15, int plot_x_16, int plot_y_16, int plot_x_17, int plot_y_17, int plot_x_18, int plot_y_18, int plot_x_19, int plot_y_19, int plot_x_20, int plot_y_20, int plot_size, uint32_t plot_colour ) { #pragma HLS INTERFACE s_axilite port=return #pragma HLS INTERFACE s_axilite port=plot_y_1 #pragma HLS INTERFACE s_axilite port=plot_x_1 #pragma HLS INTERFACE s_axilite port=plot_y_2 #pragma HLS INTERFACE s_axilite port=plot_x_2 #pragma HLS INTERFACE s_axilite port=plot_y_3 #pragma HLS INTERFACE s_axilite port=plot_x_3 #pragma HLS INTERFACE s_axilite port=plot_y_4 #pragma HLS INTERFACE s_axilite port=plot_x_4 #pragma HLS INTERFACE s_axilite port=plot_y_5 #pragma HLS INTERFACE s_axilite port=plot_x_5 #pragma HLS INTERFACE s_axilite port=plot_y_6 #pragma HLS INTERFACE s_axilite port=plot_x_6 #pragma HLS INTERFACE s_axilite port=plot_y_7 #pragma HLS INTERFACE s_axilite port=plot_x_7 #pragma HLS INTERFACE s_axilite port=plot_y_8 #pragma HLS INTERFACE s_axilite port=plot_x_8 #pragma HLS INTERFACE s_axilite port=plot_y_9 #pragma HLS INTERFACE s_axilite port=plot_x_9 #pragma HLS INTERFACE s_axilite port=plot_y_10 #pragma HLS INTERFACE s_axilite port=plot_x_10 #pragma HLS INTERFACE s_axilite port=plot_y_11 #pragma HLS INTERFACE s_axilite port=plot_x_11 #pragma HLS INTERFACE s_axilite port=plot_y_12 #pragma HLS INTERFACE s_axilite port=plot_x_12 #pragma HLS INTERFACE s_axilite port=plot_y_13 #pragma HLS INTERFACE s_axilite port=plot_x_13 #pragma HLS INTERFACE s_axilite port=plot_y_14 #pragma HLS INTERFACE s_axilite port=plot_x_14 #pragma HLS INTERFACE s_axilite port=plot_y_15 #pragma HLS INTERFACE s_axilite port=plot_x_15 #pragma HLS INTERFACE s_axilite port=plot_y_16 #pragma HLS INTERFACE s_axilite port=plot_x_16 #pragma HLS INTERFACE s_axilite port=plot_y_17 #pragma HLS INTERFACE s_axilite port=plot_x_17 #pragma HLS INTERFACE s_axilite port=plot_y_18 #pragma HLS INTERFACE s_axilite port=plot_x_18 #pragma HLS INTERFACE s_axilite port=plot_y_19 #pragma HLS INTERFACE s_axilite port=plot_x_19 #pragma HLS INTERFACE s_axilite port=plot_y_20 #pragma HLS INTERFACE s_axilite port=plot_x_20 #pragma HLS INTERFACE s_axilite port=column #pragma HLS INTERFACE s_axilite port=row #pragma HLS INTERFACE s_axilite port=plot_size #pragma HLS INTERFACE s_axilite port=plot_colour #pragma HLS INTERFACE axis register both port=op int i = 0; int y = 0; int x = 0; //int bar_pos_x = 10; //int bar_width = 30; video_stream hud_int; row_loop:for (y =0; y if (y == 0 && x == 0 ){ hud_int.user = 1; } else{ if (x == (column-1) ){ hud_int.last = 1; } else{ hud_int.last = 0; hud_int.user = 0; if ((( x >= (plot_x_1 - plot_size)) & (x <= plot_x_1 + plot_size)) & ?(( y >= (plot_y_1 - plot_size)) & (y <= plot_y_1 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_2 - plot_size)) & (x <= plot_x_2 + plot_size)) & ?(( y >= (plot_y_2 - plot_size)) & (y <= plot_y_2 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_3 - plot_size)) & (x <= plot_x_3 + plot_size)) & ?(( y >= (plot_y_3 - plot_size)) & (y <= plot_y_3 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_4 - plot_size)) & (x <= plot_x_4 + plot_size)) & ?(( y >= (plot_y_4 - plot_size)) & (y <= plot_y_4 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_5 - plot_size)) & (x <= plot_x_5 + plot_size)) & ?(( y >= (plot_y_5 - plot_size)) & (y <= plot_y_5 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_6 - plot_size)) & (x <= plot_x_6 + plot_size)) & ?(( y >= (plot_y_6 - plot_size)) & (y <= plot_y_6 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_7 - plot_size)) & (x <= plot_x_7 + plot_size)) & ?(( y >= (plot_y_7 - plot_size)) & (y <= plot_y_7 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_8 - plot_size)) & (x <= plot_x_8 + plot_size)) & ?(( y >= (plot_y_8 - plot_size)) & (y <= plot_y_8 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_9 - plot_size)) & (x <= plot_x_9 + plot_size)) & ?(( y >= (plot_y_9 - plot_size)) & (y <= plot_y_9 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_10 - plot_size)) & (x <= plot_x_10 + plot_size)) & ?(( y >= (plot_y_10 - plot_size)) & (y <= plot_y_10 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_11 - plot_size)) & (x <= plot_x_11 + plot_size)) & ?(( y >= (plot_y_11 - plot_size)) & (y <= plot_y_11 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_12 - plot_size)) & (x <= plot_x_12 + plot_size)) & ?(( y >= (plot_y_12 - plot_size)) & (y <= plot_y_12 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_13 - plot_size)) & (x <= plot_x_13 + plot_size)) & ?(( y >= (plot_y_13 - plot_size)) & (y <= plot_y_13 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_14 - plot_size)) & (x <= plot_x_14 + plot_size)) & ?(( y >= (plot_y_14 - plot_size)) & (y <= plot_y_14 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_15 - plot_size)) & (x <= plot_x_15 + plot_size)) & ?(( y >= (plot_y_15 - plot_size)) & (y <= plot_y_15 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_16 - plot_size)) & (x <= plot_x_16 + plot_size)) & ?(( y >= (plot_y_16 - plot_size)) & (y <= plot_y_16 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_17 - plot_size)) & (x <= plot_x_17 + plot_size)) & ?(( y >= (plot_y_17 - plot_size)) & (y <= plot_y_17 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_18 - plot_size)) & (x <= plot_x_18 + plot_size)) & ?(( y >= (plot_y_18 - plot_size)) & (y <= plot_y_18 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_19 - plot_size)) & (x <= plot_x_19 + plot_size)) & ?(( y >= (plot_y_19 - plot_size)) & (y <= plot_y_19 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else if ((( x >= (plot_x_20 - plot_size)) & (x <= plot_x_20 + plot_size)) & ?(( y >= (plot_y_20 - plot_size)) & (y <= plot_y_20 + plot_size))){ hud_int.data = 0x7f0000ff;//0x7f0000ff; //should be green and high alpha } else{ if (( y >= 0 & y < 3 ) | ( y>= column-3 & y < column) | (x >= 0 & x < 3)){ hud_int.data = 0x7f0000ff; } else { hud_int.data = 0; } } } } op.write(hud_int); } } } |
請注意我如何使用兩個循環(huán)在流中創(chuàng)建圖像的 X 和 Y 元素。在內(nèi)部循環(huán)中,我們處理 TUser 和 TLast 信號上的幀開始和行尾邊帶信號。
下一步是使用 C 來模擬電路,以確保行為符合我們的要求
創(chuàng)建的測試臺可用于 C 和 Co 仿真
#include "hud.h" #include int main (int argc, char** argv) { IplImage* src; IplImage* dst; axis dst_axi; int y; dst = cvCreateImage(cvSize(640,480),IPL_DEPTH_32S, 1); //hud_gen( dst_axi, 480, 640, 240, 320, 5, 0x7f0000ff, 600, 30); hud_gen( dst_axi, 480, 640, 0, 141, 32, 158, 64, 140, 96, 145, 128, 150, 160, 140, 192, 130, 224, 145, 256, 156, 288, 135, 320, 130, 352, 140, 384, 149, 416, 139, 448, 130, 480, 140, 512, 160, 544, 140, 576, 145, 608, 150, 5, 0x7f0000ff ); AXIvideo2IplImage(dst_axi, dst); cvSaveImage("op.bmp", dst); cvReleaseImage(&dst); } |
運行 C 模擬為我們提供了一個 BMP 圖像,它應該展示繪制的點
在此示例中,數(shù)據(jù)點是繪制的白點。
在性能滿意的情況下,下一步是綜合和封裝IP塊以用于新的Vivado項目。
在HLS綜合之后,預測的資源使用情況為
現(xiàn)在我們有了IP塊,我們將能夠?qū)⑵涮砑拥轿覀兊捻椖恐胁㈤_始Vivado設計。
Vivado設計
要開始使用Vivado設計,我們需要將以下IP添加到針對Basys3板創(chuàng)建的新項目中。
MicroBlaze-64KB數(shù)據(jù)和指令存儲器
AXILiteUART
視頻時序控制器-僅配置為生成
視頻測試模式生成器-最大行數(shù)和列數(shù)800、800
XADC-啟用Vaux6、7、14和15
時鐘向?qū)?20MHz(MicroBlaze)、25.175MHz(像素時鐘)、50MHz(邏輯時鐘)
視頻混合器-最大行數(shù)和列數(shù)800、800
視頻軸到視頻輸出
之前在HLS中創(chuàng)建的HUDIP
GPIO連接到按鈕-光標的未來擴展
創(chuàng)建框圖時,利用塊自動化來配置MicroBlaze-添加內(nèi)存、調(diào)試和休息結(jié)構(gòu)。還利用連接自動化來連接AXI互連。
顯示界面視圖時,端圖將類似于下圖。
完整的設計如下
我會將完整的設計放在我的github上進行探索和修改。
圖像路徑將先前創(chuàng)建的HLSIP與TPG合并(允許設置背景顏色)。這些使用視頻混合器核心合并,該核心使用alpha混合合并兩個流。
生成的輸出流被轉(zhuǎn)換回并行視頻輸出格式Pixel、VSync、HSync等,為640、480顯示器定時。AXIStream到視頻的時序由視頻時序發(fā)生器控制。
在這種方法中,軟件應用程序可以使用TPG設置背景并使用HLSIP定義繪圖。
為了確保設計適用于所有VGA顯示器,我們需要確保RGB信號在消隱期間為0。
因此,我使用了一個與門邏輯IP塊,該IP塊由AXI流提供的視頻輸出啟用門控到視頻輸出塊。Basys3上的VGA輸出使用每個通道RGB的3個輸出。為了提供可重復使用的設計,我們使用了在設計中更常見的8位像素,以允許移植到不同的板上。
該項目使用的XDC如下
##7 segment display set_property PACKAGE_PIN W7 [get_ports {seven_seg[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg[0]}] set_property PACKAGE_PIN W6 [get_ports {seven_seg[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg[1]}] set_property PACKAGE_PIN U8 [get_ports {seven_seg[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg[2]}] set_property PACKAGE_PIN V8 [get_ports {seven_seg[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg[3]}] set_property PACKAGE_PIN U5 [get_ports {seven_seg[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg[4]}] set_property PACKAGE_PIN V5 [get_ports {seven_seg[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg[5]}] set_property PACKAGE_PIN U7 [get_ports {seven_seg[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg[6]}] #set_property PACKAGE_PIN V7 [get_ports dp] #set_property IOSTANDARD LVCMOS33 [get_ports dp] set_property PACKAGE_PIN U2 [get_ports {seven_seg_led_an[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg_led_an[0]}] set_property PACKAGE_PIN U4 [get_ports {seven_seg_led_an[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg_led_an[1]}] set_property PACKAGE_PIN V4 [get_ports {seven_seg_led_an[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg_led_an[2]}] set_property PACKAGE_PIN W4 [get_ports {seven_seg_led_an[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {seven_seg_led_an[3]}] set_property PACKAGE_PIN W5 [get_ports sys_clock] set_property IOSTANDARD LVCMOS33 [get_ports sys_clock] #create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk] ##VGA Connector set_property PACKAGE_PIN G19 [get_ports {vgaRed[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[0]}] set_property PACKAGE_PIN H19 [get_ports {vgaRed[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[1]}] set_property PACKAGE_PIN J19 [get_ports {vgaRed[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[2]}] set_property PACKAGE_PIN N19 [get_ports {vgaRed[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaRed[3]}] set_property PACKAGE_PIN N18 [get_ports {vgaBlue[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[0]}] set_property PACKAGE_PIN L18 [get_ports {vgaBlue[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[1]}] set_property PACKAGE_PIN K18 [get_ports {vgaBlue[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[2]}] set_property PACKAGE_PIN J18 [get_ports {vgaBlue[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaBlue[3]}] set_property PACKAGE_PIN J17 [get_ports {vgaGreen[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[0]}] set_property PACKAGE_PIN H17 [get_ports {vgaGreen[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[1]}] set_property PACKAGE_PIN G17 [get_ports {vgaGreen[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[2]}] set_property PACKAGE_PIN D17 [get_ports {vgaGreen[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {vgaGreen[3]}] set_property PACKAGE_PIN P19 [get_ports Hsync] set_property IOSTANDARD LVCMOS33 [get_ports Hsync] set_property PACKAGE_PIN R19 [get_ports Vsync] set_property IOSTANDARD LVCMOS33 [get_ports Vsync] set_property DRIVE 8 [get_ports {vgaBlue[3]}] set_property DRIVE 8 [get_ports {vgaBlue[2]}] set_property DRIVE 8 [get_ports {vgaBlue[1]}] set_property DRIVE 8 [get_ports {vgaBlue[0]}] set_property DRIVE 8 [get_ports {vgaGreen[3]}] set_property DRIVE 8 [get_ports {vgaGreen[2]}] set_property DRIVE 8 [get_ports {vgaGreen[1]}] set_property DRIVE 8 [get_ports {vgaGreen[0]}] set_property DRIVE 8 [get_ports {vgaRed[3]}] set_property DRIVE 8 [get_ports {vgaRed[2]}] set_property DRIVE 8 [get_ports {vgaRed[1]}] set_property DRIVE 8 [get_ports {vgaRed[0]}] set_property DRIVE 8 [get_ports Hsync] set_property DRIVE 8 [get_ports Vsync] set_property C_CLK_INPUT_FREQ_HZ 300000000 [get_debug_cores dbg_hub] set_property C_ENABLE_CLK_DIVIDER false [get_debug_cores dbg_hub] set_property C_USER_SCAN_CHAIN 1 [get_debug_cores dbg_hub] connect_debug_port dbg_hub/clk [get_nets clk] |
完成后,可以構(gòu)建應用程序并導出 XSA。
資源使用
軟件開發(fā)
軟件的開發(fā)很簡單,生成的 HLS IP 內(nèi)核帶有用于 SW 開發(fā)的驅(qū)動程序。
軟件應用程序必須執(zhí)行以下操作
初始化 XADC
初始化 TPG
初始化混音器
初始化視頻時序控制器
初始化 HLS IP
設置混合器以混合兩個 640 x 480 流
設置 TPG 以輸出所需的背景顏色
為 640 x 480 時序設置視頻時序控制器
循環(huán)讀取 XADC 并更新
應用代碼如下
#include #include #include "platform.h" #include "xil_printf.h" #include "xparameters.h" #include "xvtc.h" #include "vga_modes.h" #include "xv_tpg.h" #include "xvidc.h" #include "xv_mix.h" #include "xhud_gen.h" #include "xgpio.h" XVtc VtcInst; XVtc_Config *vtc_config ; XV_tpg tpg; XV_tpg_Config *tpg_config; XGpio_Config *gpio_config; XGpio gpio; VideoMode video; int main() { XVtc_Timing vtcTiming; XVtc_SourceSelect SourceSelect; XV_mix xv_mix; XV_mix_Config *xv_config; XHud_gen_Config *XV_Hud_cfg; XHud_gen xv_hud; init_platform(); print("Hello World\n\r"); print("Successfully ran Hello World application"); gpio_config = XGpio_LookupConfig(XPAR_GPIO_0_DEVICE_ID); XGpio_CfgInitialize(&gpio,gpio_config, gpio_config->BaseAddress); XGpio_SetDataDirection(&gpio,1,0xFFFFFFFF); XGpio_SetDataDirection(&gpio,2,0x00000000); vtc_config = XVtc_LookupConfig(XPAR_VTC_0_DEVICE_ID); XVtc_CfgInitialize(&VtcInst, vtc_config, vtc_config->BaseAddress); video = VMODE_640x480; vtcTiming.HActiveVideo = video.width; /**< Horizontal Active Video Size */ vtcTiming.HFrontPorch = video.hps - video.width; /**< Horizontal Front Porch Size */ vtcTiming.HSyncWidth = video.hpe - video.hps; /**< Horizontal Sync Width */ vtcTiming.HBackPorch = video.hmax - video.hpe + 1; /**< Horizontal Back Porch Size */ vtcTiming.HSyncPolarity = video.hpol; /**< Horizontal Sync Polarity */ vtcTiming.VActiveVideo = video.height; /**< Vertical Active Video Size */ vtcTiming.V0FrontPorch = video.vps - video.height; /**< Vertical Front Porch Size */ vtcTiming.V0SyncWidth = video.vpe - video.vps; /**< Vertical Sync Width */ vtcTiming.V0BackPorch = video.vmax - video.vpe + 1;; /**< Horizontal Back Porch Size */ vtcTiming.V1FrontPorch = video.vps - video.height; /**< Vertical Front Porch Size */ vtcTiming.V1SyncWidth = video.vpe - video.vps; /**< Vertical Sync Width */ vtcTiming.V1BackPorch = video.vmax - video.vpe + 1;; /**< Horizontal Back Porch Size */ vtcTiming.VSyncPolarity = video.vpol; /**< Vertical Sync Polarity */ vtcTiming.Interlaced = 0; memset((void *)&SourceSelect, 0, sizeof(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; XVtc_RegUpdateEnable(&VtcInst); XVtc_SetGeneratorTiming(&VtcInst, &vtcTiming); XVtc_SetSource(&VtcInst, &SourceSelect); XVtc_EnableGenerator(&VtcInst); xv_config = XV_mix_LookupConfig(XPAR_XV_MIX_0_DEVICE_ID); XV_mix_CfgInitialize(&xv_mix,xv_config,xv_config->BaseAddress); XV_mix_Set_HwReg_width(&xv_mix, (u32)640); XV_mix_Set_HwReg_height(&xv_mix, (u32) 480); XV_mix_Set_HwReg_layerEnable(&xv_mix,(u32)3); XV_mix_Set_HwReg_layerStartX_0(&xv_mix,(u32)0); XV_mix_Set_HwReg_layerStartY_0(&xv_mix,0); XV_mix_Set_HwReg_layerWidth_0(&xv_mix,(u32)640); XV_mix_Set_HwReg_layerHeight_0(&xv_mix,(u32)480); XV_mix_Set_HwReg_layerAlpha_0(&xv_mix, 225); XV_mix_Set_HwReg_layerStartX_1(&xv_mix,(u32)0); XV_mix_Set_HwReg_layerStartY_1(&xv_mix,0); XV_mix_Set_HwReg_layerWidth_1(&xv_mix,(u32)640); XV_mix_Set_HwReg_layerHeight_1(&xv_mix,(u32)480); XV_mix_Set_HwReg_layerAlpha_1(&xv_mix, 225); XV_mix_EnableAutoRestart(&xv_mix); XV_mix_Start(&xv_mix); XV_Hud_cfg = XHud_gen_LookupConfig(XPAR_HUD_GEN_0_DEVICE_ID); XHud_gen_CfgInitialize(&xv_hud,XV_Hud_cfg); XHud_gen_Set_row(&xv_hud, (u32) 480); XHud_gen_Set_column(&xv_hud, (u32) 640); // XHud_gen_Set_ball_y(&xv_hud, (u32) (640/2)); // XHud_gen_Set_ball_x(&xv_hud, (u32) (280/2)); XHud_gen_Set_plot_size(&xv_hud, (u32) 5); XHud_gen_Set_plot_colour(&xv_hud, (u32) 0x7fffffff); XHud_gen_EnableAutoRestart(&xv_hud); XHud_gen_Start(&xv_hud); XVtc_Enable(&VtcInst); u32 height,width,status; tpg_config = XV_tpg_LookupConfig(XPAR_XV_TPG_0_DEVICE_ID); XV_tpg_CfgInitialize(&tpg, tpg_config, tpg_config->BaseAddress); status = XV_tpg_IsReady(&tpg); printf("TPG Status %u \n\r", (unsigned int) status); 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_maskId(&tpg, 0x0); XV_tpg_Set_motionSpeed(&tpg, 0x4); printf("info from tpg %u %u \n\r", (unsigned int)height, (unsigned int)width); XV_tpg_Set_bckgndId(&tpg,XTPG_BKGND_SOLID_BLUE);//XTPG_BKGND_COLOR_BARS); //); status = XV_tpg_Get_bckgndId(&tpg); printf("Status %x \n\r", (unsigned int) status); XV_tpg_EnableAutoRestart(&tpg); XV_tpg_Start(&tpg); status = XV_tpg_IsIdle(&tpg); printf("Status %u \n\r", (unsigned int) status); XHud_gen_Set_plot_x_1(&xv_hud, 64); XHud_gen_Set_plot_y_1(&xv_hud, 441); XHud_gen_Set_plot_x_2(&xv_hud, 128); XHud_gen_Set_plot_y_2(&xv_hud, 458); XHud_gen_Set_plot_x_3(&xv_hud, 192); XHud_gen_Set_plot_y_3(&xv_hud, 273); XHud_gen_Set_plot_x_4(&xv_hud, 256); XHud_gen_Set_plot_y_4(&xv_hud, 58); XHud_gen_Set_plot_x_5(&xv_hud, 320); XHud_gen_Set_plot_y_5(&xv_hud, 9); XHud_gen_Set_plot_x_6(&xv_hud, 384); XHud_gen_Set_plot_y_6(&xv_hud, 172); XHud_gen_Set_plot_x_7(&xv_hud, 448); XHud_gen_Set_plot_y_7(&xv_hud, 397); XHud_gen_Set_plot_x_8(&xv_hud, 512); XHud_gen_Set_plot_y_8(&xv_hud, 477); XHud_gen_Set_plot_x_9(&xv_hud, 576); XHud_gen_Set_plot_y_9(&xv_hud, 338); XHud_gen_Set_plot_x_10(&xv_hud, 640); XHud_gen_Set_plot_y_10(&xv_hud, 109); cleanup_platform(); return 0; } |
當輸出時,這會提供一個漂亮的彩色顯示,作為 VGA 顯示的基本范圍。
另外,我們可以創(chuàng)建一個簡單的項目來展示如何在VGA輸出上繪制點。
未來的改進方向可能如下:
添加標簽和標記
添加光標以在屏幕上報告樣本值
點之間的線繪制
當然,我們需要注意所需的邏輯資源,因為這個項目對設備資源的要求很高。
-
FPGA
+關注
關注
1629文章
21729瀏覽量
602978
發(fā)布評論請先 登錄
相關推薦
評論