VGA控制器设计实现显示器屏幕保护模块文档格式.docx
《VGA控制器设计实现显示器屏幕保护模块文档格式.docx》由会员分享,可在线阅读,更多相关《VGA控制器设计实现显示器屏幕保护模块文档格式.docx(33页珍藏版)》请在冰豆网上搜索。
VGA彩色显示器,彩色是由R、G、B(红、绿、蓝)三基色组成,CRT用逐行扫描方式实现图像显示,由VGA控制模块产生的水平同步信号(HS)和垂直同步信号(VS)控制阴极射线枪产生的电子束,打在涂有荧光粉的荧光屏上,产生R、G、B三基色,合成一个彩色像素。
扫描从屏幕的左上方开始,由左至右,由上到下,逐行进行扫描,每扫完一行,电子束回到屏幕下一行的起始位置,在回扫期间,CRT对电子束进行消隐,每行结束是用行同步信号HS进行行同步;
扫描完所有行,再由场同步信号VS进行场同步,并使扫描回到屏幕的左上方,同时进行场消隐,预备下一场的扫描。
显示需要R,G,B,Hsync(行同步),Vsync(帧同步)五个信号输出到显示器,本设计按照VGA工业标准输出640*480@60Hz.对应的时序如下:
图1VGA接口信号基本时序图
图2FPGA板上的VGA接口
图3VGA(640*480@60Hz)时序图
VGA显示的设计模块为:
说明:
设计中FPGA板的VGA接口将R,G,B分别设为定义为2位,3位,3位,例如显示红色RGB可以输出为11000000,绿色输出为00111000,蓝色输出为00000111.
表125MHz640*480@60Hz模式下VGA的时序
5、代码
顶层模块包括4个模块,分别为分频div_clk、按键扫描keyscan、时序产生模块video_signal_gen、算法显示模块disp_alg,其中分频模块有4个,分别输出25MHz、10kHz、50Hz、3s的时钟,25MHz是给video_signal_gen模块产生行时序和场时序的,10kHz是按键扫描的,50Hz是计算小方块的移动速度的时钟,3s是小方块背景变化时间。
而div_clk模块是用实验一的模块,所以就不写测试代码测试了。
1、顶层
按键先缓存2个时钟,为了消除亚稳态。
其他就只是连线。
modulevga256(
clk_50m,
rst_p,
key,
vsync,
hsync,
vga_de,
vga_b,
vga_g,
vga_r
);
inputwireclk_50m;
inputwirerst_p;
inputwire[2:
0]key;
outputwirevsync;
outputwirehsync;
outputwirevga_de;
outputwire[1:
0]vga_b;
outputwire[2:
0]vga_g;
0]vga_r;
wirerst_n;
assignrst_n=~rst_p;
///////////////////////////////////////////////////////////////////////////////////
//clock
wireclk_25m;
//25MHzVGA
div_clk
#(
.cnt
(2)
)
u1div_clk
(
.clk(clk_50m),
.rst_n(rst_n),
.f_clk(clk_25m)
);
wireclk_10k;
//10kHzkeyscan
.cnt(5000)
u2div_clk
.f_clk(clk_10k)
wireclk_50hz;
//50hzspeedofmovement
.cnt(1000000)
u3div_clk
.f_clk(clk_50hz)
wireclk_3s;
//3scolortranslationalspeed
.cnt(150)
u4div_clk
(
.clk(clk_50hz),
.rst_n(rst_n),
.f_clk(clk_3s)
);
//keytwobuffers
reg[2:
0]key_r1;
0]key_r2;
0]key_r3;
wire[2:
0]key_val;
always@(posedgeclk_10kornegedgerst_n)
if(!
rst_n)
begin
key_r1<
=3'
b000;
key_r2<
key_r3<
end
else
=key;
=key_r1;
=key_r2;
assignkey_val=key_r3;
//&
key_r2&
key_r1;
wire[1:
0]key1;
//wire[2:
0]key2;
0]key3;
keyscanu1keyscan(
.clk(clk_10k),
.rst_n(rst_n),
.key(key_val),
.key1(key1),
//.key2(key2),
.key3(key3)
);
wire[9:
0]vga_x;
0]vga_y;
wire[7:
0]vga_rgb;
video_signal_genb2v_inst1(
.video_clk(clk_25m),
.video_rgb(vga_rgb),
.video_x(vga_x),
.video_y(vga_y),
.video_hsync(hsync),
.video_vsync(vsync),
.video_de(vga_de),
.video_b(vga_b),
.video_g(vga_g),
.video_r(vga_r)
/////////////////////////////////////////////////////////////////////////////////////
disp_algu1disp_alg(
.clk1(clk_25m),
.clk2(clk_50hz),
.clk3(clk_3s),
.rst_n(rst_n),
.key1(key1),
.key3(key3),
.video_x(vga_x),
.video_y(vga_y),
.video_rgb(vga_rgb)
);
endmodule
RTL图:
图5.1.1顶层模块RTL图1
图5.1.2顶层模块RTL图2
-----------------------------------------------------------------------------
2、div_clk模块代码
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useieee.std_logic_arith.all;
USEieee.std_logic_unsigned.all;
--Uncommentthefollowinglibrarydeclarationifusing
--arithmeticfunctionswithSignedorUnsignedvalues
--useIEEE.NUMERIC_STD.ALL;
--Uncommentthefollowinglibrarydeclarationifinstantiating
--anyXilinxprimitivesinthiscode.
--libraryUNISIM;
--useUNISIM.VComponents.all;
entitydiv_clkis
generic(cnt:
integerrange1to2**30:
=2**30);
--分频系数
port(
clk:
instd_logic;
rst_n:
f_clk:
outstd_logic
);
enddiv_clk;
architectureBehavioralofdiv_clkis
signalsf_clk:
std_logic:
='
0'
;
begin
process(clk,rst_n)
variablei:
integerrange0tocnt:
=0;
begin
if(rst_n='
)then
i:
=cnt;
sf_clk<
if(clk'
eventandclk='
1'
i:
=i-1;
if((i<
0)or(i>
cnt))then
i:
elsif(i=0)then
sf_clk<
elsif(i>
=cnt/2)then
else
endif;
endif;
endif;
endprocess;
process(clk,sf_clk)
if(cnt=0)then
f_clk<
elsif(cnt=1)then
=clk;
=sf_clk;
endBehavioral;
3、keyscan模块代码
每按下按键一次就会产生一个脉冲,从而可以给算法来判断执行那个操作。
modulekeyscan(
clk,
rst_n,
key,
key1,
key2,
key3
);
inputclk;
inputrst_n;
input[2:
output[1:
//times
output[2:
//backcolorcount
//selectsize,60/80width
reg[1:
0]key1_r;
0]key2_r;
0]key3_r;
0]key1_pre;
0]key2_pre;
0]key3_pre;
regkey1_r1;
regkey1_r2;
wirekey1_pulse;
regkey2_r1;
regkey2_r2;
wirekey2_pulse;
regkey3_r1;
regkey3_r2;
wirekey3_pulse;
always@(posedgeclkornegedgerst_n)
key1_r1<
=1'
b0;
key1_r2<
key2_r1<
key2_r2<
key3_r1<
key3_r2<
=key[0];
=key1_r1;
=key[1];
=key2_r1;
=key[2];
=key3_r1;
assignkey1_pulse=key1_r1&
(!
key1_r2);
assignkey2_pulse=key2_r1&
key2_r2);
assignkey3_pulse=key3_r1&
key3_r2);
key1_r<
=2'
b00;
key2_r<
key3_r<
=key1_pre;
=key2_pre;
=key3_pre;
assignkey1_pre=key1_pulse?
((key1_r==2'
b11)?
2'
b00:
(key1_r+2'
b01)):
key1_r;
assignkey2_pre=key1_r[1]?
(key2_pulse?
((key2_r==3'
b111)?
3'
(key2_r+3'
b001)):
key2_r):
assignkey3_pre=key1_r[1]?
(key3_pulse?
((key3_r==2'
(key3_r+2'
key3_r):
1'
assignkey1=key1_r;
assignkey2=key2_r;
assignkey3=key3_r;
4、video_signal_gen时序产生模块
在此模块中有输入有RGB,输出有横坐标X、纵坐标Y、行同步HS、场同步VS、使能DE、红色R值、绿色G值、蓝色B值。
输入的RGB是为了给内部其他模块用的,可以根据输出的横坐标和纵坐标而改变屏幕的点的颜色。
//Description:
连接开发板的VGA接口和电脑液晶屏,
//即可显示640*480分辨率下的256种色彩
modulevideo_signal_gen
parameterHSTS=800,//allhsynctimes
HSTDISP=640,//hsyncdisplaytimes
HSTPW=96,//hsyncplusewidthtimes
HSTFP=16,//hsyncfrontplusetimes
HSTBP=48,//hsyncbackplusetimes
VSTS=521,//allvsyncplusetimes
VSTDISP=480,//vsyncdisplayplusetimes
VSTPW=2,//vsyncplusetimes
VSTFP=10,//vsyncfrontplusetimes
VSTBP=29,//vsyncbackplusetimes
width_x=10,//displayxcoordinatewidth
width_y=10//displayycoordinatewidth
(
video_clk,
rst_n,
//raminterface
video_rgb,
video_x,//pointcoordinate
video_y,
//VGAtransfer
video_hsync,
video_vsync,
video_de,
video_r,
video_g,
video_b
inputvideo_clk;
//25MHz
inputrst_n;
//reset
//raminterface
input[7:
0]video_rgb;
output[width_x-1:
0]video_x;
output[width_y-1:
0]video_y;
//FPGA与VGA接口信号
outputvideo_hsync;
//行同步信号
outputvideo_vsync;
//场同步信号
outputvideo_de;
//vaild
output[2:
0]video_r;
0]video_g;
output[1:
0]video_b;
//--------------------------------------------------
//coordinatecount
reg[width_x-1:
0]x_cnt;
//行坐标
wire[width_x-1:
0]x_cnt_pre;
reg[width_y-1:
0]y_cnt;
//列坐标
wire[width_y-1:
0]y_cnt_pre;
//generatex_cnt
always@(posedgevideo_clkornegedgerst_n)
if(!
x_cnt<
={width_x{1'
b0}};
else
=x_cnt_pre;
assignx_cnt_pre=(x_cnt==HSTS-1'
b1)?
{width_x{1'
b0}}:
(x_cnt+1'
b1);
//generatey_cnt
y_cnt<
={width_y{1'
=y_cnt_pre;
assigny_cnt_pre=(y_cnt==VSTS-1'
{width_y{1'
((x_cnt==HSTS-1'
(y_cnt+1'
b1):
y_cnt);
//generatehsync
reghsync_r;
wirehsync_r_p