用的开发板是microzus,因为ZYNQ PL 侧的 IO 结构是支持 TMDS,可以用 FPGA 直接驱动 HDMI 信号。HDMI显示主要是用的IP核实现的,这个不是官方的,所以需要另外下载,在我后面提供的github里也可以下载到。
这里主要是想讲关于FPGA从ROM里读出图像数据然后HDMI输出到显示器里。
首先需要BMP2Mif.exe,它可以将bmp转化成coe文件,包括RGB888、gray等输出。之后就可以将coe文件存到ROM里,不过由于资源有限,所以图片分辨率不能过高,我用的是200*200。
后面就是读取与显示了。这里贴出部分代码,完整代码请去github下载
wire [23:0] douta;
wire ena;
assign ena = (x_cnt >= H_Start) && (x_cnt < 12'd536) && (y_cnt >= V_Start && y_cnt < 12'd227);
reg [15:0] cnt_addr = 16'd0;
/*********************************BRAM相关信号******************************************/
//BRAM读取地址计数器
always @(posedge pix_clk )
begin
if(ena)
begin
if (cnt_addr == 16'd39999 )
cnt_addr <= 0;
else
cnt_addr <= cnt_addr+1 ;
end
else
cnt_addr <= cnt_addr;
end
blk_mem_gen_0 blk_mem_gen_0 (
.clka(pix_clk), // input wire clka
.addra(cnt_addr), // input wire [15 : 0] addra
.douta(douta) // output wire [23 : 0] douta
);
reg[7:0] VGA_R_reg;
reg[7:0] VGA_G_reg;
reg[7:0] VGA_B_reg;
always @(posedge pix_clk)
begin
if(1'b0)
begin
VGA_R_reg<=0;
VGA_G_reg<=0;
VGA_B_reg<=0;
end
else if (ena)
// begin
// VGA_R_reg<=grid_data;
// VGA_G_reg<=grid_data;
// VGA_B_reg<=grid_data;
// end
// begin
// VGA_R_reg<=douta;
// VGA_G_reg<=douta;
// VGA_B_reg<=douta;
// end
begin
VGA_R_reg<=douta[23:16];
VGA_G_reg<=douta[15:8];
VGA_B_reg<=douta[7:0];
end
else
begin
VGA_R_reg<=8'hff;
VGA_G_reg<=8'd00;
VGA_B_reg<=8'd00;
end
end
assign ena = (x_cnt >= H_Start) && (x_cnt < 12'd536) && (y_cnt >= V_Start && y_cnt < 12'd227);
这句表明图像显示的位置,我这里选的是左上角,当然也可以根据需要再修改,不过记住要保证行间隔与列间隔为200。
VGA_R_reg<=douta[23:16];
VGA_G_reg<=douta[15:8];
VGA_B_reg<=douta[7:0];
这里是图像数据的输出,这是RGB888格式的,若为灰度图则R,G,B都为一样的值(上面注释的代码就是)。
这是我测试的结果。分别实现了网格输出、灰度输出和彩色输出。
github链接:https://github.com/hywhjj/ZYNQ-pl-hdmi