verilog驱动VGA显示
系统框图如下
PLL分频模块
此模块使用锁相环IP核自动生成,相关分辨率的像素时钟不同,需要根据实际分辨率进行频率的设置。
常用VGA分辨率的时钟以及行同步和场同步如下:
VGA时序图如下:
VGA控制模块
module clk_ctrl (input wire vga_clk, //VGA时钟input wire rst_n,//复位input wire [15:0] pic_data,//输入的像素点信息output wire [9:0] pic_x,//输出显示像素的坐标output wire [9:0] pic_y,//输出显示像素的坐标output wire hsync,//行同步信号output wire vsync,//场同步信号output wire [15:0] rgb_data//输出的VGA像素点信号
);
//分辨率为640*480
//parameter define
parameter H_SYNC = 10'd96 , //行同步H_BACK = 10'd40 , //行时序后沿H_LEFT = 10'd8 , //行时序左边框H_VALID = 10'd640 , //行有效数据H_RIGHT = 10'd8 , //行时序右边框H_FRONT = 10'd8 , //行时序前沿H_TOTAL = 10'd800 ; //行扫描周期
parameter V_SYNC = 10'd2 , //场同步V_BACK = 10'd25 , //场时序后沿V_TOP = 10'd8 , //场时序上边框V_VALID = 10'd480 , //场有效数据V_BOTTOM = 10'd8 , //场时序下边框V_FRONT = 10'd2 , //场时序前沿V_TOTAL = 10'd525 ; //场扫描周期wire rgb_en;//VGA有效显示范围时,为高电平
wire pic_data_request;//高电平时申请像素点色彩
reg [9:0] count_h;//行同步信号计数
reg [9:0] count_v;//场同步信号计数//行同步信号计数
always @(posedge vga_clk or negedge rst_n) beginif (!rst_n) begincount_h <= 10'b0;endelse if (count_h == H_TOTAL -1'b1) begincount_h <= 10'b0;endelsecount_h <= count_h +1'b1;
end
//行同步信号输出
assign hsync = (count_h <= H_SYNC -1'b1) ? 1'b1 : 1'b0;//场同步信号计数
always @(posedge vga_clk or negedge rst_n) beginif (!rst_n) begincount_v <= 10'b0;endelse if ((count_v == V_TOTAL - 1'b1) && (count_h == H_TOTAL - 1'b1)) begincount_v <= 10'b0;endelse if (count_h == H_TOTAL - 1'b1) begincount_v <= count_v + 1'b1;endelsecount_v <= count_v;
end
//场同步信号输出
assign vsync = (count_v <= V_SYNC - 1'b1) ? 1'b1 : 1'b0;//rgb_en,VGA有效显示区域高电平
assign rgb_en = (((count_h >= H_SYNC + H_BACK + H_LEFT)&& (count_h < H_SYNC + H_BACK + H_LEFT + H_VALID))&&((count_v >= V_SYNC + V_BACK + V_TOP)&& (count_v < V_SYNC + V_BACK + V_TOP + V_VALID)))? 1'b1 : 1'b0;
//pic_data_request像素点信号请求
assign pic_data_request = (((count_h >= H_SYNC + H_BACK + H_LEFT - 1'b1)&& (count_h < H_SYNC + H_BACK + H_LEFT + H_VALID - 1'b1))&&((count_v >= V_SYNC + V_BACK + V_TOP)&& (count_v < V_SYNC + V_BACK + V_TOP + V_VALID)))? 1'b1 : 1'b0;//显示像素坐标
assign pic_x = (pic_data_request == 1'b1) ? (count_h - (H_SYNC + H_BACK + H_LEFT - 1'b1)) : 10'h3ff;
assign pic_y = (pic_data_request == 1'b1)? (count_v - (V_SYNC + V_BACK + V_TOP)) : 10'h3ff;
//输出RGB信号
assign rgb_data = (rgb_en == 1'b1) ? pic_data : 16'b0;endmodule //clk_ctrl
控制模块主要根据锁相环分频出的VGA像素频率进行计数,从而得到行同步信号和场同步信号,同时计算出像素的坐标,从而可以向图像显示模块申请像素信息。
图像显示模块
module clk_pic (input wire vga_clk,input wire rst_n,input wire [9:0] pic_x,input wire [9:0] pic_y,output reg [15:0] pic_data
);
//parameter define
parameter H_VALID = 10'd640 , //行有效数据V_VALID = 10'd480 ; //场有效数据parameter RED = 16'hF800, //红色ORANGE = 16'hFC00, //橙色YELLOW = 16'hFFE0, //黄色GREEN = 16'h07E0, //绿色CYAN = 16'h07FF, //青色BLUE = 16'h001F, //蓝色PURPPLE = 16'hF81F, //紫色BLACK = 16'h0000, //黑色WHITE = 16'hFFFF, //白色GRAY = 16'hD69A; //灰色always@(posedge vga_clk or negedge rst_n)if(!rst_n)pic_data <= 16'd0;else if((pic_x >= 0) && (pic_x < (H_VALID/10)*1))pic_data <= RED;else if((pic_x >= (H_VALID/10)*1) && (pic_x < (H_VALID/10)*2))pic_data <= ORANGE;else if((pic_x >= (H_VALID/10)*2) && (pic_x < (H_VALID/10)*3))pic_data <= YELLOW;else if((pic_x >= (H_VALID/10)*3) && (pic_x < (H_VALID/10)*4))pic_data <= GREEN;else if((pic_x >= (H_VALID/10)*4) && (pic_x < (H_VALID/10)*5))pic_data <= CYAN;else if((pic_x >= (H_VALID/10)*5) && (pic_x < (H_VALID/10)*6))pic_data <= BLUE;else if((pic_x >= (H_VALID/10)*6) && (pic_x < (H_VALID/10)*7))pic_data <= PURPPLE;else if((pic_x >= (H_VALID/10)*7) && (pic_x < (H_VALID/10)*8))pic_data <= BLACK;else if((pic_x >= (H_VALID/10)*8) && (pic_x < (H_VALID/10)*9))pic_data <= WHITE;else if((pic_x >= (H_VALID/10)*9) && (pic_x < H_VALID))pic_data <= GRAY;elsepic_data <= BLACK;endmodule //clk_pic
本模块主要作用是根据控制模块的像素信息生成相关的颜色信息,在这个模块中可以控制显示的内容。
顶层模块
module vga_colourbar (input wire sys_clk,input wire sys_rst_n,output wire hsync,output wire vsync,output wire [15:0] rgb_data
);wire vga_clk;
wire locked;
wire rst_n;
wire [9:0] pic_x;//显示像素的坐标
wire [9:0] pic_y;//显示像素的坐标
wire [15:0] pic_data;//像素点信息assign rst_n = (locked & sys_rst_n);clk_gen u_clk_gen(.areset (~sys_rst_n ),.inclk0 (sys_clk ),.c0 (vga_clk ),.locked (locked )
);clk_ctrl u_clk_ctrl(.vga_clk (vga_clk ),.rst_n (rst_n ),.pic_data (pic_data ),.pic_x (pic_x ),.pic_y (pic_y ),.hsync (hsync ),.vsync (vsync ),.rgb_data (rgb_data )
);clk_pic u_clk_pic(.vga_clk (vga_clk ),.rst_n (rst_n ),.pic_x (pic_x ),.pic_y (pic_y ),.pic_data (pic_data )
);endmodule //vga_colourbar
本模块主要例化了上述的三个模块,并且根据模块框图设计了复位的电路。