FPGA实现VGA显示(四)——————读取ROM显示彩色图片(a)

这里只介绍模块思路,ROM的生成和设置等等其余问题,会单独开一篇总结。先放图看结果ide

准备阶段

首先用到这两个软件第一个用来解码,将图片中的每个像素点用16进制表示,第二个用来转换图片。由于图片太大的话,资源过小,就不能显示。code

用第二个软件修改图片的长度宽度,用第一个软件生成.coe文件。blog

而后,会生成一个这个在桌面。而后生成ip就能够了。图片

这里的100是图片的宽,而后92 是图片的高。ip

代码实现

module vga_display_BMP(vga_clk,rst_n,
	x_pixel,y_pixel,
	pixel_data
    );
//---------------------------------
input    			  vga_clk	;
input 					rst_n	;
input 		[9:0]	  x_pixel	;
input 		[9:0]	  y_pixel	;
//---------------------------------
output 		[15:0]	  pixel_data;
//---------------------------------
//---------------------------------
parameter white = 16'b11111_111111_11111   ;
parameter black = 16'b00000_000000_00000   ;
parameter red   = 16'b11111_000000_00000   ;
parameter green = 16'b00000_111111_00000   ;
parameter bule  = 16'b00000_000000_11111   ;
//---------------------------------
parameter height = 10'd92;
parameter wide   = 10'd100;
parameter pos_x  = 0;
parameter pos_y  = 0;
/*pos_x,pos_y 这两个来控制左上角第一个点的位置*/
//---------------------------------
wire rom_rd_en;//读ROM使能信号
reg [13:0] rom_addr;//读ROM有效信号
reg [15:0] color_bar;
wire [32:0] total;
assign total = height * wide ;
//---------------------------------
wire [15:0] rom_data;
assign pixel_data =  rom_rd_en ? rom_data : color_bar;
assign rom_rd_en = (x_pixel > pos_x) && (x_pixel <= pos_x + wide ) && (y_pixel > pos_y) && (y_pixel <= pos_y + height ) ? 1'b1 : 1'b0;
always@(posedge vga_clk or negedge rst_n)
begin
	if(!rst_n)
		rom_addr <= 14'd1;
	else 
		if(rom_rd_en)
			begin
				if(rom_addr < total - 1'b1 )
					rom_addr <= rom_addr + 1'b1;
				else 
					rom_addr <= 'b0;
			end
		else 
			rom_addr <= rom_addr;
end
always@(posedge vga_clk or negedge rst_n)
begin
	if(!rst_n)
		color_bar <= 16'd0;
	else 
		if(~rom_rd_en)
			if(y_pixel >= 240)
				color_bar <= bule;
			else 
				color_bar <= green;
end
/*只是ROM例化,后面总结*/
rom your_instance_name (
  .clka(vga_clk), // input clka
  .addra(rom_addr), // input [13 : 0] addra
  .douta(rom_data) // output [15 : 0] douta
);
endmodule

思路是这样的,每个在.coe文件中的数据,实际上是一个个像素点的数据,在起始位置开始显示第一个,而后依次显示第一行的每个像素,在到第二行,开始显示第二行的第一个像素,依次类推。最后显示全部的像素点。资源

代码仿真

代码写完以后先最好仿真,否则出来的图片很容易使雪花。这里有一个经验,查看仿真图的时候,能够看开始的一行和结束的一行,而后屏幕每一次刷新后的开始一行的像素点和.coe。第一行的数据是否同样input