一、原理图
原理图应用小梅哥上课的笔记的截图【行扫描和场扫描的图一样】
二、行扫描和场扫描的关系
以显示像素位640*480的图像为例,每一行显示640个像素,一共显示480行。
行扫描相当于显示一行的像素,场扫描显示列的像素。没当一行扫描完事(计数器计满)列扫描的计数器增一(列计数器未满的情况下),直到记满列计数器(480).
这样的行和列组成一个二维矩阵,只有当二维矩阵都为visible area的时段时才会显示图像。
下面以一个网上的图为例,这个图非常形象。
该图来源于VGA系列之一:VGA显示器驱动篇
三、驱动程序和生成tb文件注意点
1、测试文件要求能够判断生成有效图像数据的位置是否正确,这里引入一个时序逻辑
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
vga_data_in<=0;
else if(vga_blk_en==1)
vga_data_in<=vga_data_in+1;
else if(!vga_blk_en)
vga_data_in<=vga_data_in;
end
四、驱动的程序
module vga_ctrl(
clk,
rst_n,
HSYC,
VSYC,
vga_data_out,
vga_data_in,
vga_blk,
vga_blk_en
);
input clk;
input rst_n;
input [23:0] vga_data_in;
output HSYC;
output VSYC;
output [23:0]vga_data_out;//
output vga_blk;
output vga_blk_en;
localparam hnum_1=96;
localparam hnum_2=96+40+8;
localparam hnum_3=96+40+8+640;
localparam hnum_4=96+40+8+640+8+8;
localparam vnum_1=2;
localparam vnum_2=2+25+8;
localparam vnum_3=2+25+8+480;
localparam vnum_4=2+8+8+25+2+480;
reg [9:0]hcount;
reg [9:0]vcount;
reg HSYC;
reg VSYC;
reg vga_blk;
reg vga_blk_en;
reg [23:0]vga_data_out;
//行时钟
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
hcount<=0;
else if(hcount==hnum_4-1)
hcount<=0;
else
hcount<=hcount+1;
end
//场时钟
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
vcount<=0;
else if(hcount==hnum_4-1)begin
if(vcount==vnum_4-1)
vcount<=0;
else
vcount<=vcount+1;
end
else
vcount<=vcount;
end
//行同步脉冲的开始和结束
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
HSYC=0;
else if(hcount==hnum_4-1)
HSYC<=0;
else if(hcount==hnum_1-1)
HSYC<=1;
end
//场同步脉冲开始和结束
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
VSYC=0;
else if(vcount==vnum_4-1)
VSYC<=0;
else if(vcount==vnum_1-1)
VSYC<=1;
end
//收到脉冲以后到传输数据之间的等待
//标志什么时候开始输出有效数据
//行输出标志
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
vga_blk<=0;
else if((hcount>(hnum_2-1))&&(hcount<(hnum_3))&&(vcount>(vnum_2-1))&&(vcount<(vnum_3)))
vga_blk<=1;
else
vga_blk<=0;
end
//如果下面的标志位是vga_data_in的话会滞后一拍在输出数据,也就是每一行开头会有0
//因此我们做以下修正
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
vga_blk<=0;
else if((hcount>(hnum_2-1))&&(hcount<(hnum_3))&&(vcount>(vnum_2-1))&&(vcount<(vnum_3)))
vga_blk_en<=1;
else
vga_blk_en<=0;
end
//有效数据的输出
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
vga_data_out<=0;
else if(vga_blk_en==1)
vga_data_out<=vga_data_in;
else
vga_data_out<=0;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
vga_data_out<=0;
else if(vga_blk_en==1)
vga_blk<=1;
else
vga_blk<=0;
end
endmodule