目录

一、VGA介绍

(一) VGA协议

(二) VGA端口介绍

(三) 色彩原理

(四)VGA显示原理

VGA通信协议:

VGA时序解析

时钟分频

二、实现

​1.彩条显示

2.字符显示

3.图片显示

三、代码

1.vga驱动模块

2.显示数据生成模块

3.按键消抖模块

4.顶层模块

四、效果

RTL视图

顶层​编辑

vga_drive​编辑

data_drive

视频

​五 、参考

一、VGA介绍

(一) VGA协议

什么是VGA?VGA不是用来显示的那块屏幕,而是用来传输信号的接口。VGA全称是Video Graphics Array,即视频图形阵列,是模拟信号的一种视频传输标准。不⽀持热插拔,不⽀持⾳频传输。对于⼀些嵌⼊式VGA显示系统,可以在不使⽤VGA显卡和计算机的 情况下,实现VGA图像的显示和控制。VGA显示器具有成本低、结构简单、应⽤灵活的优点。

(二) VGA端口介绍

VGA端口是视频输出端口,端口一共包含15个管脚,如下图

VGA接口是一种D型接口,上面共有15针孔,分成三排,每排五个。 其中,除了2根NC(Not Connect)信号、3根显示数据总线和5个GND信号,比较重要的是3根RGB彩色分量信号和2根扫描同步信号HSYNC和VSYNC针。VGA接口中彩色分量采用RS343电平标准。RS343电平标准的峰值电压为1V。VGA接口是显卡上应用最为广泛的接口类型,多数的显卡都带有此种接口。有些不带VGA接口而带有DVI(Digital Visual Interface数字视频接口)接口的显卡,也可以通过一个简单的转接头将DVI接口转成VGA接口,通常没有VGA接口的显卡会附赠这样的转接头。

在通常使用的连接方法里面,15个管脚里面的5个是最重要的,他们包括3个基本红、绿、蓝三条基本色彩和水平与垂直两条控制线。

大多数计算机与外部显示设备之间都是通过模拟VGA接口连接,计算机内部以数字方式生成的显示图像信息,被显卡中的数字/模拟转换器转变为R、G、B三原色信号和行、场同步信号,信号通过电缆传输到显示设备中。对于模拟显示设备,如模拟CRT显示器,信号被直接送到相应的处理电路,驱动控制显像管生成图像。而对于LCD、DLP等数字显示设备,显示设备中需配置相应的A/D(模拟/数字)转换器,将模拟信号转变为数字信号。在经过D/A和A/D两次转换后,不可避免地造成了一些图像细节的损失。VGA接口应用于CRT显示器无可厚非,但用于连接液晶之类的显示设备,则转换过程的图像损失会使显示效果略微下降。
而且可以从接口处来判断显卡是独显还是集成显卡,VGA接口竖置的说明是集成显卡,VGA接口横置说明是独立显卡(一般的台式主机都可以用此方法来查看)。

(三) 色彩原理

三基⾊是指通过其他颜⾊的混合⽆法得到的“基本 ⾊”由于⼈的⾁眼有感知红、绿、蓝三种不同颜⾊的锥体细胞,因此⾊彩空间通常可以由三种基本⾊来表达

设计RGB信号时,既可以R信号、G信号和B信号独⽴的赋值,最后连到端⼝上,也可以直接⽤RGB当做⼀个整体信号,RGB信号在使⽤时的位宽有三种常见格式,以你的VGA解码芯⽚的配置有关。

  1. RGB_8,R:G:B = 3:3:2,即RGB332
  2. RGB_16,R:G:B = 5:6:5,即RGB565
  3. RGB_24,R:G:B = 8:8:8,即RGB888

依次对应8、16、24位位宽,位宽越高,图像越清晰

(四)VGA显示原理

VGA通过引脚的模拟电压(0V-0.714V)显示红绿蓝三种颜色,不同的电压值对应不同的颜色。
VGA驱动显示器用的是扫描的方式,一般是逐行扫描。
逐行扫描是扫描从屏幕左上角一点开始,从左像右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT对电子束进行消隐,每行结束时,用行同步信号进行同步;
当扫描完所有的行,形成一帧后,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。
FPGA芯片驱动VGA显示,需要先产生模拟信号,这就要借助数模转换器D/A,利用D/A产生模拟信号,输出至VGA的RED、GREEN、BLUE基色数据线。另一种方法是利用电阻网络分流模拟D/A实现的。
具体颜色对应的电压值:

利用电阻网络分流模拟D/A:

参考:https://blog.csdn.net/qq_40147893/article/details/108342484

VGA通信协议:

VS:帧时序

帧时序的四个部分别是:同步脉冲(Sync o)、显示后沿(Back porch p)、显示时序段(Display interval q)和显示前沿(Front porchr)。其中同步脉冲(Sync o)、显示后沿(Back porch p)和显示前沿(Front porch r)是消隐区,RGB信号无效,屏幕不显示数据。显示时序段(Display interval q)是有效数据区。

HS:行时序

行时序的四个部分分别是:同步脉冲(Sync a)、显示后沿(Back porch b)、显示时序(Display interval c)和显示前沿(Front porchd)。其中同步脉冲(Sync a)、显示后沿(Back porch b)和显示前沿(Front porch d)是消隐区,RGB信号无效,屏幕不显示数据。显示时序段(Display interval c)是有效数据区。

VGA时序解析

不同分辨率对应参数

时钟分频

举例:分别使用640×480 60HZ和800×600 72HZ,对应时钟分别为25M和50M,需要使用PLL进行分频 时钟频率 = 行帧长 × 列帧长 * 刷新率,640 ×480 60HZ对应时钟频率= 800 ×525 × 60 = 25.2M,1040x666x72=49.9M

二、实现

IP核里面找到ALTPLL

基础时钟选择50M

 取消勾选输出使能

c0默认输出50M即可,c1分频到25M,如需其他时钟频率可以自己进行设置

 勾选如下选项后finish

 1.彩条显示

根据当前行地址判断需要显示的颜色即可。

2.字符显示

在子模提取工具里面输入需要显示的字符并设置字符大小为64*64,点阵大小为64*64

然后点击文件-另存为,把图片保存为BMP图片

再点击文件-打开,把保存的BMP图片打开得到整体的字符

再点击选项按如下参数设置

最后点击生成字符并保存字符为文本文件

最后得到字符如下

把得到的字符在verilog里面使用即可

注意:char_line[0]这一行全赋值为0,也就是说增加了第一行0,其余不变

之所以要转变成BMP图片格式,是因为否则生成的都是单个字模,位数会不统一,为了位数长度统一,代码中384=64*6,也就是一个字符宽度64,因为显示6个字符,因此位宽384

3.图片显示

原图:

使用工具BMP2MifV1.0把图片转为HEX文件

在转换图片之前需要先修改图片的格式,使用电脑自带的画图软件打开此图片

点击重新调整大小

点击文件-另存为

注意:保存类型一定要选择为24位位图(*.bmp;*.dib),否则加载不成功

然后开始转换

选择输出图像格式RGB565   文件类型Hex

转换完成得到dongman.hex,内容如图

由于图片数据太多需要使用ROM来存储数据

设置位宽度为16位,大小为图片大小128×78 = 9984

取消勾选下列选项

找到刚才生成的dongman.hex文件

勾选以下选项后直接finsh即可

数据的读取和使用参考后面的代码部分

三、代码

基于EP4CE6F17C8型号芯片

1.vga驱动模块

module vga_dirve (input          wire                        clk,            //系统时钟input         wire                        rst_n,          //复位input           wire        [ 15:0 ]        rgb_data,       //16位RGB对应值output           wire                            vga_clk,    //vga时钟 25Moutput           reg                         h_sync,     //行同步信号output           reg                         v_sync,     //场同步信号output           reg     [ 11:0 ]                addr_h, //行地址output         reg     [ 11:0 ]                addr_v,  //列地址output            wire        [ 4:0 ]             rgb_r,  //红基色output         wire        [ 5:0 ]             rgb_g,  //绿基色output         wire        [ 4:0 ]             rgb_b  //蓝基色
);// 640 * 480 60HZ
localparam   H_FRONT = 16; // 行同步前沿信号周期长
localparam   H_SYNC  = 96; // 行同步信号周期长
localparam   H_BLACK = 48; // 行同步后沿信号周期长
localparam   H_ACT   = 640; // 行显示周期长
localparam   V_FRONT = 11; // 场同步前沿信号周期长
localparam   V_SYNC  = 2; // 场同步信号周期长
localparam   V_BLACK = 31; // 场同步后沿信号周期长
localparam   V_ACT   = 480; // 场显示周期长// 800 * 600 72HZ
// localparam    H_FRONT = 40; // 行同步前沿信号周期长
// localparam    H_SYNC  = 120; // 行同步信号周期长
// localparam    H_BLACK = 88; // 行同步后沿信号周期长
// localparam    H_ACT   = 800; // 行显示周期长
// localparam    V_FRONT = 37; // 场同步前沿信号周期长
// localparam    V_SYNC  = 6; // 场同步信号周期长
// localparam    V_BLACK = 23; // 场同步后沿信号周期长
// localparam    V_ACT   = 600; // 场显示周期长localparam    H_TOTAL = H_FRONT + H_SYNC + H_BLACK + H_ACT; // 行周期
localparam  V_TOTAL = V_FRONT + V_SYNC + V_BLACK + V_ACT; // 列周期reg         [ 11:0 ]            cnt_h           ; // 行计数器
reg         [ 11:0 ]            cnt_v           ; // 场计数器
reg         [ 15:0 ]            rgb         ; // 对应显示颜色值// 对应计数器开始、结束、计数信号
wire                            flag_enable_cnt_h           ;
wire                            flag_clear_cnt_h            ;
wire                            flag_enable_cnt_v           ;
wire                            flag_clear_cnt_v            ;
wire                            flag_add_cnt_v              ;
wire                            valid_area                  ;// 25M时钟 行周期*场周期*刷新率 = 800 * 525* 60
wire                            clk_25          ;
// 50M时钟 1040 * 666 * 72
wire                            clk_50          ;
//PLL
pll pll_inst (.areset ( ~rst_n ),.inclk0 ( clk ),.c0 ( clk_50 ), //50M.c1 ( clk_25 ), //25M);
//根据不同分配率选择不同频率时钟
assign vga_clk = clk_25;// 行计数
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) begincnt_h <= 0;endelse if ( flag_enable_cnt_h ) beginif ( flag_clear_cnt_h ) begincnt_h <= 0;endelse begincnt_h <= cnt_h + 1;endendelse begincnt_h <= 0;end
end
assign flag_enable_cnt_h = 1;
assign flag_clear_cnt_h  = cnt_h == H_TOTAL - 1;// 行同步信号
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginh_sync <= 0;endelse if ( cnt_h == H_SYNC - 1 ) begin // 同步周期时为1h_sync <= 1;endelse if ( flag_clear_cnt_h ) begin // 其余为0h_sync <= 0;endelse beginh_sync <= h_sync;end
end// 场计数
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) begincnt_v <= 0;endelse if ( flag_enable_cnt_v ) beginif ( flag_clear_cnt_v ) begincnt_v <= 0;endelse if ( flag_add_cnt_v ) begincnt_v <= cnt_v + 1;endelse begincnt_v <= cnt_v;endendelse begincnt_v <= 0;end
end
assign flag_enable_cnt_v = flag_enable_cnt_h;
assign flag_clear_cnt_v  = cnt_v == V_TOTAL - 1;
assign flag_add_cnt_v    = flag_clear_cnt_h;// 场同步信号
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginv_sync <= 0;endelse if ( cnt_v == V_SYNC - 1 ) beginv_sync <= 1;endelse if ( flag_clear_cnt_v ) beginv_sync <= 0;endelse beginv_sync <= v_sync;end
end// 对应有效区域行地址 1-640
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginaddr_h <= 0;endelse if ( valid_area ) beginaddr_h <= cnt_h - H_SYNC - H_BLACK + 1;endelse beginaddr_h <= 0;end
end
// 对应有效区域列地址 1-480
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginaddr_v <= 0;endelse if ( valid_area ) beginaddr_v <= cnt_v -V_SYNC - V_BLACK + 1;endelse beginaddr_v <= 0;end
end
// 有效显示区域
assign valid_area = cnt_h >= H_SYNC + H_BLACK && cnt_h <= H_SYNC + H_BLACK + H_ACT && cnt_v >= V_SYNC + V_BLACK && cnt_v <= V_SYNC + V_BLACK + V_ACT;// 显示颜色
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginrgb <= 16'h0;endelse if ( valid_area ) beginrgb <= rgb_data;endelse beginrgb <= 16'b0;end
end
assign rgb_r = rgb[ 15:11 ];
assign rgb_g = rgb[ 10:5 ];
assign rgb_b = rgb[ 4:0 ];endmodule // vga_dirve

2.显示数据生成模块

module data_drive (input         wire                        vga_clk,input           wire                        rst_n,input         wire        [ 11:0 ]        addr_h,input            wire        [ 11:0 ]        addr_v,input            wire        [ 2:0 ]      key,output         reg     [ 15:0 ]                rgb_data);localparam    red    = 16'd63488;
localparam  orange = 16'd64384;
localparam  yellow = 16'd65472;
localparam  green  = 16'd1024;
localparam  blue   = 16'd31;
localparam  indigo = 16'd18448;
localparam  purple = 16'd32784;
localparam  white  = 16'd65503;
localparam  black  = 16'd0;
reg [ 383:0 ] char_line[ 64:0 ];localparam  states_1 = 1; // 彩条
localparam  states_2 = 2; // 字符
localparam  states_3 = 3; // 图片parameter   height = 78; // 图片高度
parameter   width  = 128; // 图片宽度
reg         [ 1:0 ]         states_current          ; // 当前状态
reg         [ 1:0 ]         states_next             ; // 下个状态
reg         [ 13:0 ]        rom_address             ; // ROM地址
wire            [ 15:0 ]        rom_data                ; // 图片数据wire                           flag_enable_out1            ; // 文字有效区域
wire                            flag_enable_out2            ; // 图片有效区域
wire                            flag_clear_rom_address      ; // 地址清零
wire                            flag_begin_h                ; // 图片显示行
wire                            flag_begin_v                ; // 图片显示列//状态转移
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginstates_current <= states_1;endelse beginstates_current <= states_next;end
end//状态判断
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginstates_next <= states_1;endelse if ( key[ 0 ] ) beginstates_next <= states_1;endelse if ( key[ 1 ] ) beginstates_next <= states_2;endelse if ( key[ 2 ] ) beginstates_next <= states_3;endelse beginstates_next <= states_next;end
end//状态输出
always @( * ) begincase ( states_current )states_1 : beginif ( addr_h == 0 ) beginrgb_data = black;endelse if ( addr_h >0 && addr_h <81 ) beginrgb_data = red;endelse if ( addr_h >80 && addr_h <161 ) beginrgb_data = orange;endelse if ( addr_h >160 && addr_h <241 ) beginrgb_data = yellow;endelse if ( addr_h >240 && addr_h <321 ) beginrgb_data = green;endelse if ( addr_h >320 && addr_h <401 ) beginrgb_data = blue;endelse if ( addr_h >400 && addr_h <481 ) beginrgb_data = indigo;endelse if ( addr_h >480 && addr_h <561 ) beginrgb_data = purple;endelse if ( addr_h >560 && addr_h <641 ) beginrgb_data = white;endelse beginrgb_data = black;endendstates_2 : beginif ( flag_enable_out1 ) beginrgb_data = char_line[ addr_v-208 ][ 532 - addr_h ]? white:black;endelse beginrgb_data = black;endendstates_3 : beginif ( flag_enable_out2 ) beginrgb_data = rom_data;endelse beginrgb_data = black;endenddefault: begincase ( addr_h )0 : rgb_data      = black;1 : rgb_data      = red;81 : rgb_data     = orange;161: rgb_data     = yellow;241: rgb_data     = green;321: rgb_data     = blue;401: rgb_data     = indigo;481: rgb_data     = purple;561: rgb_data     = white;default: rgb_data = rgb_data;endcaseendendcase
endassign flag_enable_out1 = states_current == states_2 && addr_h > 148 && addr_h < 533 && addr_v > 208  && addr_v < 273 ;
assign flag_begin_h     = addr_h > ( ( 640 - width ) / 2 ) && addr_h < ( ( 640 - width ) / 2 ) + width + 1;
assign flag_begin_v     = addr_v > ( ( 480 - height )/2 ) && addr_v <( ( 480 - height )/2 ) + height + 1;
assign flag_enable_out2 = states_current == states_3 && flag_begin_h && flag_begin_v;//ROM地址计数器
always @( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginrom_address <= 0;endelse if ( flag_clear_rom_address ) begin //计数满清零rom_address <= 0;endelse if ( flag_enable_out2 ) begin  //在有效区域内+1rom_address <= rom_address + 1;endelse begin  //无效区域保持rom_address <= rom_address;end
end
assign flag_clear_rom_address = rom_address == height * width - 1;//初始化显示文字
always@( posedge vga_clk or negedge rst_n ) beginif ( !rst_n ) beginchar_line[ 0 ]  = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[ 1 ]  = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[ 2 ]  = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[ 3 ]  = 384'h000000000000000000000002000000000000000000000000000000300000000000000000000000000000000000000000;char_line[ 4 ]  = 384'h0000000000000000000000078000000000000800000004000000001E0000000000000000000100000000200000800000;char_line[ 5 ]  = 384'h000000000000000000000007C000000000000E00000003000000000F80000000000180000003800000003C0000E00000;char_line[ 6 ]  = 384'h000000000000000000000007E000000000000F80000003C000000007C00000000001FFFFFFFFE00000003F0000F80000;char_line[ 7 ]  = 384'h00000000000000000000000F8000000000000F00000003C000000003E00000000001FFFFFFFFE00000003E0000F00000;char_line[ 8 ]  = 384'h00000000000000000000000FC000000000000E000000038000000003E00000000001E0000003C00000003C0000E00000;char_line[ 9 ]  = 384'h00000000000008000000001F4000000000000E000000038000600001E00000000001E0000003C00000003C0000E00000;char_line[ 10 ] = 384'h0000000000001C000000001E6000000000000E000000038000600000C00002000001E0000003C00000003C0000E00000;char_line[ 11 ] = 384'h0000000000003E000000003E3000000000000E003000038000600000C00007000001E0000003C00000003C0000E00000;char_line[ 12 ] = 384'h01FFFFFFFFFFFF000000003C3800000000000E0078300380007FFFFFFFFFFF800001E0000003C00000003C0000E00000;char_line[ 13 ] = 384'h00FFFFFFFFFFFF8000000078180000000FFFFFFFFC3C0380007FFFFFFFFFFFC00001FFFFFFFFC00000003C0000E00000;char_line[ 14 ] = 384'h0060000000000000000000F80C00000007FFFFFFFE3E038000E0000000000FE00001FFFFFFFFC00000803C0000E00000;char_line[ 15 ] = 384'h0000000000000000000000F00E00000000000E00003E038000E0018000000F800001E0000003C00000E03C0000E00000;char_line[ 16 ] = 384'h0000000000000000000001E00700000000000E00003C038001E001C000001E000001E0000003C00000F83C0000E00400;char_line[ 17 ] = 384'h0000000000000000000003E00380000000000E00003C038003E001F000001C000001E0000003C00000F03C0C00E00700;char_line[ 18 ] = 384'h0000000000000000000003C003C0000000000E00003C038003E003F8000030000001E0000003C00000F03C0FFFFFFF80;char_line[ 19 ] = 384'h00000000000000000000078001E0000000000E00003C038007C007E0000060000001E0000003C00000F03C0FFFFFFF80;char_line[ 20 ] = 384'h000000000000000000000F0000F0000000000E00403C0380078007C0003040000001FFFFFFFFC00000F03C0E00E00F00;char_line[ 21 ] = 384'h000000000000000000001E000078000000400E00603C038000000FFFFFF800000001FFFFFFFFC00000F03C0E00E00F00;char_line[ 22 ] = 384'h000000000000000000003E02003E0000007FFFFFF03C038000000FFFFFFC00000001E0000003C00000F03C0E00E00F00;char_line[ 23 ] = 384'h000000000000000000007C03801F0000007FFFFFF83C038000001F00007E00000001E0000003800000F03C0E00E00F00;char_line[ 24 ] = 384'h00000000000000000000F803E01FC00000700E00F03C038000003C8000F000000001C0000002030000F03C0E00E00F00;char_line[ 25 ] = 384'h00000000000000000001E003E007E00000700E00E03C0380000078C001E00000000000000000078000F03C0E00E00F00;char_line[ 26 ] = 384'h00000000000000000003C003C003F80000700E00E03C03800000706003C000000000000000000FC000F03C0E00E00F00;char_line[ 27 ] = 384'h000000000000000000078003C001FF0000700E00E03C03800000E030078000001FFFFFFFFFFFFFE000F03C0E00E00F00;char_line[ 28 ] = 384'h0000000000000000000F0003C000FFE000700E00E03C03800001C0180F0000000FFFFFFFFFFFFFF000F03C0E00E00F00;char_line[ 29 ] = 384'h0000000000000000001C0003C0007FF800700E00E03C03800003800C1E000000000F001E0000000000F03C0E00E00F00;char_line[ 30 ] = 384'h000000000001000000780003C0001FE000700E00E03C03800007000F3C000000000F001E0000000000F0380E00E00F00;char_line[ 31 ] = 384'h000000000003800000E00003C0000F8000700E00E03C0380000E0007F8000000000F001E0000080000F0380E00E00F00;char_line[ 32 ] = 384'h000000000007C00003800003C000030000700E00E03C0380001C0003F0000000000F001E00000C0000F0380E00E00F00;char_line[ 33 ] = 384'h001FFFFFFFFFE0000E000003C000000000700E00E03C038000300001F0000000000F001FFFFFFF0000F0380E00E00F00;char_line[ 34 ] = 384'h000FFFFFFFFFF00038000003C000000000700E00E03C038000600007FC000000000FFFFEFFFFFF8000F0380E00E00F00;char_line[ 35 ] = 384'h000600000000000000000003C000000000700E00E03C03800080000FBF000000000FFFFE44001E0000F0380E00E00F00;char_line[ 36 ] = 384'h000000000000000000000003C000000000700E00E03C03800000003E0FC00000000F001E04003C0000F0380E00E00F00;char_line[ 37 ] = 384'h000000000000000000000003C000000000701E7FE03C03800000007C03F80000000F001E06003C0000F0380E00E00F00;char_line[ 38 ] = 384'h000000000000000000000003C000000000703E0FE03C0380000001F001FF0000000F001E0200380000F0780E00E00F00;char_line[ 39 ] = 384'h000000000000000000000003C000000000703E07C03C0380000007C0007FF800000F001E0300780000F0780E00E00F00;char_line[ 40 ] = 384'h000000000000000000000003C000000000607F03803C038000001F00001FFFF8000F001E0300700000F0700E00E00F00;char_line[ 41 ] = 384'h000000000000000000000003C000000000007F82003C038000007C000007FFF0000FFFFE0180F00000F0700E00E00F00;char_line[ 42 ] = 384'h000000000000000000000003C00000000000FEE0003C03800001F000000EFFC0000FFFFE0180E00000F0700E00E00F00;char_line[ 43 ] = 384'h000000000000000000000003C00000000001EE38003C0380000FFFFFFFFF1F80000F001E01C1E00000C0F00E00E00F00;char_line[ 44 ] = 384'h000000000000000000000003C00000000003CE1E003C0380007E7FFFFFFF8300000F001E00C1C0000000E00E00E00F00;char_line[ 45 ] = 384'h000000000000000000000003C000000000038E0F003C038003E07800000F0000000F001E00E3C0000000E00E00E00F00;char_line[ 46 ] = 384'h000000000000000000000003C000000000070E07C03C03801E007800000E0000000F001E006780000001E00E00E7FF00;char_line[ 47 ] = 384'h000000000000000000000003C0000000000E0E03E03C038000007800000E0000000F001E1C7700000001C00E00E1FE00;char_line[ 48 ] = 384'h000000000000000000000003C0000000001C0E01F03C038000007800000E0000000F001FF03F00000001C00E00E07E00;char_line[ 49 ] = 384'h000000000000000000000003C000000000380E00F830038000007800000E0000000F00FF803E00000003800C00E03C00;char_line[ 50 ] = 384'h000000000000000000000003C000000000700E007800038000007800000E0000000F3FFE001E00000003800800E01800;char_line[ 51 ] = 384'h000000000000018000000003C000000000E00E007800038000007800000E0000000FFFDE003F00000007000000E00000;char_line[ 52 ] = 384'h00000000000003C000000003C000000000C00E003800038000007800000E000000FFFC1E00778000000E000000E00000;char_line[ 53 ] = 384'h00000000000007E000000003C000000001800E001000038000007800000E00000FFFC01E00E3C000000E000000E00000;char_line[ 54 ] = 384'h3FFFFFFFFFFFFFF000000003C000000003000E000000038000007800000E000007FE001E01C3F000001C000000E00000;char_line[ 55 ] = 384'h1FFFFFFFFFFFFFF800000003C00000000E000E000000038000007800000E000007E0001E0380FC000038000000E00000;char_line[ 56 ] = 384'h0C0000000000000000000003C000000018000E00000FCF8000007FFFFFFE00000380001E07007F000070000000E00000;char_line[ 57 ] = 384'h000000000000000000000003C000000030000E000007FF8000007FFFFFFE00000200001E0E003FF800E0000000E00000;char_line[ 58 ] = 384'h000000000000000000000003C000000000000E000001FF8000007800000E00000000001E18001FE001C0000000E00000;char_line[ 59 ] = 384'h000000000000000000000003C000000000000E0000007F0000007800000E00000000001E700007800300000000E00000;char_line[ 60 ] = 384'h000000000000000000000003C000000000000E0000001E0000007000000C00000000001EC00003000600000000E00000;char_line[ 61 ] = 384'h0000000000000000000000030000000000000E0000000C0000004000000000000000001F800000000800000000E00000;char_line[ 62 ] = 384'h000000000000000000000002000000000000080000000000000000000000000000000010000000000000000000800000;char_line[ 63 ] = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;char_line[ 64 ] = 384'h000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;end
end//实例化ROM
ROM1_port   ROM1_port_inst (
.address ( rom_address ),
.clock ( vga_clk ),
.q ( rom_data )
);
endmodule // data_drive

3.按键消抖模块

module key_debounce(input    wire    clk,input   wire    rst_n,input     wire    key,output  reg     flag,// 0抖动, 1抖动结束output    reg key_value//key抖动结束后的值
);parameter MAX_NUM = 20'd1_000_000;reg [19:0] delay_cnt;//1_000_000reg key_reg;//key上一次的值always @(posedge clk or negedge rst_n) beginif(!rst_n) beginkey_reg <= 1;delay_cnt <= 0;endelse beginkey_reg <= key;//当key为1 key 为0 表示按下抖动,开始计时if(key_reg  != key  ) begin delay_cnt <= MAX_NUM ;endelse beginif(delay_cnt > 0)delay_cnt <= delay_cnt -1;elsedelay_cnt <= 0;endend
end//当计时完成,获取key的值
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginflag <= 0;key_value <= 1;endelse begin// 计时完成 处于稳定状态,进行赋值if(delay_cnt == 1) beginflag <= 1;key_value <= key;endelse beginflag <= 0;key_value <= key_value;endend
endendmodule

4.顶层模块

module vga_top (input            wire                        clk,input           wire                        rst_n,input         wire        [ 2:0 ]         key,output          wire                        vga_clk,output          wire                        h_sync,output           wire                        v_sync,output           wire        [ 4:0 ]         rgb_r,output            wire        [ 5:0 ]         rgb_g,output            wire        [ 4:0 ]         rgb_b,output            reg         [ 3:0 ]         led);reg            [ 27:0 ]            cnt                 ;
wire        [ 11:0 ]            addr_h              ;
wire        [ 11:0 ]            addr_v              ;
wire        [ 15:0 ]            rgb_data            ;
wire        [ 2:0 ]             key_flag            ;
wire        [ 2:0 ]             key_value           ;//vga模块
vga_dirve u_vga_dirve(
.clk      ( clk ),
.rst_n    ( rst_n ),
.rgb_data ( rgb_data ),
.vga_clk  ( vga_clk ),
.h_sync   ( h_sync ),
.v_sync   ( v_sync ),
.rgb_r    ( rgb_r ),
.rgb_g    ( rgb_g ),
.rgb_b    ( rgb_b ),
.addr_h   ( addr_h ),
.addr_v   ( addr_v )
);//数据模块
data_drive u_data_drive(
.vga_clk ( vga_clk ),
.rst_n   ( rst_n ),
.addr_h  ( addr_h ),
.addr_v  ( addr_v ),
.key     ( {key_value[ 2 ] && key_flag[ 2 ], key_value[ 1 ] && key_flag[ 1 ], key_value[ 0 ] && key_flag[ 0 ] } ),
.rgb_data  ( rgb_data )
);//按键消抖
key_debounce u_key_debounce0(
.clk   ( vga_clk ),
.rst_n ( rst_n ),
.key   ( key[ 0 ] ),
.flag  ( key_flag[ 0 ] ),
.key_value  ( key_value[ 0 ] )
);key_debounce u_key_debounce1(
.clk   ( vga_clk ),
.rst_n ( rst_n ),
.key   ( key[ 1 ] ),
.flag  ( key_flag[ 1 ] ),
.key_value  ( key_value[ 1 ] )
);key_debounce u_key_debounce2(
.clk   ( vga_clk ),
.rst_n ( rst_n ),
.key   ( key[ 2 ] ),
.flag  ( key_flag[ 2 ] ),
.key_value  ( key_value[ 2 ] )
);// led
always @( posedge clk or negedge rst_n ) beginif ( !rst_n ) begincnt <= 0;endelse if ( cnt == 50_000_000 - 1 ) begincnt <= 0;endelse begincnt <= cnt + 1;end
end
always @( posedge clk or negedge rst_n ) beginif ( !rst_n ) beginled <= 4'b0000;endelse if ( cnt == 50_000_000 -1 )beginled <= ~led;endelse beginled <= led;end
end
endmodule // vga_top

四、效果

通过按键切换状态,根据不同状态分别输出彩条、字符、图片。

RTL视图

顶层

vga_drive

data_drive

视频

640 ×480分辨率下拍摄     点击下方链接可观看

https://live.csdn.net/v/230012

截图如下

五 、参考

https://blog.csdn.net/qq_47281915/article/details/125134764

基于FPGA的VGA显示彩条、字符、图片相关推荐

  1. 基于FPGA的VGA显示对贪吃蛇游戏的设计

    基于FPGA的VGA显示对贪吃蛇游戏的设计 摘要 目前,电子数码产品已经进入了人生活的方方面面,而大多数电子产品都依靠显示屏来传递信息,由此可见用电路对显示屏进行控制的研究有很大的实用价值和市场需求. ...

  2. VGA显示彩条和图片(FPGA)

    如愿 一.VGA协议 二.使用设备 三.模块设计 四.代码 五.总结 一.VGA协议 VGA(Video Graphics Array)视频图形阵列是 IBM 于1987年提出的一个使用模拟信号的电脑 ...

  3. 基于FPGA的VGA显示设计(一)

    前言 FPGA主要运用于芯片验证.通信.图像处理.显示VGA接口的显示器是最基本的要求了. 原理 首先需要了解 : (1)VGA接口协议:VGA端子_维基百科 .VGA视频传输标准_百度 引脚1 RE ...

  4. 基于FPGA的VGA显示

    目录 VGA原理 代码 VGA原理 VGA概念 什么是VGA?VGA不是用来显示的那块屏幕,而是用来传输信号的接口.VGA全称是Video Graphics Array,即视频图形阵列,是模拟信号的一 ...

  5. 基于FPGA的VGA显示实验

    VGA驱动原理 信号线 定义 HS 行同步信号(3.3V 电平) VS 场同步信号(3.3V 电平) R 红基色 (0~0.714V 模拟信号) G 绿基色 (0~0.714V 模拟信号) B 蓝基色 ...

  6. 基于FPGA的VGA显示图片

    一.显示一张彩色图片 设计需求: 在VGA接口的显示屏上显示一张180*120彩色图片. 需求分析 (1)对图片裁剪及取数据 a.使用画图软件/美图秀秀将图片像素裁剪成180*120大小. b.取数据 ...

  7. FPGA学习——VGA显示

    FPGA学习--VGA显示 一.VGA原理 (一)VGA协议 (二)VGA端口结构 (三)⾊彩原理 (四)扫描原理 1.扫描方式 2.逐行扫描 3.隔行扫描 (五)⾏场信号 二.显示姓名学号 (一)实 ...

  8. imut FPGA课设 基于FPGA的VGA弹球游戏设计 *秋昊

    写在前面的话: 本文主要呈现了一篇IMUT的FPGA课设报告. 课设报告内容(word版),视频演示,程序源码,专业创新实践简介,专业创新实践指导书均已放入下面的百度云链接中,也不大,总共不到20MB ...

  9. 【FPGA】VGA显示文字、彩条、图片——基于DE2-115

    录 一.VGA概述 1.1 简述 1.2 管脚定义 1.3 行.场时序及分辨率 二.VGA显示文字 2.1 点阵汉字生成 2.2 工程建立 2.3 引入ip核-实现特定时钟频率+不同分辨率显示 2.3 ...

最新文章

  1. eclipse--各类型版本包含插件比较
  2. Linux 升级 Python 至 3.x
  3. Hadoop 详细配置文档
  4. Google的价值观
  5. OpenGL绘制Triangle三角形
  6. JSONObject和JSONArray的关系
  7. java实现简易聊天窗口先运行服务器还是客户端_一个简易聊天功能的服务器端和客户端源码...
  8. 【转】POSIX 是什么?让我们听听 Richard Stallman 的诠释 | Linux 中国
  9. vue项目中出现cannot get/的解决办法
  10. [Android] 环境配置之正式版Android Studio 1.0
  11. 招投标系统简介 招投标系统源码 java招投标系统 spring cloud spring boot 招投标系统功能设计
  12. qqmail的文件中转站可真好用啊
  13. 推荐5款免费网盘,空间大不限速!
  14. 阿里云对象存储OSS使用
  15. 几何公差学习笔记(二)-- 公差带的定义、标注和解释
  16. html 的smap标签,SMap.Label
  17. 维修技术论坛万能预装系统 v5.0
  18. IDEA修改Git仓库远端地址,处理服务器ip发生变化的情况
  19. Hive远程连接设置用户名和密码
  20. 作家助手macos_我们正在寻找一般兴趣作家

热门文章

  1. [附源码]Python计算机毕业设计儿童成长记录与分享系统Django(程序+LW)
  2. 如何深入学习Django?
  3. 话剧的一般内容及一份话剧台词
  4. 计算机学校教育中的应用,计算机在学校教育的应用与创举研究
  5. java 雪花算法生成ID
  6. 《MATLAB智能算法30个案例》:第28章 支持向量机的分类——基于乳腺组织电阻抗特性的乳腺癌诊断
  7. C4D 英文界面设置为中文界面
  8. CADENAS为Autodesk云端设计软件提供零部件数据解决方案
  9. java根据ip定位地理位置
  10. 互动电影游戏-H5互动游戏方桉之品牌营销