"); //-->
空里找闲,继续实验了VGA功能。
电路很简单,就是几个电阻。关于VGA的知识上网学习了下。
参考:
http://www.tinyvga.com/vga-timing/800x600@72Hz
http://bbs.****.com/BLOG_ARTICLE_184836.HTM
实验内容:
显示800x600分辨率,72Hz刷新,时钟50MHz。用示波器测试,都符合。
屏幕分成8x6块,每块100x100。RGB三色中红色用行计数,绿色用场计数,蓝色是1s变化一次
module m_vga(clk, rst, hsync, vsync, vga_r, vga_g, vga_b);
input clk; //系统时钟输入,50MHz,0.02us
input rst; //系统复位输入
output hsync; //行同步输出,48kHz
output vsync; //场同步输出,72Hz
reg hsync, vsync;
output[2:0] vga_r; //RGB信号输出
output[2:0] vga_g;
output[1:0] vga_b;
reg[10:0] pixel; //行向时序,1040像素
reg[9:0] line; //场向时序,666行
//行向时序
always @(posedge clk or negedge rst)
begin
if(rst == 0) pixel <= 11'd0;
else if(pixel == 11'd1040) pixel <= 11'd0;
else pixel <= pixel + 1'b1;
end
//场向时序
always @(posedge clk or negedge rst)
begin
if(rst == 0) line <= 10'd0;
else if(line == 10'd666) line <= 10'd0;
else if(pixel == 11'd1040) line <= line + 1'b1;
end
//hsync信号(行同步),vsync信号(场同步)
always @(posedge clk or negedge rst)
begin
if (rst == 0)
begin
hsync <= 1'b0;
vsync <= 1'b0;
end
else
begin
hsync <= pixel >= 11'd120;
vsync <= line >= 10'd6;
end
end
reg[2:0] xpos;
reg[2:0] ypos;
parameter
Left = 120 + 64,
PixelWidth = 100,
Top = 6 + 23;
//计算8x6色块行地址
always @(posedge clk or negedge rst)
begin
if(rst == 0) xpos <= 3'b000;
else if(pixel >= Left && pixel < Left + PixelWidth) xpos <= 3'b000;
else if(pixel >= Left + PixelWidth && pixel < Left + 2 * PixelWidth) xpos <= 3'b001;
else if(pixel >= Left + 2 * PixelWidth && pixel < Left + 3 * PixelWidth) xpos <= 3'b010;
else if(pixel >= Left + 3 * PixelWidth && pixel < Left + 4 * PixelWidth) xpos <= 3'b011;
else if(pixel >= Left + 4 * PixelWidth && pixel < Left + 5 * PixelWidth) xpos <= 3'b100;
else if(pixel >= Left + 5 * PixelWidth && pixel < Left + 6 * PixelWidth) xpos <= 3'b101;
else if(pixel >= Left + 6 * PixelWidth && pixel < Left + 7 * PixelWidth) xpos <= 3'b110;
else if(pixel >= Left + 7 * PixelWidth && pixel < Left + 8 * PixelWidth) xpos <= 3'b111;
else xpos <= 3'b000;
end
//计算8x6色块场地址
always @(posedge clk or negedge rst)
begin
if(rst == 0) ypos <= 3'b000;
else if(line >= Top && line < Top + PixelWidth) ypos <= 3'b000;
else if(line >= Top + PixelWidth && line < Top + 2 * PixelWidth) ypos <= 3'b001;
else if(line >= Top + 2 * PixelWidth && line < Top + 3 * PixelWidth) ypos <= 3'b010;
else if(line >= Top + 3 * PixelWidth && line < Top + 4 * PixelWidth) ypos <= 3'b011;
else if(line >= Top + 4 * PixelWidth && line < Top + 5 * PixelWidth) ypos <= 3'b100;
else if(line >= Top + 5 * PixelWidth && line < Top + 6 * PixelWidth) ypos <= 3'b101;
else ypos <= 3'b110;
end
reg clk1s; //分频时钟
reg[25:0] clk_cnt; //分频计数器
//系统时钟分频,产生1s的时钟
always @(posedge clk)
begin
if(clk_cnt == 25'd25000000)
begin
clk1s = ~clk1s;
clk_cnt = 0;
end
else
begin
clk_cnt = clk_cnt + 1'b1;
end
end
reg[1:0] color_cnt;
//每1s改变蓝色
always @(posedge clk1s or negedge rst)
begin
if(rst == 0)
color_cnt = 2'b00;
else
color_cnt <= color_cnt + 1'b1;
end
wire[7:0] color;
reg [7:0] color_r;
always @(posedge clk or negedge rst)
begin
if(rst == 0)
begin
color_r = 8'b00000000;
end
else
begin
color_r <= { xpos, ypos, color_cnt }; //红色+绿色+蓝色
end
end
assign color = color_r;
//显示区标志
wire valid;
assign valid = (pixel > 10'd184) && (pixel < 10'd984) && (line > 10'd29) && (line < 10'd629);
//颜色输出
assign vga_r[2] = valid ? color[7] : 1'b0;
assign vga_r[1] = valid ? color[6] : 1'b0;
assign vga_r[0] = valid ? color[5] : 1'b0;
assign vga_g[2] = valid ? color[4] : 1'b0;
assign vga_g[1] = valid ? color[3] : 1'b0;
assign vga_g[0] = valid ? color[2] : 1'b0;
assign vga_b[1] = valid ? color[1] : 1'b0;
assign vga_b[0] = valid ? color[0] : 1'b0;
endmodule
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。