目录
一、任务
用VGA静态显示字符“风已经起了”,模式为640x480@60(对模式不清楚的可以看看FPGA学习笔记——VGA简介-CSDN博客),一个字符一个格子,格子为64x64,字符占56x56,字符显示在中间位置。 (相关IP核配置,可以去看看FPGA学习笔记——VGA彩条显示-CSDN博客,这里只重点说文字提取)
二、分析
(1)分析
首先,根据下图我们知道该模式的具体参数,行同步信号的有效图像为640,场同步信号的有效图像为480。
任务说要在中间显示,那么就要知道第一个字符的位置、整个字符行长度和整个字符的场长度。
第一个字符位置:(640 - 64x5)/2 - 1 = 159 --- 整个行同步信号有效图像是640,5个字符占64x5,减一是从0开始。
字符的场同步信号位置:(480 - 64)/2 - 1 = 199 --- 字符是并行排列,只占64。
(2)字符提取
根据以上的分析,我们就可以开始字符提取了。
第一步:选择好模式与字符大小
第二步:输入字符并另存为.BMP
第三步:将刚刚存的.BMP打开,并配置好格式
这里为什么要镜像:如果我不镜像,它显示出来就是镜像。可能和上位机或者其它的东西有关吧。
第四步:生成.txt
.txt文件里面就是我们要i的。
三、代码
top.v
module top (
input wire clk ,
input wire rst_n ,
output wire [15:0] data_rgb ,
output wire Hsync ,
output wire Vsync
);
//vga
wire De;
wire [9:0] X;
wire [9:0] Y;
vga vga_u(
. pclk (pclk ) ,
. rst_n (locked) ,
. De (De ) , //数据有效信号
. X (X ) ,
. Y (Y ) ,
. Hsync (Hsync ) , //行同步信号
. Vsync (Vsync ) //场同步信号
);
char char_u(
. clk (pclk ) ,
. rst_n (locked) ,
. De (De ) ,
. X (X ) ,
. Y (Y ) ,
. data (data_rgb )
);
wire pclk;
wire locked;
pll pll_inst (
.areset ( !rst_n ),
.inclk0 ( clk ),
.c0 ( pclk ),
.locked ( locked )
);
endmodule
vga.v
module vga (
input wire pclk ,
input wire rst_n ,
output wire [9:0] X ,//X坐标
output wire [9:0] Y ,//Y坐标
output wire De , //数据有效信号
output wire Hsync , //行同步信号
output wire Vsync //场同步信号
);
localparam H_Total = 800 ,//行总像素点
H_Addr = 640 ,//有效像素点
H_Right = 8 ,//右边框
H_Front = 8 ,//前沿
H_Sync = 96 , //同步
H_Back = 40 , //后沿
H_Left = 8 ;//左边框
localparam V_Total = 525 ,//场总像素点
V_Addr = 480 ,//有效像素点
V_Bottom = 8 ,//底边框
V_Front = 2 ,//前沿
V_Sync = 2 , //同步
V_Back = 25 , //后沿
V_Top = 8 ; //上边框
reg [9:0] cnt_h,cnt_v;
//行周期计数
always @(posedge pclk) begin
if(!rst_n)
cnt_h <= 0;
else if( cnt_h == H_Total - 1 )
cnt_h <= 0;
else
cnt_h <= cnt_h + 1;
end
//场周期计数
always @(posedge pclk) begin
if(!rst_n)
cnt_v <= 0;
else if( cnt_h == H_Total - 1 ) begin
if( cnt_v == V_Total - 1 )
cnt_v <= 0;
else
cnt_v <= cnt_v + 1;
end
else
cnt_v <= cnt_v;
end
//行场同步信号
assign Hsync = (cnt_h < H_Sync ) ? 1 : 0;
assign Vsync = (cnt_v < V_Sync ) ? 1 : 0;
assign De = ((cnt_h > H_Sync + H_Back + H_Left - 1) &&
(cnt_h < H_Sync + H_Back + H_Left + H_Addr) &&
(cnt_v >= V_Sync + V_Back + V_Top ) &&
(cnt_v < V_Sync + V_Back + V_Top + V_Addr) ) ? 1 : 0;
assign X = (De == 1) ? (cnt_h - H_Sync - H_Back - H_Left) : 1'b0;
assign Y = (De == 1) ? (cnt_v - V_Sync - V_Back - V_Top ) : 1'b0;
endmodule
cahr.v
module char (
input wire clk ,
input wire rst_n ,
input wire De ,
input wire [9:0] X ,
input wire [9:0] Y ,
output reg [15:0] data
);
parameter CHAR_B_H = 10'd160,
CHAR_B_V = 10'd200;
parameter CHAR_W = 10'd320,
CHAR_H = 10'd64 ;
parameter BLACK = 16'h0000,
GOLDEN = 16'hFEC0;
reg [319:0] char [64:0] ;
wire [9:0] char_x ;
wire [9:0] char_y ;
wire [9:0] x;
wire [9:0] y;
assign x = ((X < 160) || X > 480 ) ? 0 : (X - 160);
assign y = ((Y < 200) || Y > 264 ) ? 0 : (Y - 200);
assign char_x = ((X > CHAR_B_H) && (X < CHAR_B_H + CHAR_W)) ? 1: 0;
assign char_y = ((Y > CHAR_B_V) && (Y < CHAR_B_V + CHAR_H)) ? 1 : 0;
always @(posedge clk) begin
char[1] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[2] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[3] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[4] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[5] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[6] <= 320'h00000000000000000000000000020000000000000000000000000000000000000000000000000000;
char[7] <= 320'h000000000000000000000000000E000000000000000000000000000000000000000000E000000000;
char[8] <= 320'h000000C00000000000000000003E0000000000000000E0000000000030000000000001FC00000000;
char[9] <= 320'h000003F80000000000000000003C0000000000800001E00000000001F8000000000003FFE0000000;
char[10] <= 320'h000007FFC000000000000000001C0000000003C00003E00000000007FE000000000007E3FF807000;
char[11] <= 320'h00000FE3FFC0000000000000001C0000000007F80001E00000000007FFF00000000001E007FFF000;
char[12] <= 320'h00000FE00FFFFC0000000000001C000000000FFF8000E00000000007FFFFE000000001E0000FE000;
char[13] <= 320'h000007F0007FF80000000000001C0000000007E7FC00E00000000003F01FC000000000E00001E000;
char[14] <= 320'h000001F80007F00000001F00001C0000000001E0FC18700000000001F0000000000000E00001C000;
char[15] <= 320'h0000007C0000000000003FF0001C0000000001E00070700000000000F0000000000000E06001C000;
char[16] <= 320'h0000001E0000000000003FFFC01C0000000000F000F8300000000000F8000000000000E1E001C000;
char[17] <= 320'h0000000F0000000000001F0F001C00000000007800781800000000007800000000000061E001C000;
char[18] <= 320'h000000038000000000000F0007FC00000000003800781800000000003800040000000061E001C000;
char[19] <= 320'h00000001C00000000000070003FE00000000003C003C0C000000000038000C0000000071E001C000;
char[20] <= 320'h00000000E000000000000700007FC0000000001E001E0E000000000018001C0000000070E001C000;
char[21] <= 320'h000000003E00000000000300001FF0000000000F000E0700000000001C003C0000000070F011C000;
char[22] <= 320'h000000003C00000000000380001C0000000001F70007FF80000000001C003C00000000707021C000;
char[23] <= 320'h00000000FC000000000007C0000C000000000FE38003FF80000000001F001C00000000707061C000;
char[24] <= 320'h00000000F8000000000007FEE00C000000003F81C0038780000000003FF01C000000007078C1C000;
char[25] <= 320'h00000000780000000000003FC7CC00000000FF00E001C0800000000007FF1C00000000703981C000;
char[26] <= 320'h000000007800000000000000C3FC00000001FC007000C00000000000003FFC00000000703B81C000;
char[27] <= 320'h000000007800000000000000C07F80000003F8003C006000000000000000FC00000000701F00C000;
char[28] <= 320'h000000007800000000000000C00FF8000003E0000E0070000000000000000C00000000701F00E000;
char[29] <= 320'h000000007000000000000000C01CFFC00003C000030038000000000000000C00000000701E00E000;
char[30] <= 320'h000000007000000000000000C01C0FF800030000009F98000000000000000C00000000703E00E000;
char[31] <= 320'h000000007000000000004000C01C01F000000FC00007FC000000000000000C00000000603F00E000;
char[32] <= 320'h00000000700000000000C000C01C004000000FFC0000FF000001000000000C00000000607F00E000;
char[33] <= 320'h00000000700000000000C000C19C1800000003FFE0003F000001000000000C00000000E0FB806000;
char[34] <= 320'h00000000700000000000E000C7FC38000000001FFC000F000001000000000C00000000E0F3C07000;
char[35] <= 320'h00000000700000000000E001C0FC78000000001E000002000001800000000C00000000E1E1C07000;
char[36] <= 320'h00000000700000000001FC07801C38000000001E000000000001800000000C00000000E3E0E07000;
char[37] <= 320'h00000000700000000001FFFF801C1C000000001E000000000001800000000C00000000C3C0703800;
char[38] <= 320'h000000007000000000007FFF001C7C000000000E001C00000001C00000000C00000001C380383800;
char[39] <= 320'h0000000070000000000007F0001DCE000000000E000780000001C00000001C00000801C7801C1C00;
char[40] <= 320'h000000007000000000000000001F8E000000000E0003F0000001E00000001C00000803C7000E1C00;
char[41] <= 320'h000000007000000000000000003E07000000000E0000FF000001F00000003C00000C078300030E00;
char[42] <= 320'h00000000780000000000000000F803800000000E00003FE00003FC00000038000004078000008600;
char[43] <= 320'h00000000780000000000000007E001C00001F80E00001FC00003FF000000780000060F0000000700;
char[44] <= 320'h0000000078000000000000003F8000C00007FFFE000007800001FFF00003F00000063E0000000180;
char[45] <= 320'h000000007800000000000003FE0000600007FFFFFF00030000007FFFF1FFE0000007FE00000000C0;
char[46] <= 320'h000000007C3000000000007FF800003000000007FFF8000000000FFFFFFFC000000FFC0000000060;
char[47] <= 320'h000000007FE00000003FFFFFE0000008000000000FE000000000007FFFFE0000000FF80000000010;
char[47] <= 320'h000000007F800000000FFFFF80000000000000000000000000000001FFE00000000FE00000000000;
char[48] <= 320'h000000003F0000000001FFFE0000000000000000000000000000000000000000000FC00000000000;
char[49] <= 320'h000000001F00000000003FF00000000000000000000000000000000000000000000E000000000000;
char[50] <= 320'h000000001E0000000000038000000000000000000000000000000000000000000000000000000000;
char[51] <= 320'h000000000C0000000000000000000000000000000000000000000000000000000000000000000000;
char[52] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[53] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[54] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[55] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[56] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[57] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[58] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[59] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[60] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[61] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[62] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
char[63] <= 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
end
always @(posedge clk) begin
if(!rst_n)
data <= BLACK;
else if( char_x && char_y && (char[y][x] == 1) && De == 1)
data <= GOLDEN;
else
data <= BLACK;
end
endmodule
四、现象
以上就是VGA静态图像显示。