文章目录
1. VGA时序
VGA总线包含vga_clk, v ga_vs, vga_hs, vga_de, vga_data五种信号。vga_clk即为时钟信号;vga_vs为场同步信号(vertical synchronous signal),代表着一帧信号是否有效;vga_hs为行同步信号(horizontal synchronous signal),代表一行数据是否有效;vga_de为数据有效信号(data enable),代表是否数据有效;vga_data为数据信号(以下为RGB888 24bits)。以下为VGA时序图。需要注意的是行场同步信号既有可能高电平有效也有可能低电平有效,具体看设计要求,下面设计以低电平有效为例。
为了数据的对齐,VGA时序增加一些前沿(Front porch)和后沿(Back porch),不同显示分辨率对应不同的沿参数。具体含义可参考该博客(传送门)。以下以640x480分辨率为例。
2. VGA时序代码
该模块模拟VGA时序输出,模块内部vga_data是累加得到的,具体数据可以另外设置,可以修改参数改变分辨率。
//VGA接口,模拟VGA显示时序的功能
module vga_gen(
input clk,
input rst_n,
output reg vga_hs, //高电平有效
output reg vga_vs, //高电平有效
output reg vga_de,
output reg [7:0] vga_data
);
reg[15:0] h_counter; //行计数器
reg[15:0] v_counter; //场计数器
//parameter define
// 640x480
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 ; //场扫描周期
//行同步信号计数器
always@ (posedge clk or negedge rst_n)begin
if(!rst_n)
h_counter <= 0;
else if(h_counter == H_TOTAL-1)
h_counter <= 0;//复位行计数器
else
h_counter <= h_counter+1;
end
//场同步信号计数器
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
v_counter <= 0;
else if(v_counter == V_TOTAL-1 & h_counter == H_TOTAL-1)
v_counter <= 0;
else if(h_counter == H_TOTAL-1)
v_counter <= v_counter+1;
else
v_counter <= v_counter;
end
//产生vsync脉冲
always @(*) begin
if(v_counter <= V_SYNC - 1'b1)
vga_vs = 0;
else
vga_vs = 1;
end
//产生hsync脉冲
always @(*)begin
if(h_counter <= H_SYNC - 1'b1)
vga_hs = 0;
else
vga_hs = 1;
end
//产生de脉冲
always@(*) begin
if((h_counter >= H_SYNC + H_BACK )
&& (h_counter < H_SYNC + H_BACK + H_VALID)
&&(v_counter >= V_SYNC + V_BACK )
&& (v_counter < V_SYNC + V_BACK + V_VALID))
vga_de = 1;
else
vga_de = 0;
end
//生成vga_data数据
//需要有vga_de才输出vga_data,不然vga显示器无法显示图像
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
vga_data <= 'd0;
else if(vga_de)
vga_data <= vga_data+'d1;
end
endmodule
NOTE:需要注意的是如果VGA显示器无法输出正确图像是黑屏状态,但是已经上电了,可能需要保证vga_data在vga_de时才输出有效,不能保持vga_data不变。