项目名称
带动画的矩形显示
具体要求
分为5个状态,状态1显示红蓝绿三个区域,状态2显示蓝绿,状态3显示绿,状态4显示蓝绿,状态5显示红蓝绿。
设计说明
根据vgs显示时序图计算出需要显示区域的临界点,红色和绿色为100*100和200*200的像素。
分辨率 | 时钟(mhz) | 行时序(像素) | 场时序(像素) | ||||||||
a | b | c | d | e | a | b | c | d | e | ||
640*480@60hz | 25.175mhz | 96 | 48 | 640 | 16 | 800 | 2 | 33 | 480 | 10 | 525 |
其中横线和竖线的左侧和上侧的数据代表的是边界区域的上一列和上一行的行时序和场时序。每个状态显示0.5s,需要设计一个状态改变计数器和状态计数器,对于每个区域显示设计一个标志信号。有些人不明白为什么要做VGA显示,笔者目前做图像处理方面的研究,在FPGA图像处理方面VGA显示是用的比较多的,所以对VGA一定要带入相关的项目深入了解,虽然项目比较简单,但是学习是一个由易到难的过程。
主要代码设计
//部分主要代码
localparam red=24'hff0000;
localparam green=24'h00ff00;
localparam blue=24'h0000ff;
localparam white=24'hffffff;
localparam black=24'h000000;
localparam yellow=24'hffff00;
localparam cyan=24'hff00ff;
localparam royal=24'h00ffff;
reg [10:0] cnt1;//行像素计数器
reg [10:0] cnt2;//列像素计数器
//行时序计满799,从0开始计数
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt1<=11'd0;
else if(cnt1<11'd799)
cnt1<=cnt1+1'b1;
else
cnt1<=11'd0;
//场时序计满524
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt2<=11'd0;
else if(cnt1==11'd799)begin
if(cnt2<11'd524)
cnt2<=cnt2+1;
else
cnt2<=0;
end
else
cnt2<=cnt2;
assign vga_hs=(cnt1<=95)?0:1;
assign vga_vs=(cnt2<=1)?0:1;
//显示区标志信号
wire flag=(cnt1>=10'd144 && cnt1<10'd784) && (cnt2>=10'd35 && cnt2<10'd515);
//-----------显示区域标志信号---------------//
wire imshow_red=(cnt1>=10'd414 && cnt1<10'd514) && (cnt2>=10'd225 && cnt2<10'd325);
wire imshow_green=((cnt1>=10'd144 && cnt1<10'd364) || (cnt1>=10'd564 && cnt1<10'd784)
||(cnt2>=10'd35 && cnt2<10'd175) || (cnt2>=10'd375 && cnt2<10'd515));
//-----------显示区域标志信号---------------//
wire imshow_blue_big=((cnt1>=10'd364 && cnt1<10'd564) && (cnt2>=10'd175 && cnt2<10'd375));
//--------------------------------//
reg [3:0] state;
//每隔0.5s改变一下状态
reg [24:0] cnt_s;
always@(posedge clk or negedge rst_n)
if(!rst_n)
cnt_s<=0;
else if(cnt_s<25'd24999999)
cnt_s<=cnt_s+1;
else
cnt_s<=0;
wire cnt_s_done=(cnt_s==25'd24999999)?1:0;
always@(posedge clk or negedge rst_n)
if(!rst_n)
state<=0;
else if(cnt_s_done)begin
if(state<4)
state<=state+1;
else
state<=0;
end
else
state<=state;
//状态显示
always@(posedge clk or negedge rst_n)
if(!rst_n)
vga_rgb<=0;
else begin
case(state)
0: if(flag)
begin
if(imshow_green)
vga_rgb<=green;
else if(imshow_red)
vga_rgb<=red;
else
vga_rgb<=blue;
end
else
vga_rgb<=0;
1: if(flag)
begin
if(imshow_blue_big)
vga_rgb<=blue;
else
vga_rgb<=green;
end
else
vga_rgb<=0;
2:if(flag)
vga_rgb<=green;
else
vga_rgb<=0;
3:if(flag)
begin
if(imshow_blue_big)
vga_rgb<=blue;
else
vga_rgb<=green;
end
else
vga_rgb<=0;
4:if(flag)
begin
if(imshow_green)
vga_rgb<=green;
else if(imshow_red)
vga_rgb<=red;
else
vga_rgb<=blue;
end
else
vga_rgb<=0;
default:vga_rgb<=0;
endcase
end
assign lcd_sync=1'd0;
assign lcd_blank=vga_hs & vga_vs;
assign lcd_dclk=~clk;
显示结果