VGA显示文字、彩条


一、点阵汉字生成

使用网站:https://www.zhetao.com/fontarray.html
在记事本中整理
请添加图片描述

二、工程建立

1. 引入ip核

在这里插入图片描述在这里插入图片描述
建立过程参考:https://blog.csdn.net/YouthBlood9/article/details/125226768

2.代码实现

vga_param

`define vga_640_480//这里在你使用不同分辨率的时候要改变

//笔主因为老师要求不同分辨率,所以定义两种,其他可自行添加(根据前面的那个分辨率显示参数表格)

`ifdef  vga_640_480
    //执行操作A
    `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_800_600
    //执行操作B
    `define H_Right_Border  0
    `define H_Front_Border  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
`endif 

vga_ctrl

`include "vga_param.v"

module vga_ctrl (
    input   wire              clk         , //vga clk 640*480 25.2MHz
    input   wire              rst_n       , //复位信号
    input   wire   [23:0]     data_disp   , //

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

    output  reg               vsync       , //
    output  reg               hsync       , //

    output  reg    [07:0]     vga_r       , //RGB三色
    output  reg    [07:0]     vga_g       , //
    output  reg    [07:0]     vga_b       , //
    output  reg               vga_blk     , //VGA 消隐信号
    output  wire              vga_clk       //

);
//参数定义
    parameter   H_SYNC_STA = 1 ,//行同步开始信号
                H_SYNC_STO = `H_Sync_Time ,//行同步停止
                H_Data_STA = `H_Sync_Time + `H_Back_Porch + `H_Left_Border,//行数据开始
                H_Data_STO = `H_Sync_Time + `H_Back_Porch + `H_Left_Border + `H_Data_Time ,//行数据开始

                V_SYNC_STA = 1 ,
                V_SYNC_STO = `V_Sync_Time ,
                V_Data_STA = `V_Sync_Time + `V_Back_Porch + `V_Top_Border,
                V_Data_STO = `V_Sync_Time + `V_Back_Porch + `V_Top_Border + `V_Data_Time;

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

    reg     [11:00]     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) begin
                cnt_h_addr <= 12'd0;
            end
            else begin
                cnt_h_addr <= cnt_h_addr + 12'd1;
            end
        end
        else begin
            cnt_h_addr <= cnt_h_addr;
        end
    end

    assign   add_h_addr = 1'b1;
    assign   end_h_addr = add_h_addr && cnt_h_addr >= `H_Total_Time - 1;


//场地址计数器
   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) begin
                cnt_v_addr <= 12'd0;
            end
            else begin
                cnt_v_addr <= cnt_v_addr + 12'd1;
            end
        end
        else begin
            cnt_v_addr <= cnt_v_addr;
        end
    end

    assign   add_v_addr =  end_h_addr;
    assign   end_v_addr = add_v_addr && cnt_v_addr >= `V_Total_Time - 1;


//行场同步信号
//行同步信号
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)begin
            hsync <= 1'b1;
        end
        else if (cnt_h_addr == H_SYNC_STA - 1) begin
            hsync <= 1'b0;
        end
        else if (cnt_h_addr == H_SYNC_STO - 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_STA - 1) begin
            vsync <= 1'b0;
        end
        else if (cnt_v_addr == V_SYNC_STO - 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_STA) && (cnt_h_addr <= H_Data_STO)) begin
            h_addr <= cnt_h_addr - H_Data_STA;
        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_STA) && (cnt_v_addr <= V_Data_STO)) begin
            v_addr <= cnt_v_addr - V_Data_STA;
        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;
            vga_blk <= 1'b0;
        end
        else if ((cnt_h_addr >= H_Data_STA -1) && (cnt_h_addr <= H_Data_STO - 1)
                    && (cnt_v_addr >= V_Data_STA -1 ) && (cnt_v_addr <= V_Data_STO -1)) begin
            vga_r = data_disp[23:16];//data_dis[23-:8]
            vga_g = data_disp[15:08];//data_dis[15-:8]
            vga_b = data_disp[07:00];//data_dis[07-:8]
            vga_blk <= 1'b1;
        end
        else begin
            vga_r <= 8'd0;
            vga_g <= 8'd0;
            vga_b <= 8'd0;
            vga_blk <= 1'b0;
        end
    end
endmodule

data_gen

module data_gen (
    input   wire              clk         , //vga clk 640*480 25.2MHz
    input   wire              rst_n       , //复位信号

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

    output  reg    [23:0]     data_disp     //数据

);

    reg [ 223:0 ] char_line[ 15:0 ];//16*14个字符=224,224*16的字符存储区
//参数定义
    parameter
        BLACK   = 24'h000000,
        RED     = 24'hFF0000,
        GREEN   = 24'h00FF00,
        BLUE    = 24'h0000FF,
        YELLOW  = 24'hFFFF00,
        SKY_BULE= 24'h00FFFF,
        PURPLE  = 24'hFF00FF,
        GRAY    = 24'hC0C0C0,
        WHITE   = 24'hFFFFFF; 
    parameter
        H_VLD   = 640,
        // H_VLD   = 800,
        V_VLD   = 480,
        // V_VLD   = 600,
        
        PIC_W   = 224,
        PIC_H   = 16,

        X_START = (H_VLD - PIC_W >> 1)-1,//正中间
        Y_START = (V_VLD - PIC_H >> 1)- 1;

    reg   [10:00] pix_x,pix_y;//字符显示坐标

//显示区域
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)begin
            pix_x <= 11'd0;
            pix_y <= 11'd0;
        end
        else if ((h_addr >= X_START - 1 && h_addr < X_START + PIC_W)
                && (v_addr >= Y_START && v_addr < Y_START + PIC_H)) begin
            pix_x <= h_addr - X_START;
            pix_y <= v_addr - Y_START;
        end
        else begin
            pix_x = 11'h7FF;
            pix_y = 11'h7FF;
        end
    end
    
//显示颜色
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)begin
            data_disp <= WHITE;
        end
        else if (pix_x != 11'h7FF && pix_y != 11'h7FF) begin
            if (char_line[pix_y][223 - pix_x] == 1'b1) begin
                data_disp <= PURPLE ;
            end
            else begin
                data_disp <= WHITE   ;
            end
        end
        else 
            data_disp <= BLACK;
    end
    
//初始化显示文字
    always@( posedge clk or negedge rst_n ) begin
        if ( !rst_n ) begin//将前面得到的点阵放在这里~
          char_line[ 0 ]  = 224'h10001082002000000000000000000000000000000000000000000000;
          char_line[ 1 ]  = 224'h11f8108200f000000000000000000000000000000000000000000000;
          char_line[ 2 ]  = 224'h101010841f0000000000000000000000000000000000000000000000;
          char_line[ 3 ]  = 224'h1020108810000000000018003c003c00080018007e00180018001800;
          char_line[ 4 ]  = 224'hfc40fbd0100000000000240042004200380024004200240024002400;
          char_line[ 5 ]  = 224'h10107f44400042000800420042000400420040004200420042004200;
          char_line[ 6 ]  = 224'h31fe3082108000000000400002004200080042000400420040004200;
          char_line[ 7 ]  = 224'hc10648545c000400080042004200080042005c004200020002002400;
          char_line[ 8 ]  = 224'h389239c41080000000005c000400020008004200080042005c004200;
          char_line[ 9 ]  = 224'h549255a8108000000000620018000400080042000800420062004200;
          char_line[ 10 ] = 224'h54925290108000000000420004000800080042001000420042004200;
          char_line[ 11 ] = 224'h11105154420042000800020042001000420042004200200020004200;
          char_line[ 12 ] = 224'h91129282fffe00000000420002001000080042001000420042004200;
          char_line[ 13 ] = 224'h11221482000000000000420042002000080042001000420042004200;
          char_line[ 14 ] = 224'h12221084084000000000220042004200080024001000240022002400;
          char_line[ 15 ] = 224'h144210881020000000001c003c007e003e001800100018001c001800;
          char_line[ 15 ] = 224'h10941090201000000000000000000000000000000000000000000000;
          char_line[ 15 ] = 224'h110810a0400800000000000000000000000000000000000000000000;
        end
    end
    
endmodule

vga_top

module vga_top (
    input   wire              clk   ,
    input   wire              rst_n ,

    output  wire              vsync       , //
    output  wire              hsync       , //
    output  wire    [07:00]   vga_r       , //RGB三色
    output  wire    [07:00]   vga_g       , //
    output  wire    [07:00]   vga_b       , //
    output  wire              vga_blk     , //  
    output  wire              vga_clk       //  

);
    wire [23:00] data_disp;
    wire            vga_25;
    wire            vga_40;//60MHz

    wire            locked;  

    wire [10:00] h_addr;
    wire [10:00] v_addr;

    wire            reset;

    assign reset = rst_n & locked;


    // pll	u_pll (
	// .areset ( !rst_n     ),
	// .inclk0 ( clk        ),
	// .c0     ( vga_25    )
	// );

    pll_25	pll_25_inst (
	.areset ( ~rst_n ),
	.inclk0 ( clk ),
	.c0 ( vga_25 ),
    .c1 ( vga_40 ),
	.locked (locked)
	);


    data_gen u_data_gen(
        .clk         (vga_25  ), //vga clk 640*480 25.2MHz
        .rst_n       (reset    ), //复位信号
        .h_addr      (h_addr   ), //数据有效显示区域行地址
        .v_addr      (v_addr   ), //数据有效显示区域场地址

        .data_disp   (data_disp)  //
    );
    vga_ctrl u_vga_ctrl(
        .clk         (vga_25 ), //vga clk 640*480 25.2MHz
        .rst_n       (reset    ), //复位信号
        .data_disp   (data_disp), //
        
        .h_addr      (h_addr   ), //数据有效显示区域行地址
        .v_addr      (v_addr   ), //数据有效显示区域场地址
        .vsync       (vsync    ), //
        .hsync       (hsync    ), //
        .vga_r       (vga_r    ), //RGB三色
        .vga_g       (vga_g    ), //
        .vga_b       (vga_b    ), //
        .vga_blk     (vga_blk  ), //
        .vga_clk     (vga_clk  )  //
    );
endmodule

vga_tb

module vga_top (
    input   wire              clk   ,
    input   wire              rst_n ,

    output  wire              vsync       , //
    output  wire              hsync       , //
    output  wire    [07:00]   vga_r       , //RGB三色
    output  wire    [07:00]   vga_g       , //
    output  wire    [07:00]   vga_b       , //
    output  wire              vga_blk     , //  
    output  wire              vga_clk       //  

);
    wire [23:00] data_disp;
    wire            vga_25;//25MHz
    wire            vga_40;//40MHz

    wire            locked;  

    wire [10:00] h_addr;
    wire [10:00] v_addr;

    wire            reset;
    
    assign reset = rst_n & locked;

    pll_25	pll_25_inst (
	.areset ( ~rst_n ),
	.inclk0 ( clk ),
	.c0 ( vga_25 ),
    .c1 ( vga_40 ),
	.locked (locked)
	);


    data_gen u_data_gen(
        .clk         (vga_25  ), //vga clk 640*480 25.2MHz
        .rst_n       (reset    ), //复位信号
        .h_addr      (h_addr   ), //数据有效显示区域行地址
        .v_addr      (v_addr   ), //数据有效显示区域场地址

        .data_disp   (data_disp)  //
    );
    vga_ctrl u_vga_ctrl(
        .clk         (vga_25 ), //vga clk 640*480 25.2MHz
        .rst_n       (reset    ), //复位信号
        .data_disp   (data_disp), //
        
        .h_addr      (h_addr   ), //数据有效显示区域行地址
        .v_addr      (v_addr   ), //数据有效显示区域场地址
        .vsync       (vsync    ), //
        .hsync       (hsync    ), //
        .vga_r       (vga_r    ), //RGB三色
        .vga_g       (vga_g    ), //
        .vga_b       (vga_b    ), //
        .vga_blk     (vga_blk  ), //
        .vga_clk     (vga_clk  )  //
    );
endmodule

上板验证:

在这里插入图片描述

vga显示彩条

代码实现
data_gen

module data_gen (
    input   wire              clk         , //vga clk 640*480 25.2MHz
    input   wire              rst_n       , //复位信号

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

    output  reg    [23:0]     data_disp     //

);

//参数定义
    parameter
        BLACK   = 24'h000000,
        RED     = 24'hFF0000,
        GREEN   = 24'h00FF00,
        BLUE    = 24'h0000FF,
        YELLOW  = 24'hFFFF00,
        SKY_BULE= 24'h00FFFF,
        PURPLE  = 24'hFF00FF,
        GRAY    = 24'hC0C0C0,
        WHITE   = 24'hFFFFFF; 
        
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)begin
            data_disp <= WHITE;
        end
        else begin//彩条
            case (h_addr)
                0   : data_disp <= BLACK    ;
                80  : data_disp <= RED      ;
                160 : data_disp <= GREEN    ;
                240 : data_disp <= BLUE     ;
                320 : data_disp <= YELLOW   ;
                400 : data_disp <= SKY_BULE ;
                480 : data_disp <= PURPLE   ;
                560 : data_disp <= GRAY     ;
                default: data_disp <= data_disp ;
            endcase
        end
    end
endmodule

上板验证
在这里插入图片描述
参考链接:https://blog.csdn.net/qq_45659777/article/details/124834294

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值