0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何使用Basys3板創(chuàng)建一個簡單的示波器

科技觀察員 ? 來源:亞當泰勒 ? 作者:亞當泰勒 ? 2022-05-03 16:38 ? 次閱讀

該項目將大家一起使用Basys3板創(chuàng)建一個簡單的示波器,花費時間約4小時。

poYBAGJdI2iAKDguAAcin69u3xA570.png

硬件組件

Digilent Basys 3

軟件應用程序和在線服務

Xilinx Vivado 設計套件

Xilinx Vitis 統(tǒng)一軟件平臺

項目介紹

Digilent Basys3 板是一款功能強大的板,可用于開始開發(fā) FPGA 項目。它為用戶提供了一個 Artix 35T 設備、USB-UART、四個 Pmod——包括一個為 XADC 配置的 Pmod、12 位 VGA 和開關、LED 和七段顯示器。

該項目旨在演示 Basys3 板的功能,為此我們將創(chuàng)建一個簡單的示波器,它可以使用 XDAC Pmod 輸入通道和 VGA 顯示器來顯示波形。

為此,我們將使用 MicroBlaze 控制器來運行應用程序并控制 XADC 的測量,并確定在 VGA 屏幕上繪制數據的位置。

VGA 顯示器將是 640 x 480,12 位 RGB 在軟件內存中渲染需要 3、686、400 位。這超過了 FPGA 中可用的 1、800、000 位 BRAM。處理器也無法以能夠達到所需幀速率所需的速度運行。

我們將通過使用處理器來確定數據點圖來解決這個問題,同時邏輯渲染幀以實時顯示。為此,我們將使用我們首先創(chuàng)建的高級綜合核心。

高級綜合核心
開始時要重新創(chuàng)建一個 HLS 核心,它可以在 VGA 顯示器中繪制多達 10 個樣本(當然,您可以稍后更改)。HLS 內核將生成一個 640 像素 x 480 行的 AXI 流。為了更新每一幀的顯示,將有定義樣本數據位置的 sample_x / _y 寄存器、定義數據點大小的寄存器和定義數據點顏色的最終寄存器。

創(chuàng)建 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);
}
}
}

請注意我如何使用兩個循環(huán)在流中創(chuàng)建圖像的 X 和 Y 元素。在內部循環(huán)中,我們處理 TUser 和 TLast 信號上的幀開始和行尾邊帶信號。

下一步是使用 C 來模擬電路,以確保行為符合我們的要求

創(chuàng)建的測試臺可用于 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板創(chuàng)建的新項目中。

MicroBlaze-64KB數據和指令存儲器

AXILiteUART

視頻時序控制器-僅配置為生成

視頻測試模式生成器-最大行數和列數800、800

XADC-啟用Vaux6、7、14和15

時鐘向導-20MHz(MicroBlaze)、25.175MHz(像素時鐘)、50MHz(邏輯時鐘)

視頻混合器-最大行數和列數800、800

視頻軸到視頻輸出

之前在HLS中創(chuàng)建的HUDIP

GPIO連接到按鈕-光標的未來擴展

創(chuàng)建框圖時,利用塊自動化來配置MicroBlaze-添加內存、調試和休息結構。還利用連接自動化來連接AXI互連。

顯示界面視圖時,端圖將類似于下圖。

poYBAGJdI1GAVmPpAAEZYDdv6Mo922.png

完整的設計如下

pYYBAGJdI02AKvbpAAHdhaTyZRM086.png

我會將完整的設計放在我的github上進行探索和修改。

圖像路徑將先前創(chuàng)建的HLSIP與TPG合并(允許設置背景顏色)。這些使用視頻混合器核心合并,該核心使用alpha混合合并兩個流。

pYYBAGJdI0mAJ9WuAAIe9mgelyI566.png

生成的輸出流被轉換回并行視頻輸出格式Pixel、VSync、HSync等,為640、480顯示器定時。AXIStream到視頻的時序由視頻時序發(fā)生器控制。

在這種方法中,軟件應用程序可以使用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

軟件開發(fā)

軟件的開發(fā)很簡單,生成的 HLS IP 內核帶有用于 SW 開發(fā)的驅動程序。

軟件應用程序必須執(zhí)行以下操作

初始化 XADC

初始化 TPG

初始化混音器

初始化視頻時序控制器

初始化 HLS IP

設置混合器以混合兩個 640 x 480 流

設置 TPG 以輸出所需的背景顏色

為 640 x 480 時序設置視頻時序控制器

循環(huán)讀取 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

另外,我們可以創(chuàng)建一個簡單的項目來展示如何在VGA輸出上繪制點。

未來的改進方向可能如下:

添加標簽和標記

添加光標以在屏幕上報告樣本值

點之間的線繪制

當然,我們需要注意所需的邏輯資源,因為這個項目對設備資源的要求很高。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯系本站處理。 舉報投訴
  • FPGA
    +關注

    關注

    1620

    文章

    21510

    瀏覽量

    598908
收藏 人收藏

    評論

    相關推薦

    xilinx的basys3板子的4位7段數碼管4數字中間有兩點

    xilinx的basys3板子的4位7段數碼管4數字中間有兩點,請問這個管腳是什么。
    發(fā)表于 04-13 12:51

    初學請教:nesys3basys3學習選擇

    本人初學FPGA,想入手塊二手板子??吹骄W上有賣nesys3basys3板子,看到用nesys3的人比較多,basys3板子資源比nes
    發(fā)表于 08-02 08:20

    出手塊全新的FPGA開發(fā) Xilinx Basys 3 原裝未拆過

    本帖最后由 FPGA愛好者_001 于 2017-9-10 20:04 編輯 我在閑魚賣·全新 FPGA學習開發(fā) Basys3 原裝#來閑魚,發(fā)現更多閑置超值好物#ht去掉tp://a.p6去掉ff.com/F.XMRXL
    發(fā)表于 09-10 20:02

    基于FPGA vivado 17.2 Basys3 示波器實驗設計

    的基本組成結構二、實驗原理介紹數字存儲示波器能夠將模擬信號進行采樣、存儲以及顯示。本系統(tǒng)在DIGILENT Basys3上構建了簡易數字存儲示波
    發(fā)表于 12-22 20:28

    basys3電子鐘的代碼,包括校時和鬧鐘功能,拜托各位大神了~~~~

    basys3電子鐘的代碼,包括校時和鬧鐘功能,拜托各位大神了~~~~
    發(fā)表于 04-08 16:16

    Basys3 時鐘上升沿很長,是什么原因?

    大家好,我在用 Basys3一個簡單的電路時,發(fā)現問題。程序代碼:module Pmod_Top( input clk, outpu
    發(fā)表于 04-12 10:50

    緊急求助 basys3的板子怎么實現用u***-a接口的通信

    正在做一個計算機設計的課設 要求用verilog和匯編設計mips現在匯編和mips都已經寫好了 但是要求要用xlinx的basys3 這塊板子的USB-A接口接USB鍵盤完成輸入
    發(fā)表于 07-07 11:39

    有沒有用basys3的攝像頭圖像顯示

    現在手上有basys3,ov7670攝像頭無fifo,還有iic模塊應該是好了,之后改如何操作,是否為建立bram,但向bram里面?zhèn)鬏敂祿牡刂窙]法確定希望大家給簡明點的主意
    發(fā)表于 05-26 14:14

    基于 FPGA Vivado 示波器設計(附源工程)

    工程代碼,可在公眾號內回復“示波器設計源工程”。 原理介紹 數字存儲示波器能夠將模擬信號進行采樣、存儲以及顯示。本系統(tǒng)在DIGILENT Basys3上構建了
    發(fā)表于 08-17 19:31

    基于Vivado 的Basys3開發(fā)的解碼教程

    基于Vivado 的Basys3開發(fā)的解碼教程
    發(fā)表于 08-03 19:37 ?66次下載

    Basys3開發(fā)板實現示波器設計

    、目的 1)掌握基于v文件的vivado工程設計流程 2)學習示波器的基本組成結構 二、原理介紹 數字存儲示波器能夠將模擬信號進行采樣、存儲以及顯示。本系統(tǒng)在Basys3上構建了
    發(fā)表于 02-08 14:53 ?1204次閱讀
    <b class='flag-5'>Basys3</b>開發(fā)板實現<b class='flag-5'>示波器</b>設計

    Basys3開發(fā)的MicroBlaze串口實驗

    microblaze基本結構 3.實現microblaze調用uart模塊,完成串口打印功能。 實驗原理:本系統(tǒng)中,Basys3的Microblaze模塊調用基于AXI協(xié)議的uart IP核,通過
    發(fā)表于 02-08 15:05 ?931次閱讀
    <b class='flag-5'>Basys3</b>開發(fā)<b class='flag-5'>板</b>的MicroBlaze串口實驗

    創(chuàng)建工程項目并使用三種方法下載工程項目到Basys3 FPGA開發(fā)上教程

    舊版Vivado均可使用,但是步驟可能有些許不同 源文件 . basys3_sw_demo.zip 教程 1. 創(chuàng)建工程項目 首先,我們要創(chuàng)建
    發(fā)表于 11-15 14:10 ?1w次閱讀
    <b class='flag-5'>創(chuàng)建</b>工程項目并使用三種方法下載工程項目到<b class='flag-5'>Basys3</b> FPGA開發(fā)<b class='flag-5'>板</b>上教程

    用于Basys3的VHDL中的UART接口

    電子發(fā)燒友網站提供《用于Basys3的VHDL中的UART接口.zip》資料免費下載
    發(fā)表于 11-22 09:50 ?2次下載
    用于<b class='flag-5'>Basys3</b><b class='flag-5'>板</b>的VHDL中的UART接口

    verilog設計之基于basys3實現的簡易分秒數字鐘

    基于basys3實現的簡易分秒數字鐘
    發(fā)表于 09-03 14:15 ?0次下載