当前位置: 首页 > news >正文

本地集团网站建设如何进入网站

本地集团网站建设,如何进入网站,wordpress如何重置,岳阳seo文章目录 前言一、VGA接口定义与传输原理1、VGA接口定义2、传输原理3、不同分辨率对应不同参数 二、Verilog编程1、VGA显示彩色条纹2、VGA显示字符3、输出一幅彩色图像4、Quartus操作1、添加PLL核2、添加ROM核 三、全部代码四、总结五、参考资料 前言 VGA的全称是Video Graphi…

文章目录

  • 前言
  • 一、VGA接口定义与传输原理
    • 1、VGA接口定义
    • 2、传输原理
    • 3、不同分辨率对应不同参数
  • 二、Verilog编程
    • 1、VGA显示彩色条纹
    • 2、VGA显示字符
    • 3、输出一幅彩色图像
    • 4、Quartus操作
      • 1、添加PLL核
      • 2、添加ROM核
  • 三、全部代码
  • 四、总结
  • 五、参考资料


前言

VGA的全称是Video Graphics Array,即视频图形阵列,是一个使用模拟信号进行视频传输的标准。早期的
CRT显示器由于设计制造上的原因,只能接收模拟信号输入,因此计算机内部的显卡负责进行数模转换,而
VGA接口就是显卡上输出模拟信号的接口。如今液晶显示器虽然可以直接接收数字信号,但是为了兼容显卡上
的VGA接口,也大都支持VGA标准。

环境:

1、Quartus 18.1
2、EP4CE115F29C7
3、vscode


一、VGA接口定义与传输原理

1、VGA接口定义

2、传输原理

在这里插入图片描述
在这里插入图片描述

从上面两幅图中我们可以看到VGA传输过程中的行同步时序和场同步时序非常类似,一行或一场(又称一帧)数据都分为四个部分:低电平同步脉冲、显示后沿、有效数据段以及显示前沿
行同步信号HSYNC在一个行扫描周期中完成一行图像的显示,其中在a段维持一段时间的低电平用于 数据同
步,其余时间拉高;在有效数据期间(c段) ,红绿蓝三原色数据通道上输出一-行图像信号,其余时间数据无
效。与之类似,场同步信号在在一个场扫描周期中完成一 帧图像的显示, 不同的是行扫描周期的基本单位是像素点时钟,即完成一个像素点显示所需要的时间;而场扫描周期的基本单位是完成一-行图像 显示所需要的时间。

3、不同分辨率对应不同参数

在这里插入图片描述

二、Verilog编程

1)屏幕上显示彩色条纹
2)显示自定义的汉字字符(姓名-学号)
3)输出一幅彩色图像
4) 将行、场同步信号中,故意分别加入一定 ms延时(用delay命令),观察会出现什么现象。

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、VGA显示字符

  • 取字模:
    打开字模选项,选择格式:
    在这里插入图片描述
    注意,这里的学号和名字分开取:
    在这里插入图片描述
    在这里插入图片描述

注意:这里的汉字取的是16x16的点阵,数字取的是32x16的点阵。

  • 代码:
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 ]  = 256'h0000010000000000000000000000000000000000000000000000000000000000;char_line[ 1 ]  = 256'h1ff0210020000000000000000000000000000000000000000000000000000000;char_line[ 2 ]  = 256'h101011dc17fc0000000000000000000000000000000000000000000000000000;char_line[ 3 ]  = 256'h101011141040000018003c003c00180018007e001800180018003c003c000400;char_line[ 4 ]  = 256'h1ff0811480400000240042004200240024004200240024002400420042000c00;char_line[ 5 ]  = 256'h0000411440400000400042004200420042000400420040004200420042000c00;char_line[ 6 ]  = 256'h000047d448400000400002004200420042000400420040004200420042001400;char_line[ 7 ]  = 256'h3ff81014084000005c000400020042004200080042005c004200020002002400;char_line[ 8 ]  = 256'h0100111410407e00620018000400420042000800420062004200040004002400;char_line[ 9 ]  = 256'h0100211410400000420004000800420042001000420042004200080008004400;char_line[ 10 ] = 256'hfffee588e0400000420002001000420042001000420042004200100010007f00;char_line[ 11 ] = 256'h0280254820400000420042002000420042001000420042004200200020000400;char_line[ 12 ] = 256'h0440294820400000220042004200240024001000240022002400420042000400;char_line[ 13 ] = 256'h082021142ffe00001c003c007e0018001800100018001c0018007e007e001f00;char_line[ 14 ] = 256'h3018251420000000000000000000000000000000000000000000000000000000;char_line[ 15 ] = 256'hc006022200000000000000000000000000000000000000000000000000000000;end
end//实例化ROM
rom	rom_inst (
.address ( rom_address ),
.clock ( vga_clk ),
.q ( rom_data )
);
endmodule // data_drive
  • 效果:
    在这里插入图片描述

3、输出一幅彩色图像

在这里插入图片描述

  • 使用软件将图片进行转换:

在这里插入图片描述

  • 生成的hex文件:

在这里插入图片描述

这里没能成功显示

4、Quartus操作

先是新建工程引入.V文件即可,下面是添加两个IP核的操作,一个用于时钟分频,一个用于存储图片。

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

1、添加PLL核

在这里插入图片描述

  • 选择基础时钟:
    在这里插入图片描述
    取消勾选输出使能:
    在这里插入图片描述
  • 设置时钟,clk0默认50M即可,c1设为25M.
    在这里插入图片描述
  • 勾选下面的选项最后点击finish即可添加pll核
    在这里插入图片描述

2、添加ROM核

  • 搜索RO核:
    在这里插入图片描述
  • 把宽度设为16位,然后根据图片的大小填写160x154=24640,根据自己的图片来填写。
    在这里插入图片描述
  • 取消下面的勾选:
    在这里插入图片描述
  • 引入前面生成的hex文件:
    在这里插入图片描述
  • 勾选下面选项然后点击finish:
    在这里插入图片描述

三、全部代码

  • data_drive文件:
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 ]  = 256'h0000010000000000000000000000000000000000000000000000000000000000;char_line[ 1 ]  = 256'h1ff0210020000000000000000000000000000000000000000000000000000000;char_line[ 2 ]  = 256'h101011dc17fc0000000000000000000000000000000000000000000000000000;char_line[ 3 ]  = 256'h101011141040000018003c003c00180018007e001800180018003c003c000400;char_line[ 4 ]  = 256'h1ff0811480400000240042004200240024004200240024002400420042000c00;char_line[ 5 ]  = 256'h0000411440400000400042004200420042000400420040004200420042000c00;char_line[ 6 ]  = 256'h000047d448400000400002004200420042000400420040004200420042001400;char_line[ 7 ]  = 256'h3ff81014084000005c000400020042004200080042005c004200020002002400;char_line[ 8 ]  = 256'h0100111410407e00620018000400420042000800420062004200040004002400;char_line[ 9 ]  = 256'h0100211410400000420004000800420042001000420042004200080008004400;char_line[ 10 ] = 256'hfffee588e0400000420002001000420042001000420042004200100010007f00;char_line[ 11 ] = 256'h0280254820400000420042002000420042001000420042004200200020000400;char_line[ 12 ] = 256'h0440294820400000220042004200240024001000240022002400420042000400;char_line[ 13 ] = 256'h082021142ffe00001c003c007e0018001800100018001c0018007e007e001f00;char_line[ 14 ] = 256'h3018251420000000000000000000000000000000000000000000000000000000;char_line[ 15 ] = 256'hc006022200000000000000000000000000000000000000000000000000000000;end
end//实例化ROM
rom	rom_inst (
.address ( rom_address ),
.clock ( vga_clk ),
.q ( rom_data )
);
endmodule // data_drive
  • key_debounce文件:
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
  • vga_dirve文件:
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
  • vga_top顶层文件:
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

四、总结

了解了VGA显示的原理,其实就是为每个坐标分配一个RGB三通道的值,就是每个像素,场信号扫描得很快就能连成一幅图像。掌握了两种IP核的使用,就是图片没能成功显示。

五、参考资料

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

http://www.hengruixuexiao.com/news/10862.html

相关文章:

  • 网站模板安装步骤手游推广加盟
  • 网站做外链软件手机建站系统
  • 网站建设难度大吗网站推广优化价格
  • 链接关系 网站层次结构萧山市seo关键词排名
  • 网站备案资料 下载单页站好做seo吗
  • 申通e物流的网站建设推广下载app拿佣金
  • 网站首页线框图怎么做项目宣传推广方案
  • wordpress 飘窗上海seo优化外包公司
  • 美观网站建设物美价廉个人做外贸怎样起步
  • 免费网站注册申请百度推广价格
  • 广州微网站建设价位seo网站关键词优化怎么做
  • html网页制作模板图片it菜鸡网seo
  • 网站开发google长春seo按天计费
  • 网站建设公司一般几个人市场营销方案
  • 网站建设和管理无人区在线观看高清1080
  • 免费书画网站模板搜狗关键词排名此会zjkwlgs
  • 广安建设局网站阿亮seo技术
  • 苏州园区网站建设优书网首页
  • 网站制作1000元百度关键词排名查询接口
  • ueditor 转wordpress北京seo优化
  • 个人网站名字可以用哪些今晚比分足球预测
  • wordpress暂停网站百度识图搜索图片来源
  • 做网站平台成本seo快速优化软件网站
  • 网站收录入口申请查询绍兴seo推广公司
  • 营销型网站建设实训总结提高工作效率的方法
  • 工信部网站手机备案查询二维码推广赚佣金平台
  • 建个网站大概多少钱怎么让百度搜出自己
  • 上海网站备案核验郑州seo优化外包公司
  • 平面设计图用什么软件百度ocpc怎么优化
  • 招聘网站毕业设计网上国网推广