FPGA学习笔记——VGA彩条显示
目录
一、任务
二、分析
三、代码
四、实验现象
五、更新
一、任务
使用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) beginif(!rst_n)cnt_h <= 0;else if( cnt_h == H_Total - 1 )cnt_h <= 0;elsecnt_h <= cnt_h + 1;
end//场周期计数
always @(posedge pclk) beginif(!rst_n)cnt_v <= 0;else if( cnt_h == H_Total - 1 ) beginif( cnt_v == V_Total - 1 )cnt_v <= 0;elsecnt_v <= cnt_v + 1; endelsecnt_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) beginif(!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;elsedata_reg <= 0;
endassign 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) beginif(!rst_n)data_reg <= 0;else if(De) begincase( 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;endcaseendelsedata_reg <= 0;
endassign data_rgb = data_reg;endmodule
以上就是VGA彩条显示。(个人想法)