【精品博文】基于FPGA的VGA测试程序
赢一个双肩背包
有多难?
戳一下试试看!
→_→
由于自己先买的黑金的开发板,后买的CB的书,最近在看基于SDRAM的VGA显示,一直有点问题,今天上午本来想写个验证程序看一下问题在哪,但是却弄了一上午,因为碰到了一个小问题,不过最终还是解决了。
先上效果图
就是这样每隔一秒切换下一张,但是问题是,VGA一直停留在第一张图片上
这是我的定时器程序:
就是每当一张图片的数据完成以后开始定时1s,isCount是定时器的开关
原本写成这样,做了仿真,isCount时钟等于0,定时器无论如何也不会开始工作,很郁闷,最后发现
是这个样子的:
尽管
if ( lcd_xpos == `H_DISP && lcd_ypos == `V_DISP )begin isCount <= 1'b1;打开了定时器但是同时由于没有display_done == 0; 导致执行了下面这个if语句的else,也就是isCount <= isCount,而此时isCount是上一个clk的值,也就是复位时候的0,所以导致了isCount被赋值1时候也被赋值0,产生了竞争,最后可能是由于编译器优化为了0,导致定时器开启失败,也就导致,状态机只停留在了这个状态最后优化如下:if ( display_done ) begin isCount <= 1'b0; image_state <= image_state + 1'b1; endelse if ( lcd_xpos == `H_DISP && lcd_ypos == `V_DISP ) begin isCount <= 1'b1; image_state <= image_state; end 问题解决!!!
最后上自己的程序,只上传自己写的部分,剩下的程序都是Bingo的,尊重别人版权,需要的去他那里下载。不过我这个也是在他那个基础上改的。
`timescale 1 ns / 1 ns
module VGAData_Simulate_16Bit
(
// global clock
input clk,
input rst_n,
input [10:0] lcd_xpos, //lcd horizontal coordinate
input [10:0] lcd_ypos, //lcd vertical coordinate
output reg [15:0] lcd_data //lcd data
);
`include "lcd_para.v"
//--------------------------------------------------------------------------
// Always Block 1
// the delay time of write a frame of picture
// delay Start when a frame of picture is write over
localparam DISP_DELAY_CNT = 25'd25000000; // delay 1s (25Mhz)
//localparam DISP_DELAY_CNT = 25'd2500; // just for simulation
reg [24:0] delay_cnt; // the delay time counter
reg isCount; // enable counter
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
delay_cnt <= 25'd0;
else if ( isCount == 1'b1 ) // a frame of picture write over
if ( delay_cnt < DISP_DELAY_CNT -1'b1 )
delay_cnt <= delay_cnt + 1'b1;
else
delay_cnt <= 25'd0;
else
delay_cnt <= 0;
end
wire display_done = (delay_cnt == DISP_DELAY_CNT -1'b1) ? 1'b1 : 1'b0;
//---------------------------------------
reg [1:0] image_state; // switch a frame of image counter
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
image_state <= 1'b0;
lcd_data <= `BLACK;
isCount <= 1'b0;
end
else
begin
//-----------------------------------------------------------------------------------------------
case(image_state)
// picture 1
2'd0:
begin
lcd_data <= lcd_xpos * lcd_ypos;
if ( display_done )
begin
isCount <= 1'b0;
image_state <= image_state + 1'b1;
end
else if ( lcd_xpos == `H_DISP - 1'b1 && lcd_ypos == `V_DISP - 1'b1 )
begin
isCount <= 1'b1;
image_state <= image_state;
end
end
// picture 2
2'd1:
begin
lcd_data <= (lcd_ypos < `V_DISP/2) ? {lcd_ypos[7:3], lcd_ypos[7:2], lcd_ypos[7:3]}:
{lcd_xpos[7:3], lcd_xpos[7:2], lcd_xpos[7:3]};
if ( display_done )
begin
isCount <= 1'b0;
image_state <= image_state + 1'b1;
end
else if ( lcd_xpos == `H_DISP - 1'b1 && lcd_ypos == `V_DISP - 1'b1 )
begin
isCount <= 1'b1;
image_state <= image_state;
end
end
//-----------------------------------------------------------------------------------------------
// picture 3
2'd2:
begin
lcd_data <= (lcd_xpos >= (`H_DISP/8)*0 && lcd_xpos < (`H_DISP/8)*1) ? `RED :
(lcd_xpos >= (`H_DISP/8)*1 && lcd_xpos < (`H_DISP/8)*2) ? `GREEN :
(lcd_xpos >= (`H_DISP/8)*2 && lcd_xpos < (`H_DISP/8)*3) ? `BLUE :
(lcd_xpos >= (`H_DISP/8)*3 && lcd_xpos < (`H_DISP/8)*4) ? `WHITE :
(lcd_xpos >= (`H_DISP/8)*4 && lcd_xpos < (`H_DISP/8)*5) ? `BLACK :
(lcd_xpos >= (`H_DISP/8)*5 && lcd_xpos < (`H_DISP/8)*6) ? `YELLOW :
(lcd_xpos >= (`H_DISP/8)*6 && lcd_xpos < (`H_DISP/8)*7) ? `CYAN : `ROYAL;
if ( display_done )
begin
isCount <= 1'b0;
image_state <= image_state + 1'b1;
end
else if ( lcd_xpos == `H_DISP - 1'b1 && lcd_ypos == `V_DISP - 1'b1 )
begin
isCount <= 1'b1;
image_state <= image_state;
end
end
//-----------------------------------------------------------------------------------------------
// picture 4
2'd3:
begin
lcd_data <= (lcd_ypos >= (`V_DISP/8)*0 && lcd_ypos < (`V_DISP/8)*1) ? `RED :
(lcd_ypos >= (`V_DISP/8)*1 && lcd_ypos < (`V_DISP/8)*2) ? `GREEN :
(lcd_ypos >= (`V_DISP/8)*2 && lcd_ypos < (`V_DISP/8)*3) ? `BLUE :
(lcd_ypos >= (`V_DISP/8)*3 && lcd_ypos < (`V_DISP/8)*4) ? `WHITE :
(lcd_ypos >= (`V_DISP/8)*4 && lcd_ypos < (`V_DISP/8)*5) ? `BLACK :
(lcd_ypos >= (`V_DISP/8)*5 && lcd_ypos < (`V_DISP/8)*6) ? `YELLOW :
(lcd_ypos >= (`V_DISP/8)*6 && lcd_ypos < (`V_DISP/8)*7) ? `CYAN : `ROYAL;
if ( display_done )
begin
isCount <= 1'b0;
image_state <= image_state + 1'b1;
end
else if ( lcd_xpos == `H_DISP - 1'b1 && lcd_ypos == `V_DISP - 1'b1 )
begin
isCount <= 1'b1;
image_state <= image_state;
end
end
endcase
end
end
endmodule