Home > Detection Circuits >Instrumentation > How to create a simple oscilloscope using the Basys3 board

How to create a simple oscilloscope using the Basys3 board

Source: InternetPublisher:无人共我 Keywords: fpga Updated: 2024/03/01

This project will involve everyone working together to create a simple oscilloscope using the Basys3 board, which will take about 4 hours.

Hardware components

Digilent Basys 3

Software applications and online services

Xilinx Vivado Design Suite

Xilinx Vitis Unified Software Platform

Project Introduction

The Digilent Basys3 board is a powerful board with which to start developing FPGA projects. It provides the user with an Artix 35T device, USB-UART, four Pmods - including one configured for XADC, 12-bit VGA and switches, LEDs and seven-segment display.

This project is intended to demonstrate the capabilities of the Basys3 board, for which we will create a simple oscilloscope that can display waveforms using the XDAC Pmod input channel and a VGA monitor.

To do this, we will use the MicroBlaze controller to run the application and control the XADC measurements and determine where to draw the data on the VGA screen.

A VGA monitor will be 640 x 480, and 12-bit RGB requires 3, 686, 400 bits to render in software memory. This exceeds the 1, 800, 000 bits of BRAM available in FPGAs. The processor also wasn't able to run at the speed needed to be able to achieve the required frame rates.

We will solve this problem by using the processor to determine the data point plot while logically rendering the frame for real-time display. To do this, we'll use the high-level synthesis core we first created.

The Advanced Synthesis Core
begins by recreating an HLS core that can draw up to 10 samples into a VGA monitor (of course, you can change this later). The HLS kernel will generate a 640 pixel x 480 line AXI stream. To update the display each frame, there will be sample_x/_y registers that define the location of the sample data, a register that defines the size of the data points, and a final register that defines the color of the data points.

Creating HLS streams requires simple definition using the ap_fixed.h and hls_video.h libraries.

We will have a 32-bit pixel, which includes 8 bits for each RGB, and an 8-bit alpha channel for blending.

The hud.h file includes the following lines

#include "hls_video.h"
#include

While the body of the code looks like

#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

请注意我如何使用两个循环在流中创建图像的 X 和 Y 元素。在内部循环中,我们处理 TUser 和 TLast 信号上的帧开始和行尾边带信号。

下一步是使用 C 来模拟电路,以确保行为符合我们的要求

创建的测试台可用于 C 和 Co 仿真

#include "hud.h"
#include

运行 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_port s {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 Vsync
]
set_property C_CLK_INPUT_FREQ_HZ 3000000 00 [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]

Once completed, the application can be built and the XSA exported.

Resource usage

software development

Software development is simple, and the generated HLS IP core comes with drivers for SW development.

The software application must do the following

Initialize XADC

Initialize TPG

Initialize mixer

Initialize video timing controller

Initialize HLS IP

Set up the mixer to mix two 640 x 480 streams

Set TPG to output desired background color

Set up video timing controller for 640 x 480 timing

Loop to read XADC and update

The application code is as follows

#include

When output, this provides a nice color display, as is the base range of a VGA display.

Alternatively, we can create a simple project to show how to draw points on the VGA output.

Future improvement directions may be as follows:

Add labels and tags

Added cursor to report sample values ​​on screen

Line drawing between points

Of course, we need to pay attention to the required logical resources, as this project has high requirements on device resources.

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号