FPGA学习笔记——VGA彩条显示

发布于:2025-08-07 ⋅ 阅读:(13) ⋅ 点赞:(0)

目录

一、任务

二、分析

三、代码

四、实验现象

五、更新


一、任务

使用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彩条显示。(个人想法)


网站公告

今日签到

点亮在社区的每一天
去签到