0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

科技观察员 来源:亚当泰勒 作者:亚当泰勒 2022-05-03 16:38 次阅读

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

poYBAGJdI2iAKDguAAcin69u3xA570.png

硬件组件

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 图像,它应该展示绘制的点

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

pYYBAGJdI1mAMgvhAAAjqRl1seU142.png

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

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

poYBAGJdI1aAFiDDAAKVjiWr70Y039.png

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

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

poYBAGJdI1GAVmPpAAEZYDdv6Mo922.png

完整的设计如下

pYYBAGJdI02AKvbpAAHdhaTyZRM086.png

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

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

pYYBAGJdI0mAJ9WuAAIe9mgelyI566.png

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

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

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

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

pYYBAGJdI0WAL8GXAAH1DVWqTF0588.png

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

资源使用

poYBAGJdIzqAU6fsAAFE7WeHrM4826.png

软件开发

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

pYYBAGJdIzCAISHzAAMzBzQh-F8566.png

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

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

添加标签和标记

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

点之间的线绘制

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

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

    关注

    1625

    文章

    21663

    浏览量

    601666
收藏 人收藏

    评论

    相关推荐

    xilinx的basys3板子的4位7段数码管4数字中间有两点

    xilinx的basys3板子的4位7段数码管4数字中间有两点,请问这个管脚是什么。
    发表于 04-13 12:51

    初学请教:nesys3basys3学习选择

    本人初学FPGA,想入手块二手板子。看到网上有卖nesys3basys3板子,看到用nesys3的人比较多,basys3板子资源比nes
    发表于 08-02 08:20

    出手块全新的FPGA开发 Xilinx Basys 3 原装未拆过

    本帖最后由 FPGA爱好者_001 于 2017-9-10 20:04 编辑 我在闲鱼卖·全新 FPGA学习开发 Basys3 原装#来闲鱼,发现更多闲置超值好物#ht去掉tp://a.p6去掉ff.com/F.XMRXL
    发表于 09-10 20:02

    基于FPGA vivado 17.2 Basys3 示波器实验设计

    的基本组成结构二、实验原理介绍数字存储示波器能够将模拟信号进行采样、存储以及显示。本系统在DIGILENT Basys3上构建了简易数字存储示波
    发表于 12-22 20:28

    basys3电子钟的代码,包括校时和闹钟功能,拜托各位大神了~~~~

    basys3电子钟的代码,包括校时和闹钟功能,拜托各位大神了~~~~
    发表于 04-08 16:16

    Basys3 时钟上升沿很长,是什么原因?

    大家好,我在用 Basys3一个简单的电路时,发现问题。程序代码:module Pmod_Top( input clk, outpu
    发表于 04-12 10:50

    紧急求助 basys3的板子怎么实现用u***-a接口的通信

    正在做一个计算机设计的课设 要求用verilog和汇编设计mips现在汇编和mips都已经写好了 但是要求要用xlinx的basys3 这块板子的USB-A接口接USB键盘完成输入
    发表于 07-07 11:39

    有没有用basys3的摄像头图像显示

    现在手上有basys3,ov7670摄像头无fifo,还有iic模块应该是好了,之后改如何操作,是否为建立bram,但向bram里面传输数据的地址没法确定希望大家给简明点的主意
    发表于 05-26 14:14

    基于 FPGA Vivado 示波器设计(附源工程)

    工程代码,可在公众号内回复“示波器设计源工程”。 原理介绍 数字存储示波器能够将模拟信号进行采样、存储以及显示。本系统在DIGILENT Basys3上构建了
    发表于 08-17 19:31

    基于Vivado 的Basys3开发的解码教程

    基于Vivado 的Basys3开发的解码教程
    发表于 08-03 19:37 66次下载

    Basys3开发板实现示波器设计

    、目的 1)掌握基于v文件的vivado工程设计流程 2)学习示波器的基本组成结构 二、原理介绍 数字存储示波器能够将模拟信号进行采样、存储以及显示。本系统在Basys3上构建了
    发表于 02-08 14:53 1282次阅读
    <b class='flag-5'>Basys3</b>开发板实现<b class='flag-5'>示波器</b>设计

    Basys3开发的MicroBlaze串口实验

    microblaze基本结构 3.实现microblaze调用uart模块,完成串口打印功能。 实验原理:本系统中,Basys3的Microblaze模块调用基于AXI协议的uart IP核,通过
    发表于 02-08 15:05 968次阅读
    <b class='flag-5'>Basys3</b>开发<b class='flag-5'>板</b>的MicroBlaze串口实验

    创建工程项目并使用三种方法下载工程项目到Basys3 FPGA开发上教程

    旧版Vivado均可使用,但是步骤可能有些许不同 源文件 . basys3_sw_demo.zip 教程 1. 创建工程项目 首先,我们要创建
    发表于 11-15 14:10 1w次阅读
    <b class='flag-5'>创建</b>工程项目并使用三种方法下载工程项目到<b class='flag-5'>Basys3</b> FPGA开发<b class='flag-5'>板</b>上教程

    用于Basys3的VHDL中的UART接口

    电子发烧友网站提供《用于Basys3的VHDL中的UART接口.zip》资料免费下载
    发表于 11-22 09:50 2次下载
    用于<b class='flag-5'>Basys3</b><b class='flag-5'>板</b>的VHDL中的UART接口

    verilog设计之基于basys3实现的简易分秒数字钟

    基于basys3实现的简易分秒数字钟
    发表于 09-03 14:15 0次下载