该项目将大家一起使用Basys3板创建一个简单的示波器,花费时间约4小时。
硬件组件
Digilent Basys 3
软件应用程序和在线服务
Xilinx Vivado 设计套件
Xilinx Vitis 统一软件平台
项目介绍
Digilent Basys3 板是一款功能强大的板,可用于开始开发 FPGA 项目。它为用户提供了一个 Artix 35T 设备、USB-UART、四个 Pmod——包括一个为 XADC 配置的 Pmod、12 位 VGA 和开关、LED 和七段显示器。
该项目旨在演示 Basys3 板的功能,为此我们将创建一个简单的示波器,它可以使用 XDAC Pmod 输入通道和 VGA 显示器来显示波形。
为此,我们将使用 MicroBlaze 控制器来运行应用程序并控制 XADC 的测量,并确定在 VGA 屏幕上绘制数据的位置。
VGA 显示器将是 640 x 480,12 位 RGB 在软件内存中渲染需要 3、686、400 位。这超过了 FPGA 中可用的 1、800、000 位 BRAM。处理器也无法以能够达到所需帧速率所需的速度运行。
我们将通过使用处理器来确定数据点图来解决这个问题,同时逻辑渲染帧以实时显示。为此,我们将使用我们首先创建的高级综合核心。
高级综合核心
开始时要重新创建一个 HLS 核心,它可以在 VGA 显示器中绘制多达 10 个样本(当然,您可以稍后更改)。HLS 内核将生成一个 640 像素 x 480 行的 AXI 流。为了更新每一帧的显示,将有定义样本数据位置的 sample_x / _y 寄存器、定义数据点大小的寄存器和定义数据点颜色的最终寄存器。
创建 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); } } } |
请注意我如何使用两个循环在流中创建图像的 X 和 Y 元素。在内部循环中,我们处理 TUser 和 TLast 信号上的帧开始和行尾边带信号。
下一步是使用 C 来模拟电路,以确保行为符合我们的要求
创建的测试台可用于 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 图像,它应该展示绘制的点
在此示例中,数据点是绘制的白点。
在性能满意的情况下,下一步是综合和封装IP块以用于新的Vivado项目。
在HLS综合之后,预测的资源使用情况为
现在我们有了IP块,我们将能够将其添加到我们的项目中并开始Vivado设计。
Vivado设计
要开始使用Vivado设计,我们需要将以下IP添加到针对Basys3板创建的新项目中。
MicroBlaze-64KB数据和指令存储器
AXILiteUART
视频时序控制器-仅配置为生成
视频测试模式生成器-最大行数和列数800、800
XADC-启用Vaux6、7、14和15
时钟向导-20MHz(MicroBlaze)、25.175MHz(像素时钟)、50MHz(逻辑时钟)
视频混合器-最大行数和列数800、800
视频轴到视频输出
之前在HLS中创建的HUDIP
GPIO连接到按钮-光标的未来扩展
创建框图时,利用块自动化来配置MicroBlaze-添加内存、调试和休息结构。还利用连接自动化来连接AXI互连。
显示界面视图时,端图将类似于下图。
完整的设计如下
我会将完整的设计放在我的github上进行探索和修改。
图像路径将先前创建的HLSIP与TPG合并(允许设置背景颜色)。这些使用视频混合器核心合并,该核心使用alpha混合合并两个流。
生成的输出流被转换回并行视频输出格式Pixel、VSync、HSync等,为640、480显示器定时。AXIStream到视频的时序由视频时序发生器控制。
在这种方法中,软件应用程序可以使用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] |
完成后,可以构建应用程序并导出 XSA。
资源使用
软件开发
软件的开发很简单,生成的 HLS IP 内核带有用于 SW 开发的驱动程序。
软件应用程序必须执行以下操作
初始化 XADC
初始化 TPG
初始化混音器
初始化视频时序控制器
初始化 HLS IP
设置混合器以混合两个 640 x 480 流
设置 TPG 以输出所需的背景颜色
为 640 x 480 时序设置视频时序控制器
循环读取 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 显示的基本范围。
另外,我们可以创建一个简单的项目来展示如何在VGA输出上绘制点。
未来的改进方向可能如下:
添加标签和标记
添加光标以在屏幕上报告样本值
点之间的线绘制
当然,我们需要注意所需的逻辑资源,因为这个项目对设备资源的要求很高。
全部0条评论
快来发表一下你的评论吧 !