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