基于FPGA的VGA协议实现


一、VGA介绍

VGA(Video Graphics Array)视频图形阵列是IBM于1987年提出的一个使用模拟信号的电脑显示标准。VGA接口即电脑采用VGA标准输出数据的专用接口。VGA接口共有15针,分成3排,每排5个孔,显卡上应用最为广泛的接口类型,绝大多数显卡都带有此种接口。它传输红、绿、蓝模拟信号以及同步信号(水平和垂直信号)。

VGA驱动显示器用的是扫描的方式,一般是逐行扫描。
逐行扫描是扫描从屏幕左上角一点开始,从左像右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间,CRT对电子束进行消隐,每行结束时,用行同步信号进行同步;
当扫描完所有的行,形成一帧后,用场同步信号进行场同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。
以下是vs 和 hs的时序简图。

在这里插入图片描述
可以看出,VGA一直在扫描,每一场的扫描包括了若干行扫描,如此循环。

综上我们可以知道,一个标准的VGA接口应该有以下的端口:

红色信号 r
绿色信号 g
蓝色信号 b
行同步信号 hs
场同步信号 vs
以及很多的地屏蔽

管脚定义:

管脚 定义
1 红基色
2 绿基色
3 蓝基色
4 地址码 ID Bit
5 自测试
6 红地
7 绿地
8 蓝地
9 保留(各家定义不同)
10 数字码
11 地址码
12 地址码
13 行同步
14 场同步
15 地址码(各家定义不同)

二、VGA显示彩色条纹

首先,VGA需要25M的时钟:

module clk_25M_get(
  input   wire          clk           , //VGA时
  input   wire          rst_n         , //复位
  output  reg         clk_25M         
);

always @(posedge clk or negedge rst_n) begin
     if (!rst_n) begin
         clk_25M <= 1'b0     ; 
     end 
     else  begin
         clk_25M <=  ~clk_25M;
     end 
end
endmodule

屏幕相关信息定义:

`define vga_640_480

`ifdef vga_640_480
    `define H_Right_Border   8
    `define H_Front_Porch    8
    `define H_Sync_Time      96
    `define H_Back_Porch     40
    `define H_Left_Border    8
    `define H_Data_Time      640
    `define H_Total_Time     800

    `define V_Bottom_Border   8
    `define V_Front_Porch    2
    `define V_Sync_Time      2
    `define V_Back_Porch     25
    `define V_Top_Border     8
    `define V_Data_Time      480
    `define V_Total_Time     525


`elsif vga_1920_1080
    `define H_Right_Border    0
    `define H_Front_Porch    88
    `define H_Sync_Time      44
    `define H_Back_Porch     148
    `define H_Left_Border    0
    `define H_Data_Time      1920
    `define H_Total_Time     2200

    `define V_Bottom_Border   0
    `define V_Front_Porch    4
    `define V_Sync_Time      5
    `define V_Back_Porch     36
    `define V_Top_Border     0
    `define V_Data_Time      1080
    `define V_Total_Time     1125    



`elsif vga_800_480
    `define H_Right_Border   0
    `define H_Front_Porch    40
    `define H_Sync_Time      128
    `define H_Back_Porch     88
    `define H_Left_Border    0
    `define H_Data_Time      800
    `define H_Total_Time     1056

    `define V_Bottom_Border  8
    `define V_Front_Porch    2
    `define V_Sync_Time      2
    `define V_Back_Porch     25
    `define V_Top_Border     8
    `define V_Data_Time      480
    `define V_Total_Time     525


`elsif vga_800_600
    `define H_Right_Border   0
    `define H_Front_Porch    40
    `define H_Sync_Time      128
    `define H_Back_Porch     88
    `define H_Left_Border    0
    `define H_Data_Time      800
    `define H_Total_Time     1056

    `define V_Bottom_Border  0
    `define V_Front_Porch    1
    `define V_Sync_Time      4
    `define V_Back_Porch     23
    `define V_Top_Border     0
    `define V_Data_Time      600
    `define V_Total_Time     628


`elsif vga_1024_600
    `define H_Right_Border   0
    `define H_Front_Porch    24
    `define H_Sync_Time      136
    `define H_Back_Porch     160
    `define H_Left_Border    0
    `define H_Data_Time      1024
    `define H_Total_Time     1344

    `define V_Bottom_Border  0
    `define V_Front_Porch    1
    `define V_Sync_Time      4
    `define V_Back_Porch     23
    `define V_Top_Border     0
    `define V_Data_Time      600
    `define V_Total_Time     628


`elsif vga_1024_768
    `define H_Right_Border   0
    `define H_Front_Porch    24
    `define H_Sync_Time      136
    `define H_Back_Porch     160
    `define H_Left_Border    0
    `define H_Data_Time      1024
    `define H_Total_Time     1344

    `define V_Bottom_Border  0
    `define V_Front_Porch    3
    `define V_Sync_Time      6
    `define V_Back_Porch     29
    `define V_Top_Border     0
    `define V_Data_Time      768
    `define V_Total_Time     806


`elsif vga_1280_720
    `define H_Right_Border   0
    `define H_Front_Porch    110
    `define H_Sync_Time      40
    `define H_Back_Porch     220
    `define H_Left_Border    0
    `define H_Data_Time      1280
    `define H_Total_Time     1650

    `define V_Bottom_Border  0
    `define V_Front_Porch    5
    `define V_Sync_Time      5
    `define V_Back_Porch     20
    `define V_Top_Border     0
    `define V_Data_Time      720
    `define V_Total_Time     750

`else



`endif

vga_ctrl.v


`include "vga_param.v"
// `define vga_640_480
// `define vga_1920_1080



/**
 *
 * VGA控制模块
*/
module vga_ctrl(
    input   wire            clk         ,
    input   wire            rst_n       ,
    input   wire [23:0]     data_display,   // 要显示的数据

    output  reg [10:0]      h_addr      ,   // 行地址--数据有效显示区域行地址
    output  reg [10:0]      v_addr      ,   // 场地址--数据有效显示区域场地址
    
    output  reg             hsync       ,
    output  reg             vsync       ,
    output  reg [7:0]       vga_r       ,    // R
    output  reg [7:0]       vga_g       ,    // G
    output  reg [7:0]       vga_b       ,    // B
    // output  wire            vga_sync_n  ,
    output  reg             vga_black   ,
    output  wire            vga_clk          // 时钟
);

    
    parameter           H_SYNC_START = 1;                        // 行同步开始
    parameter           H_SYNC_STOP  = `H_Sync_Time;         // 行同步结束
    parameter           H_DATA_START = `H_Sync_Time + `H_Back_Porch + `H_Left_Border; 
    parameter           H_DATA_STOP  = `H_Sync_Time + `H_Back_Porch + `H_Left_Border + `H_Data_Time;
    
    parameter           V_SYNC_START = 1;                        // 场同步开始
    parameter           V_SYNC_STOP  = `V_Sync_Time;         // 场同步结束
    parameter           V_DATA_START = `V_Sync_Time + `V_Back_Porch + `V_Top_Border; 
    parameter           V_DATA_STOP  = `V_Sync_Time + `V_Back_Porch + `V_Top_Border + `V_Data_Time;


    // parameter           V_BLANK      = `V_Total_Time;        //场空白信号总周期长
    // parameter           H_BLANK      = `H_Total_Time;        //场空白信号总周期长



    reg     [11:0]      cnt_h_addr;   // 行地址计数器
    wire                add_h_addr;
    wire                end_h_addr;

    reg     [11:0]      cnt_v_addr;   // 场地址计数器
    wire                add_v_addr;
    wire                end_v_addr;



// 行地址计数
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cnt_h_addr <= 12'd0;
        end

        else if (add_h_addr) begin
            if (end_h_addr)
                cnt_h_addr <= 12'd0;
            else
                cnt_h_addr <= cnt_h_addr + 1'b1;
        end

        else begin
            cnt_h_addr <= 12'd0;
        end
    end
    assign add_h_addr = 1'b1;
    assign end_h_addr = ((cnt_h_addr>=`H_Total_Time-1) && add_h_addr);


// 场地址计数
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            cnt_v_addr <= 12'd0;
        end

        else if (add_v_addr) begin
            if (end_v_addr)
                cnt_v_addr <= 12'd0;
            else
                cnt_v_addr <= cnt_v_addr + 1'b1;
        end

        else begin
            cnt_v_addr <= cnt_v_addr;
        end
    end
    assign add_v_addr = end_h_addr;
    assign end_v_addr = ((cnt_v_addr>=`V_Total_Time-1) && add_v_addr);


    // always @(posedge clk or negedge rst_n) begin
    //     if (!rst_n) begin
    //     end
    //
    //     else if (add_v_addr) begin
    //     end
    //
    //     else begin
    //     end
    // end


    // assign vga_sync_n = 1'b0; //符合同步控制信号      行时序和场时序都要产生同步脉冲
    //assign vga_black  = ~((cnt_h_addr < H_BLANK) || (cnt_v_addr < V_BLANK));  //当行计数器小于行空白总长或场计数器小于场空白总长时,空白信号低电平


// 行同步信号  低有效
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            hsync <= 1'b1;
        end
    
        else if (cnt_h_addr == H_SYNC_START - 1) begin  // 行同步开始
            hsync <= 1'b0;
        end

        else if (cnt_h_addr == H_SYNC_STOP - 1) begin   // 行同步结束
            hsync <= 1'b1;
        end
    
        else begin
            hsync <= hsync;
        end
    end


// 场同步信号  低有效
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            vsync <= 1'b1;
        end
    
        else if (cnt_v_addr == V_SYNC_START - 1) begin
            vsync <= 1'b0;
        end

        else if (cnt_v_addr == V_SYNC_STOP - 1) begin
            vsync <= 1'b1;
        end
    
        else begin
            vsync <= vsync;
        end
    end



    assign vga_clk = clk;


// 数据有效显示区域定义
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            h_addr <= 11'd0;
        end
    
        else if ((cnt_h_addr >= (H_DATA_START - 1)) && (cnt_h_addr <= H_DATA_STOP)) begin
            h_addr <= cnt_h_addr - H_DATA_START - 1;  // 总的 减去 前面的多余部分
        end
    
        else begin
            h_addr <= 11'd0;
        end
    end


// 数据有效显示区域定义
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            v_addr <= 11'd0;
        end
    
        else if ((cnt_v_addr >= (V_DATA_START - 1)) && (cnt_v_addr <= V_DATA_STOP)) begin
            v_addr <= cnt_v_addr - V_DATA_START - 1;
        end
    
        else begin
            v_addr <= 11'd0;
        end
    end


// 显示数据
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            vga_r <= 8'd0;
            vga_g <= 8'd0;
            vga_b <= 8'd0;
        end
    
        // 在显示数据范围内
        else if (  ((cnt_h_addr >= (H_DATA_START - 1)) && (cnt_h_addr <= H_DATA_STOP)) && 
                    ((cnt_v_addr >= (V_DATA_START - 1)) && (cnt_v_addr <= V_DATA_STOP))  ) begin
            vga_r <= data_display[23:16];
            vga_g <= data_display[15:8];
            vga_b <= data_display[7:0];
            vga_black <= 1'b1;
        end
    
        else begin
            vga_r <= 8'd0;
            vga_g <= 8'd0; 
            vga_b <= 8'd0;
            vga_black <= 1'b0;
        end
    end




endmodule

vga_generate.v

module data_generate(
    input   wire            clk         ,
    input   wire            rst_n       ,

    input   wire [10:0]     h_addr      ,   // 行地址--数据有效显示区域行地址
    input   wire [10:0]     v_addr      ,   // 场地址--数据有效显示区域场地址

    output  reg [23:0]      data_display   // 要显示的数据
);


    parameter 
        BLACK    = 24'h000000,
        RED      = 24'hFF0000,
        GREEN    = 24'h00FF00,
        BLUE     = 24'h0000FF,
        YELLOW   = 24'hFFFF00,
        CYANRAY  = 24'h00FFFF,
        PURPLE   = 24'hFF00FF,
        GRAY     = 24'hC0C0C0,
        WHITE    = 24'hFFFFFF;





    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            data_display <= WHITE;
        end

        else begin
            case (h_addr)
                0:          data_display <= BLACK  ;
                80:         data_display <= RED    ;
                160:        data_display <= GREEN  ;
                240:        data_display <= BLUE   ;
                320:        data_display <= YELLOW ;
                400:        data_display <= CYANRAY;
                480:        data_display <= PURPLE ;
                560:        data_display <= GRAY   ;
                default:    data_display <= data_display;
            endcase
        end

    end


endmodule

顶层文件vga_top.v

/**
 *
 * 顶层文件
*/

module vga_top(
    input   wire        clk,
    input   wire        rst_n,

    output  wire             hsync       ,
    output  wire             vsync       ,
    output  wire [7:0]       vga_r       ,
    output  wire [7:0]       vga_g       ,
    output  wire [7:0]       vga_b       ,
    // output  wire             vga_sync_n  ,
    output  wire             vga_black   ,
    output  wire             vga_clk      
);

    wire [23:0]     data_display;   // 要显示的数据

    wire [10:0]     h_addr      ;   // 行地址--数据有效显示区域行地
    wire [10:0]     v_addr      ;   // 场地址--数据有效显示区域场地

    
    wire    clk_25M;

     clk_25M_get u_clk_25M_get(
         .clk           (clk    ), //VGA时
         .rst_n         (rst_n  ), //复位
         .clk_25M       (clk_25M)  
     );



     data_generate u_data_generate(
         /*input   wire        */    .clk            (clk_25M      ),
         /*input   wire        */    .rst_n          (rst_n        ),

         /*input   wire [10:0] */    .h_addr         (h_addr       ),   // 行地址--数据有效显示区域行地址
         /*input   wire [10:0] */    .v_addr         (v_addr       ),   // 场地址--数据有效显示区域场地址

         /*output  wire [23:0] */    .data_display   (data_display )    // 要显示的数据
     );![请添加图片描述](https://img-blog.csdnimg.cn/1660334f7ecd4160b71c835ce6129c95.png)


    // 显示字符
//    data_gen_char u_data_gen_char(
//        /*input   wire        */    .clk            (clk_25M      ),
//        /*input   wire        */    .rst_n          (rst_n        ),

//        /*input   wire [10:0] */    .h_addr         (h_addr       ),   // 行地址--数据有效显示区域行地址
//        /*input   wire [10:0] */    .v_addr         (v_addr       ),   // 场地址--数据有效显示区域场地址

//        /*output  wire [23:0] */    .data_display   (data_display )    // 要显示的数据
    );



    vga_ctrl u_vga_ctrl(
        /*input   wire       */     .clk            (clk_25M     ),
        /*input   wire       */     .rst_n          (rst_n       ),
        /*input   wire [23:0]*/     .data_display   (data_display),   // 要显示的数据
        
        /*output  wire [10:0]*/     .h_addr         (h_addr      ),   // 行地址--数据有效显示区域行地址
        /*output  wire [10:0]*/     .v_addr         (v_addr      ),   // 场地址--数据有效显示区域场地址
        
        /*output  reg        */     .hsync          (hsync       ),
        /*output  reg        */     .vsync          (vsync       ),
        /*output  reg [7:0]  */     .vga_r          (vga_r       ),    // R
        /*output  reg [7:0]  */     .vga_g          (vga_g       ),    // G
        /*output  reg [7:0]  */     .vga_b          (vga_b       ),    // B
                                    // .vga_sync_n     (vga_sync_n  ),
                                    .vga_black      (vga_black   ),
        /*output  wire       */     .vga_clk        (vga_clk     )  // 时钟
    );



endmodule

运行效果:
请添加图片描述



三、VGA显示字符

只需替换data_generate.v文件:

`include "vga_param.v"
module data_gen_char(
    input   wire            clk         ,
    input   wire            rst_n       ,

    input   wire [10:0]     h_addr      ,   // 行地址--数据有效显示区域行地址
    input   wire [10:0]     v_addr      ,   // 场地址--数据有效显示区域场地址

    output  reg [23:0]      data_display   // 要显示的数据
);


    parameter        WIDTH_LEN      = 64;   // 字符总长度
    parameter        HEIGHT_LEN     = 16;   // 字符总高度

    parameter        WIDTH_REMAIN   = (`H_Data_Time - WIDTH_LEN) / 2;    //两边应该留的宽度
    parameter        HEIGHT_REMAIN  = (`V_Data_Time - HEIGHT_LEN) / 2;    //上下应该留的高度 232 

    // 每一行应该显示的数据(bit为1则显示)
    reg   [63:0]     char_lines [15:0];

    reg  [4:0]       now_line;       // 当前为字符的第几行,0为不在
    wire             in_charline;    // 在字符行
    wire             in_charcolumn;  // 在字符列
    
    reg  [6:0]       now_column;      // 当前为字符的第几列

    // 颜色
    parameter 
        BLACK    = 24'h000000,
        RED      = 24'hFF0000,
        GREEN    = 24'h00FF00,
        BLUE     = 24'h0000FF,
        YELLOW   = 24'hFFFF00,
        CYANRAY  = 24'h00FFFF,
        PURPLE   = 24'hFF00FF,
        GRAY     = 24'hC0C0C0,
        WHITE    = 24'hFFFFFF;


// 字符数据
    always @(*) begin
        char_lines[0 ]    = 64'h0040_0000_0000_0200;
        char_lines[1 ]    = 64'h2040_00FC_FFFE_0200;
        char_lines[2 ]    = 64'h17FC_7C84_0100_0200;
        char_lines[3 ]    = 64'h1040_4484_0100_0200;
        char_lines[4 ]    = 64'h83F8_4484_0100_0200;
        char_lines[5 ]    = 64'h4040_44FC_7FFC_0200;
        char_lines[6 ]    = 64'h47FE_7C84_4104_03F8;
        char_lines[7 ]    = 64'h1000_4484_4104_0200;
        char_lines[8 ]    = 64'h13F8_4484_4944_0200;
        char_lines[9 ]    = 64'h2208_44FC_4524_0200;
        char_lines[10]    = 64'hE3F8_7C84_4104_0200;
        char_lines[11]    = 64'h2208_4484_4944_0200;
        char_lines[12]    = 64'h23F8_0104_4524_0200;
        char_lines[13]    = 64'h2208_0104_4104_0200;
        char_lines[14]    = 64'h2228_0214_4114_FEFE;
        char_lines[15]    = 64'h0210_0408_4008_0000;
    end


// 字符第几行的判定
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            now_line <= 5'd0;
        end
    
        else if (in_charline && in_charcolumn) begin  // 在字符范围内
            now_line <= v_addr - HEIGHT_REMAIN + 1;
        end
    
        else begin
            now_line <= 5'd0;
        end
    end

    // 在字符行、列内
    assign in_charcolumn    = ((h_addr >= WIDTH_REMAIN)  && (h_addr < WIDTH_REMAIN  + WIDTH_LEN))  ;
    assign in_charline      = ((v_addr >= HEIGHT_REMAIN) && (v_addr < HEIGHT_REMAIN + HEIGHT_LEN)) ;


// 字符第几列的判定
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            now_column <= 7'd0;
        end
    
        else if (in_charline && in_charcolumn) begin  // 在字符范围内
            now_column <= h_addr - WIDTH_REMAIN;
        end
    
        else begin
            now_column <= 7'd0;
        end
    end


    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            data_display <= WHITE;
        end
    
        else if (now_line != 5'd0 && now_column != 7'd0) begin  // 在字符范围内
            if (char_lines[now_line-1][WIDTH_LEN - now_column]) begin
                // data_display <= {$random};
                data_display <= CYANRAY;
            end
            
            else begin
                data_display <= BLACK;
            end
        end

        else begin
            data_display <= BLACK;
        end 

    end


endmodule

显示效果:

请添加图片描述



三、VGA显示图像

将bmp文件转换为mif文件:
在这里插入图片描述

在这里插入图片描述

将生成的mif文件保存在ROM中。此时我们的ROM的位宽度为16位,深度的设置一定要大于图片的大小就行:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述


data_drive.v:

module data_drive (
    input			wire						vga_clk,
    input			wire						rst_n,
    input			wire		[ 10:0 ]		addr_h,
    input			wire		[ 10:0 ]		addr_v,
    output			reg		    [ 15:0 ]		rgb_data
);

localparam	black  = 16'd0;

parameter	height = 209; // 图片高度
parameter	width  = 102; // 图片宽度

reg			[ 20:0 ]		rom_address				; // ROM地址
wire		[ 20:0 ]		rom_data				; // 图片数据

wire						flag_enable_out2			; // 图片有效区域
wire						flag_clear_rom_address		; // 地址清零
wire						flag_begin_h			    ; // 图片显示行
wire						flag_begin_v			    ; // 图片显示列


always @( posedge vga_clk or negedge rst_n) begin
    if(!rst_n)begin
        rgb_data = black;
    end
    else if ( flag_enable_out2 ) begin
        rgb_data = rom_data;
    end
    else begin
        rgb_data = black;
    end
end

//ROM地址计数器
always @( posedge vga_clk or negedge rst_n ) begin
    if ( !rst_n ) begin
        rom_address <= 0;
    end
    else if ( flag_clear_rom_address ) begin //计数满清零
        rom_address <= 0;
    end
        else if ( flag_enable_out2 ) begin  //在有效区域内+1
        rom_address <= rom_address + 1;
        end
    else begin  //无效区域保持
        rom_address <= rom_address;
    end
end
assign flag_clear_rom_address = rom_address == height * width - 1;
assign flag_begin_h     = addr_h > ( ( 640 - width ) / 2 ) && addr_h < ( ( 640 - width ) / 2 ) + width + 1;
assign flag_begin_v     = addr_v > ( ( 480 - height )/2 ) && addr_v <( ( 480 - height )/2 ) + height + 1;
assign flag_enable_out2 = flag_begin_h && flag_begin_v;

//实例化ROM
rom_mif	rom_inst (
.address    ( rom_address   ),
.clock      ( vga_clk       ),
.q          ( rom_data      )
);

endmodule

修改顶层文件:

/**
 *
 * 顶层文件
*/

module vga_top(
    input   wire        clk,
    input   wire        rst_n,

    output  wire             hsync       ,
    output  wire             vsync       ,
    output  wire [7:0]       vga_r       ,
    output  wire [7:0]       vga_g       ,
    output  wire [7:0]       vga_b       ,
    // output  wire             vga_sync_n  ,
    output  wire             vga_black   ,
    output  wire             vga_clk      
);

    wire [23:0]     data_display;   // 要显示的数据

    wire [10:0]     h_addr      ;   // 行地址--数据有效显示区域行地
    wire [10:0]     v_addr      ;   // 场地址--数据有效显示区域场地

    
    wire    clk_25M;

     clk_25M_get u_clk_25M_get(
         .clk           (clk    ), //VGA时
         .rst_n         (rst_n  ), //复位
         .clk_25M       (clk_25M)  
     );




    // data_generate u_data_generate(
    //     /*input   wire        */    .clk            (clk_25M      ),
    //     /*input   wire        */    .rst_n          (rst_n        ),

    //     /*input   wire [10:0] */    .h_addr         (h_addr       ),   // 行地址--数据有效显示区域行地址
    //     /*input   wire [10:0] */    .v_addr         (v_addr       ),   // 场地址--数据有效显示区域场地址

    //     /*output  wire [23:0] */    .data_display   (data_display )    // 要显示的数据
    // );

    // 显示字符
    // data_gen_char u_data_gen_char(
    //     /*input   wire        */    .clk            (clk_25M      ),
    //     /*input   wire        */    .rst_n          (rst_n        ),

    //     /*input   wire [10:0] */    .h_addr         (h_addr       ),   // 行地址--数据有效显示区域行地址
    //     /*input   wire [10:0] */    .v_addr         (v_addr       ),   // 场地址--数据有效显示区域场地址

    //     /*output  wire [23:0] */    .data_display   (data_display )    // 要显示的数据
    // );

    data_drive u_data_drive(
        .vga_clk            (clk_25M),
        .rst_n              (rst_n),
        .addr_h             (h_addr),    
        .addr_v             (v_addr),
        .rgb_data           (data_display)
    );




    vga_ctrl u_vga_ctrl(
        /*input   wire       */     .clk            (clk_25M     ),
        /*input   wire       */     .rst_n          (rst_n       ),
        /*input   wire [23:0]*/     .data_display   (data_display),   // 要显示的数据
        
        /*output  wire [10:0]*/     .h_addr         (h_addr      ),   // 行地址--数据有效显示区域行地址
        /*output  wire [10:0]*/     .v_addr         (v_addr      ),   // 场地址--数据有效显示区域场地址
        
        /*output  reg        */     .hsync          (hsync       ),
        /*output  reg        */     .vsync          (vsync       ),
        /*output  reg [7:0]  */     .vga_r          (vga_r       ),    // R
        /*output  reg [7:0]  */     .vga_g          (vga_g       ),    // G
        /*output  reg [7:0]  */     .vga_b          (vga_b       ),    // B
                                    // .vga_sync_n     (vga_sync_n  ),
                                    .vga_black      (vga_black   ),
        /*output  wire       */     .vga_clk        (vga_clk     )  // 时钟
    );

endmodule

显示:
请添加图片描述



参考

【FPGA实验】基于DE2-115平台的VGA显示

fpga控制vga显示彩色图片

猜你喜欢

转载自blog.csdn.net/weixin_46628481/article/details/125226689