module vga256(
clk_50,rst_n, //系统控制
hsync,vsync,
vga_r,vga_g,vga_b // VGA控制
);
input clk_50; // 50MHz
input rst_n; //低电平复位
// FPGA与VGA接口信号
output hsync; //行同步信号
output vsync; //场同步信号
output[3:0] vga_r;
output[3:0] vga_g;
output[3:0] vga_b;
//===========================================================================
// PARAMETER declarations
//===========================================================================
// Horizontal Parameter
parameter H_FRONT = 152;
parameter H_SYNC = 232;
parameter H_BACK = 80;
parameter H_ACT = 1440;
parameter H_VALID = H_FRONT+H_SYNC;
parameter H_TOTAL = H_FRONT+H_SYNC+H_BACK+H_ACT;
// Vertical Parameter
parameter V_FRONT = 3;
parameter V_SYNC = 28;
parameter V_BACK = 1;
parameter V_ACT = 900;
parameter V_VALID = V_FRONT+V_SYNC;
parameter V_TOTAL = V_FRONT+V_SYNC+V_BACK+V_ACT;
//===============================================================================
//===============================================================================
wire clk_106;
pll_clk pll_clk_inst (
.inclk0 ( clk_50),
.c0 ( clk_106 )
);
assign clk = clk_106;
//--------------------------------------------------
// 坐标计数
reg[10:0] x_cnt; //行坐标
reg[10:0] y_cnt; //列坐标
always @ (posedge clk or negedge rst_n)
if(!rst_n) x_cnt <= 11'd0;
else if(x_cnt == H_TOTAL-1) x_cnt <= 11'd0;
else cnt <= x_cnt+1'b1;
always @ (posedge clk or negedge rst_n)
if(!rst_n) y_cnt <= 11'd0;
else if(y_cnt == V_TOTAL-1) y_cnt <= 11'd0;
else if(x_cnt == H_TOTAL-1) y_cnt <= y_cnt+1'b1;
//--------------------------------------------------
// VGA场同步,行同步信号
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 == H_FRONT-1) hsync_r <= 1'b1;
always @ (posedge clk or negedge rst_n)
if(!rst_n) vsync_r <= 1'b1;
else if(y_cnt == 11'd0) vsync_r <= 1'b0; //产生vsync信号
else if(y_cnt == V_FRONT-1) vsync_r <= 1'b1;
assign hsync = hsync_r;
assign vsync = vsync_r;
//--------------------------------------------------
//有效显示标志位产生
wire valid; //有效显示区标志
assign valid = (x_cnt >= H_VALID) && (x_cnt <= H_VALID+H_ACT)
&& (y_cnt >= V_VALID) && (y_cnt <= V_VALID+V_ACT);
//--------------------------------------------------
wire[10:0] x_dis,y_dis; //有效显示区坐标
assign x_dis = x_cnt-H_VALID;
assign y_dis = y_cnt-V_VALID;
//--------------------------------------------------
// VGA色彩信号产生
/*RGB = 000 黑色 RGB = 100 红色
= 001 蓝色 = 101 紫色
= 010 绿色 = 110 黄色
= 011 青色 = 111 白色
一共1440*900个像素点,需要显示256(2^8)种颜色;
那么每个颜色显示区域为90*56.25,就正好。*/
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'd56) vga_rgb <= 8'd0;//0000_0000
else if(y_dis >= 10'd56 && y_dis < 10'd113) vga_rgb <= 8'd16;//0001_0000
else if(y_dis >= 10'd113 && y_dis < 10'd169) vga_rgb <= 8'd32;//0010_0000
else if(y_dis >= 10'd169 && y_dis < 10'd225) vga_rgb <= 8'd48;//0100_0000
else if(y_dis >= 10'd225 && y_dis < 10'd281) vga_rgb <= 8'd64;//1000_0000
else if(y_dis >= 10'd281 && y_dis < 10'd338) vga_rgb <= 8'd80;
else if(y_dis >= 10'd338 && y_dis < 10'd394) vga_rgb <= 8'd96;
else if(y_dis >= 10'd394 && y_dis < 10'd450) vga_rgb <= 8'd112;
else if(y_dis >= 10'd450 && y_dis < 10'd506) vga_rgb <= 8'd128;
else if(y_dis >= 10'd506 && y_dis < 10'd563) vga_rgb <= 8'd144;
else if(y_dis >= 10'd563 && y_dis < 10'd619) vga_rgb <= 8'd160;
else if(y_dis >= 10'd619 && y_dis < 10'd675) vga_rgb <= 8'd176;
else if(y_dis >= 10'd675 && y_dis < 10'd731) vga_rgb <= 8'd192;
else if(y_dis >= 10'd731 && y_dis < 10'd788) vga_rgb <= 8'd208;
else if(y_dis >= 10'd788 && y_dis < 10'd844) vga_rgb <= 8'd224;
else vga_rgb <= 8'd240; //剩下的450-480为vga_rgb <= 8'd240
end
10'd90,10'd180,10'd270,10'd360,10'd450,10'd540,10'd630,10'd720,10'd810,10'd900,
10'd990,10'd1080,10'd1170,10'd1260,10'd1350,10'd1440: 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
文章评论(0条评论)
登录后参与讨论