此程序参考了众多例程序,搞腾了两天时间才完工(本人愚钝,请勿见笑),程序修改了无数次,经历了20多个版本,因为多数例子都是显示的8色,16色之类的,所以在256色显示上,本人走了太多的弯路,感慨万千,一下是我所做过的弯路实现的功能吧。
以上是两天内的各种版本的缩影,还参照了51FPGA的部分程序,以下是最终的版本,实现了256色的显示,虽然我自己看着也不像256色,但是程序上讲,是实现的,色差可能与分压电阻有关系。
程序代码如下:
module vga(
clk,rst_n,
hsync,vsync,
vga_r,vga_g,vga_b
);
input clk; //50MHz
input rst_n; //低电平复位
output hsync; //行同步信号
output vsync; //场同步信号
output[2:0] vga_r;
output[2:0] vga_g;
output[1:0] vga_b;
//--------------------------------------------------
reg[10:0] x_cnt; //行坐标
reg[9:0] y_cnt; //列坐标
always @ (posedge clk or negedge rst_n)
if(!rst_n) x_cnt <= 11'd0;
else if(x_cnt == 11'd1039) x_cnt <= 11'd0;
else x_cnt <= x_cnt+1'b1;
always @ (posedge clk or negedge rst_n)
if(!rst_n) y_cnt <= 10'd0;
else if(y_cnt == 10'd665) y_cnt <= 10'd0;
else if(x_cnt == 11'd1039) y_cnt <= y_cnt+1'b1;
//--------------------------------------------------
wire valid; //有效显示区标志
assign valid = (x_cnt >= 11'd187) && (x_cnt < 11'd987)
&& (y_cnt >= 10'd31) && (y_cnt < 10'd631);
wire[9:0] x_dis,y_dis; //有效显示区坐标
assign x_dis = x_cnt-11'd187;
assign y_dis = y_cnt-10'd31;
//--------------------------------------------------
reg hsync_r,vsync_r; //同步信号产生
always @ (posedge clk or negedge rst_n)
if(!rst_n) hsync_r <= 1'b1;
else if(x_cnt == 11'd0) hsync_r <= 1'b0; //产生hsync信号
else if(x_cnt == 11'd120) hsync_r <= 1'b1;
always @ (posedge clk or negedge rst_n)
if(!rst_n) vsync_r <= 1'b1;
else if(y_cnt == 10'd0) vsync_r <= 1'b0; //产生vsync信号
else if(y_cnt == 10'd6) vsync_r <= 1'b1;
assign hsync = hsync_r;
assign vsync = vsync_r;
//--------------------------------------------------
// VGA色彩信号产生
/*
一共800*600个像素点,需要显示256种颜色;
大约每块区域显示50*38
*/
reg[7:0] vga_rgb; // VGA色彩显示寄存器
always @ (posedge clk)
if(!valid) vga_rgb <= 8'd0;
else begin
case(x_dis)
10'd0: begin //当x坐标回到0时,让显示色彩数据根据当前的y坐标值重新复位
if(y_dis >= 10'd0 && y_dis < 10'd38) vga_rgb <= 8'd0;
else if(y_dis >= 10'd38 && y_dis < 10'd76) vga_rgb <= 8'd16;
else if(y_dis >= 10'd76 && y_dis < 10'd114) vga_rgb <= 8'd32;
else if(y_dis >= 10'd114 && y_dis < 10'd152) vga_rgb <= 8'd48;
else if(y_dis >= 10'd152 && y_dis < 10'd190) vga_rgb <= 8'd64;
else if(y_dis >= 10'd228 && y_dis < 10'd266) vga_rgb <= 8'd80;
else if(y_dis >= 10'd266 && y_dis < 10'd304) vga_rgb <= 8'd96;
else if(y_dis >= 10'd304 && y_dis < 10'd342) vga_rgb <= 8'd112;
else if(y_dis >= 10'd342 && y_dis < 10'd380) vga_rgb <= 8'd128;
else if(y_dis >= 10'd418 && y_dis < 10'd456) vga_rgb <= 8'd144;
else if(y_dis >= 10'd456 && y_dis < 10'd494) vga_rgb <= 8'd160;
else if(y_dis >= 10'd494 && y_dis < 10'd532) vga_rgb <= 8'd176;
else if(y_dis >= 10'd532 && y_dis < 10'd570) vga_rgb <= 8'd192;
else if(y_dis >= 10'd570 && y_dis < 10'd608) vga_rgb <= 8'd208;
else if(y_dis >= 10'd608 && y_dis < 10'd644) vga_rgb <= 8'd224;
else vga_rgb <= 8'd240;
end
10'd50,10'd100,10'd150,10'd200,10'd250,10'd300,10'd350,10'd400,10'd450,10'd500,
10'd550,10'd600,10'd650,10'd700,10'd750,10'd800: vga_rgb <= vga_rgb+1'b1; //每40个横坐标像素点后显示色彩数据增1变化
default: ;
endcase
end
//r,g,b控制液晶屏颜色显示
assign vga_r = vga_rgb[7:5];
assign vga_g = vga_rgb[4:2];
assign vga_b = vga_rgb[1:0];
endmodule