目录
一、任务
使用VGA实现彩条显示,模式是640x480@60。
二、分析
首先,模式是640x480@60,那么对照以下图标,知道其它信息,不清楚时序和VGA扫描方式的可以看看这个FPGA学习笔记——VGA简介-CSDN博客,那么对行同步信号,在有效图像里面对640进行分块(我这里是分成10块)。
那么,在写代码的时候应该先配置好PLL IP核,模式的时钟频率是25.175MHz,我这里使用的时钟是50MHz,所以我对它二分频得到25MHz的时钟,然后,对常量进行定义,再对应的有效图像里面对颜色进行赋值。
PLL IP核配置
三、代码
top.v
module top (
input wire clk ,
input wire rst_n ,
output wire [15:0] data_rgb ,
output wire Hsync ,
output wire Vsync
);
//vga
wire De;
wire [9:0] X;
vga vga_u(
. pclk (pclk ) ,
. rst_n (locked) ,
. De (De ) , //数据有效信号
. X (X ) ,
. Hsync (Hsync ) , //行同步信号
. Vsync (Vsync ) //场同步信号
);
data data_u(
. clk (pclk ) ,
. rst_n (locked ) ,
. X (X ) ,
. De (De ) ,
. data_rgb (data_rgb )
);
wire pclk;
wire locked;
pll pll_inst (
.areset ( !rst_n ),
.inclk0 ( clk ),
.c0 ( pclk ),
.locked ( locked )
);
endmodule
vga.v
module vga (
input wire pclk ,
input wire rst_n ,
output wire [9:0] X ,
output wire De , //数据有效信号
output wire Hsync , //行同步信号
output wire Vsync //场同步信号
);
localparam H_Total = 800 ,//行总像素点
H_Addr = 640 ,//有效像素点
H_Right = 8 ,//右边框
H_Front = 8 ,//前沿
H_Sync = 96 , //同步
H_Back = 40 , //后沿
H_Left = 8 ;//左边框
localparam V_Total = 525 ,//场总像素点
V_Addr = 480 ,//有效像素点
V_Bottom = 8 ,//底边框
V_Front = 2 ,//前沿
V_Sync = 2 , //同步
V_Back = 25 , //后沿
V_Top = 8 ; //上边框
reg [9:0] cnt_h,cnt_v;
//行周期计数
always @(posedge pclk) begin
if(!rst_n)
cnt_h <= 0;
else if( cnt_h == H_Total - 1 )
cnt_h <= 0;
else
cnt_h <= cnt_h + 1;
end
//场周期计数
always @(posedge pclk) begin
if(!rst_n)
cnt_v <= 0;
else if( cnt_h == H_Total - 1 ) begin
if( cnt_v == V_Total - 1 )
cnt_v <= 0;
else
cnt_v <= cnt_v + 1;
end
else
cnt_v <= cnt_v;
end
//行场同步信号
assign Hsync = (cnt_h < H_Sync ) ? 1 : 0;
assign Vsync = (cnt_v < V_Sync ) ? 1 : 0;
assign De = ((cnt_h > H_Sync + H_Back + H_Left - 1) &&
(cnt_h < H_Sync + H_Back + H_Left + H_Addr) &&
(cnt_v >= V_Sync + V_Back + V_Top ) &&
(cnt_v < V_Sync + V_Back + V_Top + V_Addr) ) ? 1 : 0;
assign X = (De == 1) ? (cnt_h - H_Sync - H_Back - H_Left) : 0 ;
endmodule
data.v
module data (
input wire clk ,
input wire rst_n ,
input wire De ,
input wire [9:0] X ,
output wire [15:0] data_rgb
);
reg [15:0] data_reg ;
always @(posedge clk) begin
if(!rst_n)
data_reg <= 0;
else if (X < 64 && De == 1)
data_reg <= 16'hF800;
else if (X < 128 && De == 1)
data_reg <= 16'h07E0;
else if (X < 192 && De == 1)
data_reg <= 16'h001F;
else if (X < 256 && De == 1)
data_reg <= 16'hD700;
else if (X < 320 && De == 1)
data_reg <= 16'h07AF;
else if (X < 384 && De == 1)
data_reg <= 16'hF00F;
else if (X < 448 && De == 1)
data_reg <= 16'hA0F8;
else if (X < 512 && De == 1)
data_reg <= 16'hBCDA;
else if (X < 576 && De == 1)
data_reg <= 16'hCD69;
else if (X < 640 && De == 1)
data_reg <= 16'hFFFF;
else
data_reg <= 0;
end
assign data_rgb = data_reg;
endmodule
四、实验现象
五、更新
针对vga.v代码,想要显示更多的颜色可以使用case语句更好
module data (
input wire clk ,
input wire rst_n ,
input wire De ,
input wire [9:0] X ,
output wire [15:0] data_rgb
);
reg [15:0] data_reg ;
localparam H_Addr = 640 ;//有效像素点
//always @(posedge clk) begin
// if(!rst_n)
// data_reg <= 0;
// else if (X < 64 && De == 1)
// data_reg <= 16'hF800;
// else if (X < 128 && De == 1)
// data_reg <= 16'h07E0;
// else if (X < 192 && De == 1)
// data_reg <= 16'h001F;
// else if (X < 256 && De == 1)
// data_reg <= 16'hD700;
// else if (X < 320 && De == 1)
// data_reg <= 16'h07AF;
// else if (X < 384 && De == 1)
// data_reg <= 16'hF00F;
// else if (X < 448 && De == 1)
// data_reg <= 16'hA0F8;
// else if (X < 512 && De == 1)
// data_reg <= 16'hBCDA;
// else if (X < 576 && De == 1)
// data_reg <= 16'hCD69;
// else if (X < 640 && De == 1)
// data_reg <= 16'hFFFF;
// else
// data_reg <= 0;
//end
//n 份数
//H_Addr/n 颜色宽度
always @(posedge clk) begin
if(!rst_n)
data_reg <= 0;
else if(De) begin
case( X/(H_Addr/5) )
0:data_reg <= 16'hF800;
1:data_reg <= 16'h07E0;
2:data_reg <= 16'hFFFF;
3:data_reg <= 16'hCD69;
4:data_reg <= 16'h07AF;
default:data_reg <= 0;
endcase
end
else
data_reg <= 0;
end
assign data_rgb = data_reg;
endmodule
以上就是VGA彩条显示。(个人想法)