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
    +关注

    关注

    1603

    文章

    21326

    浏览量

    593249
收藏 人收藏

    评论

    相关推荐

    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

    怎么使用自动量程在VHDL Basys2中创建频率计数器

    我必须使用自动量程在VHDL Basys2中创建频率计数器。有人能帮我吗?我是初学者以上来自于谷歌翻译以下为原文I must make a Frequency counter in
    发表于 03-05 13:44

    有没有用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 65次下载

    Basys3开发板实现示波器设计

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

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

    Basys 3 支持以下三种方式配置/下载程序: . JTAG . Quad SPI Flash . USB Flash Drive 此教程旨在告诉初学者如何开始创建工程项目以及分别通过以上三种
    发表于 11-15 14:10 9714次阅读
    <b class='flag-5'>创建</b>工程项目并使用三种方法下载工程项目到<b class='flag-5'>Basys3</b> FPGA开发板上教程

    用于Basys3板的VHDL中的UART接口

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