最近在做摄像头到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
效果: