Verilog——HDMI屏幕文字叠加显示

最近在做摄像头到HDMI的一个项目,然后发现网上文字叠加显示的代码比较少,因此写了一个放上来分享一下:

字模来源于PCtoLCD2002,具体配置如下:

其余设置好字高字宽之后就可以直接生成字模联络。生成好的字模复制到string数组当中即可。

模块输入如下

module front_show(
    input      [10:0]  pixel_x,//输入像素X轴坐标
    input      [10:0]  pixel_y,//输入像素X轴坐标
    input      [23:0]  front_colour,//文字颜色,RGB888格式
    input      [23:0]  back_colour,//文字背景颜色,RGB888格式
    input      [23:0]  default_colour,//默认颜色,RGB888格式
    input              pixel_clk,//输入像素时钟
    output             front_de,//当x,轴坐标移动到文字区域内时该标志位拉高
    output reg [23:0]  pixel_data_out
    );

`timescale 1ns / 1ps
module front_show(
    input      [10:0]  pixel_x,
    input      [10:0]  pixel_y,
    input      [23:0]  front_colour,//文字颜色
    input      [23:0]  back_colour,//文字背景颜色
    input      [23:0]  default_colour,//默认颜色
    input              pixel_clk,
    output             front_de,
    output reg [23:0]  pixel_data_out
    );
parameter front_xstart=16'd10;//字符串起始x坐标
parameter front_ystart=16'd10;//字符串起始y坐标  
parameter front_num=16'd18;//显示的文字数量
parameter front_width=8'd24;
parameter front_high=8'd24;
parameter front_len=384;//24x24字模英文长宽比为24:12,两个字符间隔为4个像素点,因此实际长宽为W=12+4=16,H=24,W*H=16*24=384   
/*字库*/
reg [front_len-1:0]string [front_num-1:0];
initial begin

string[0]=384'h000000000000000000000F00198030C030C06060606060606060606060606060606030C030C019800F00000000000000;/*"0",0*/
string[1]=384'h0000000000000000000002003E0006000600060006000600060006000600060006000600060006003FC0000000000000;/*"1",1*/
string[2]=384'h000000000000000000001F00218040C060C060C000C00080018003000600040008001040204060407FC0000000000000;/*"2",2*/
string[3]=384'h000000000000000000001E006300618061800180018003000E000180008000C000C060C060C061801F00000000000000;/*"3",3*/
string[4]=384'h0000000000000000000001800180038005800580098011801180218041807FF0018001800180018007E0000000000000;/*"4",4*/
string[5]=384'h000000000000000000003FC0200020002000200020002F00318020C000C000C060C060C0418021801F00000000000000;/*"5",5*/
string[6]=384'h00000000000000000000078018C030C0300020006000678068C070606060606060602060304018C00F00000000000000;/*"6",6*/
string[7]=384'h000000000000000000001FE0306020402080008000800100010002000200020006000600060006000600000000000000;/*"7",7*/
string[8]=384'h000000000000000000001F8030C0606060606060304038C00F00138030C0606060606060606030C00F80000000000000;/*"8",8*/
string[9]=384'h000000000000000000000F00308030C0604060606060606060E031601E60006000C000C0308031801E00000000000000;/*"9",9*/
string[10]=384'h00000000000000000000FFC060C0602060206000610061007F006100610061006000600060006000F800000000000000;/*"F"10*/
string[11]=384'h00000000000000000000FF0060C06060606060606060606061C07F00600060006000600060006000F800000000000000;/*"P"11*/
string[12]=384'h000000000000000000000F001880304030402040600060006000600063F060C060C030C030C018C00F00000000000000;/*"G"12*/
string[13]=384'h00000000000000000000060006000A000B00090009001100118010801F8020C020C0204040404060F0F0000000000000;/*"A"13*/
string[14]=384'h000000000000000000000000040004000C000C007F800C000C000C000C000C000C000C000C400C400780000000000000;/*"t"14*/
string[15]=384'h0000000000000000000000000000000000000000078018C01040306030603FE030003000182018400780000000000000;/*"e"15*/
string[16]=384'h00000000000000000000000000000000000000000FC038C0304030401C000F0003C020C020C031C03F80000000000000;/*"s"16*/
string[17]=384'h000000000000000000000000040004000C000C007F800C000C000C000C000C000C000C000C400C400780000000000000;/*"t"17*/

end
/*字库*/



reg [11:0]string_width = front_width*front_num;//最长4095
wire [10:0]x_cnt;
wire [10:0]y_cnt;
assign front_de = (pixel_x >= front_xstart) && (pixel_x<(front_xstart+string_width)) && (pixel_y>=front_ystart) && (pixel_y<front_ystart+front_high) ;
assign x_cnt = pixel_x-front_xstart; //像素点相对于字符区城起始点水平华布
assign y_cnt = pixel_y-front_ystart; //像素点相对于字符区城起始点垂直华杨/测试时长
always @(posedge pixel_clk ) 
begin    
        if(front_de)
        begin
            if(string[x_cnt/front_width][front_len-(x_cnt%front_width+(y_cnt-1)*front_width)]!=0)
                pixel_data_out <= front_colour;
            else
                pixel_data_out <= back_colour;
        end
        else
            pixel_data_out <= default_colour;
end    
endmodule

应用举例(屏幕彩条实验为例):

module  video_display(
    input                pixel_clk,
    input                sys_rst_n,
    
    input        [10:0]  pixel_xpos,  //像素点横坐标
    input        [10:0]  pixel_ypos,  //像素点纵坐标
    output  reg  [23:0]  pixel_data   //像素点数据
);



//parameter define
parameter  H_DISP = 11'd1280;                       //分辨率——行
parameter  V_DISP = 11'd720;                        //分辨率——列

localparam WHITE  = 24'b11111111_11111111_11111111;  //RGB888 白色
localparam BLACK  = 24'b00000000_00000000_00000000;  //RGB888 黑色
localparam RED    = 24'b11111111_00001100_00000000;  //RGB888 红色
localparam GREEN  = 24'b00000000_11111111_00000000;  //RGB888 绿色
localparam BLUE   = 24'b00000000_00000000_11111111;  //RGB888 蓝色

wire [23:0] front_de,front_show_data;
 
 
//*****************************************************
//**                    main code
//*****************************************************


//根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条
always @(posedge pixel_clk ) begin
    if (!sys_rst_n)
        pixel_data <= 16'd0;
    else begin
       if(!front_de)
            begin
             if((pixel_xpos >= 0) && (pixel_xpos < (H_DISP/5)*1))
                 pixel_data <= WHITE;
             else if((pixel_xpos >= (H_DISP/5)*1) && (pixel_xpos < (H_DISP/5)*2))
                 pixel_data <= BLACK;  
             else if((pixel_xpos >= (H_DISP/5)*2) && (pixel_xpos < (H_DISP/5)*3))
                 pixel_data <= RED;  
             else if((pixel_xpos >= (H_DISP/5)*3) && (pixel_xpos < (H_DISP/5)*4))
                 pixel_data <= GREEN;
             else 
                 pixel_data <= BLUE;
            end
        else
                 pixel_data<=front_show_data;

    end
end


front_show #(
    .front_xstart(16'd50),
    .front_ystart(16'd50),
    .front_high(8'd24),
    .front_width(8'd16)
)
u_string_show(
    .pixel_x       (pixel_xpos),
    .pixel_y       (pixel_ypos),
    .front_colour  (BLACK),
    .back_colour   (WHITE),
    .default_colour(BLACK),
    .pixel_clk     (pixel_clk),
    .front_de      (front_de),
    .pixel_data_out (front_show_data)
    );


endmodule

效果: