1.vga我们要用时用的较多的信号是行同步信号hys、场同步信号vys、颜色三原色红R、绿G、蓝B。
2.如图,以640*480的分辨率为例,hys的时序如图所示,而vys与hys类似,不同的只是数据和单位。
hys的单位是基准时钟,而vys的单位是行,见下表:
3.场同步信号和行同步信号均处于显示区域的时候,才是真正的显示区域
4.基准时钟的计算:与分辨率的刷新率有关
若为60HZ,意味着一秒显示60幅图像,而一幅图像占据800x525个时钟,所以基准时钟周期 = (1/60)/(800x525),约为39.68ns,时钟晶振约为25M。
5.先设计一个驱动模块:
module color
(
clk,
rst_n,
hys,
vys,
lcd_rgb
); //5个接口:时钟、复位、行、列、rgb显示
input clk;
input rst_n;
output hys;
output vys;
output [15:0] lcd_rgb; //输入输出声明
reg [9:0] h_cnt; //行信号计数器,最大为800个基准时钟
wire add_h_cnt;
wire end_h_cnt;
reg [9:0] v_cnt; //列信号计数器,最大为525个基准时钟
wire add_v_cnt;
wire end_v_cnt;
reg hys;
reg vys;
reg red_area;
reg [15:0] lcd_rgb; //16位的rgb信号
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
h_cnt <= 0;
end
else if(add_h_cnt)begin
if(end_h_cnt)
h_cnt <= 0;
else
h_cnt <= h_cnt + 1;
end
end
assign add_h_cnt =1 ;
assign end_h_cnt = add_h_cnt && h_cnt==800-1 ; //计数器0:行基准时钟计数
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
hys <= 0;
end
else if(add_h_cnt && h_cnt==96-1)begin //由时序图可知,在96个基准时钟后将hys拉高
hys <= 1;
end
else if(end_h_cnt)begin
hys <= 0;
end
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
v_cnt <= 0;
end
else if(add_v_cnt)begin
if(end_v_cnt)
v_cnt <= 0;
else
v_cnt <= v_cnt + 1;
end
end
assign add_v_cnt =end_h_cnt ;
assign end_v_cnt = add_v_cnt && v_cnt==525-1 ; //计数器1:列计数
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
vys <=0;
end
else if(add_v_cnt && v_cnt==2-1)begin //在第二列时将vys信号拉高
vys <=1;
end
else if(end_v_cnt)begin
vys <=0;
end
end
always @(*)begin
red_area = (h_cnt >= (96+48) && h_cnt<(96+48+640)) && (v_cnt>=(2+33) && v_cnt<(2+33+480));
end //显示的有效区域
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
lcd_rgb <= 0;
end
else if(red_area)begin
lcd_rgb <= 16'b11111_000000_00000; //显示功能
end
else begin
lcd_rgb <= 0;
end
end
endmodule
5.因为基准时钟为25M,而我们的时钟是50M,因此需要引用PLL的IP核来对时钟进行分频。
6.分频后,在顶层模块调用pll和驱动模块即可完成设计。
module color_top
(
clk,
rst_n,
hys,
vys,
lcd_rgb
);
input clk;
input rst_n;
output hys;
output vys;
output [15:0] lcd_rgb;
wire clk_0;
wire hys;
wire vys;
wire [15:0] lcd_rgb;
my_pll module_1 //调用PLL ip核
(
.inclk0 (clk),
.c0 (clk_0)
);
color module_2 //调用驱动模块
(
.clk(clk_0),
.rst_n(rst_n),
.hys(hys),
.vys(vys),
.lcd_rgb(lcd_rgb)
);
endmodule
最后的RTL电路如图所示: