如何使用Basys3板创建一个简单的示波器

描述

  该项目将大家一起使用Basys3板创建一个简单的示波器,花费时间约4小时。

FPGA

  硬件组件

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 > axis;
typedef ap_axiu video_stream;
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  column_loop:for (x =0; x <  column; x++) {
     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 图像,它应该展示绘制的点

在此示例中,数据点是绘制的白点。

FPGA

  在性能满意的情况下,下一步是综合和封装IP块以用于新的Vivado项目。

  在HLS综合之后,预测的资源使用情况为

FPGA

  现在我们有了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互连。

  显示界面视图时,端图将类似于下图。

FPGA

  完整的设计如下

FPGA

  我会将完整的设计放在我的github上进行探索和修改。

  图像路径将先前创建的HLSIP与TPG合并(允许设置背景颜色)。这些使用视频混合器核心合并,该核心使用alpha混合合并两个流。

FPGA

  生成的输出流被转换回并行视频输出格式Pixel、VSync、HSync等,为640、480显示器定时。AXIStream到视频的时序由视频时序发生器控制。

  在这种方法中,软件应用程序可以使用TPG设置背景并使用HLSIP定义绘图。

  为了确保设计适用于所有VGA显示器,我们需要确保RGB信号在消隐期间为0。

  因此,我使用了一个与门逻辑IP块,该IP块由AXI流提供的视频输出启用门控到视频输出块。Basys3上的VGA输出使用每个通道RGB的3个输出。为了提供可重复使用的设计,我们使用了在设计中更常见的8位像素,以允许移植到不同的板上。

FPGA

  该项目使用的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。

资源使用

FPGA

  软件开发

软件的开发很简单,生成的 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 显示的基本范围。

FPGA

  另外,我们可以创建一个简单的项目来展示如何在VGA输出上绘制点。

  未来的改进方向可能如下:

  添加标签和标记

  添加光标以在屏幕上报告样本值

  点之间的线绘制

  当然,我们需要注意所需的逻辑资源,因为这个项目对设备资源的要求很高。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分