HDMI工程中使用rom IP 作为lotus (莲花图像)的存储。 莲花图像为:24bit (RGB 888) 480 x 270 像素 ,所以rom IP 使用的资源大小如下:
ROM ip 及 coe 文件:
其中 port A depth 为 480 x 270 , 在rom IP 初始化时,增加 coe 文件:
关于一个计算机普通的文件如何转换为coe 文件, 可以查看相关的文章, 我们针对图像转coe 做了一个小的工程,帮助大家转换。
iic_cfg.v 控制模块:
i2c 控制模块由两个部分组成: i2c_phy.v 模块 和 i2c_ctrl.v 控制模块。
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2020/05/15 14:17:04 // Design Name: // Module Name: iic_cfg // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module iic_cfg( input clk, //50m input rst_n, inout iic_sda, inout iic_scl ); //============================= //phy wire [1:0] cmd; wire [7:0] wr_data; wire [15:0] addr; wire [6:0] device_addr; wire done; wire [7:0] rd_data; i2c_phy #( .IIC_F100K (500), //100K-500 .IIC_F400K (125) //400K-125 ) i2c_phy_inst( .clk_50m (clk), .rst_n (rst_n), .cmd (cmd), .wr_data (wr_data), .addr (addr), .device_addr(device_addr), .done (done), .rd_data (rd_data), .SDA (iic_sda), .SCL (iic_scl) //100K ); //================================== //ctrl i2c_ctrl i2c_ctrl_inst( .clk_50m (clk), .rst_n (rst_n), .cmd (cmd), .wr_data (wr_data), .addr (addr), .device_addr(device_addr), .done (done), .rd_data (rd_data) ); endmodule
i2c_phy.v 模块是一个标准的i2c 物理层模块, 它可以在很多的工程中使用, 而不是一定在hdmi fpga 当前这个工程使用。
i2c_ctrl.v 模块是专门用来控制adv7511 的部分,它的主要功能是将当前项目(hdmi 图像显示) adv7511 所需要的相关寄存器配置, 写入到adv7511 寄存器中。
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2020/05/07 19:39:07 // Design Name: // Module Name: ad_ctrl // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module i2c_ctrl( input clk_50m, input rst_n, output reg [1:0] cmd, output reg [7:0] wr_data, output reg [15:0] addr, output [6:0] device_addr, input done, input [7:0] rd_data ); assign device_addr = 7'b0111_001; //ADV7511 reg [4:0] wr_st; always @ (posedge clk_50m) if(!rst_n) begin wr_st <= 0; cmd <= 0; addr <= 0; wr_data <= 0; end else case(wr_st) 0: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h01; wr_data <= 8'h00;end 1: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h02; wr_data <= 8'h18;end 2: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h03; wr_data <= 8'h00;end 3: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h15; wr_data <= 8'h00; end 4: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h16; wr_data <= 8'h61; end 5: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h18; wr_data <= 8'h46; end 6: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h40; wr_data <= 8'h80; end 7: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h41; wr_data <= 8'h10; end 8: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h48; wr_data <= 8'h48; end 9: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h48; wr_data <= 8'ha8; end 10: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h4c; wr_data <= 8'h06; end 11: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h55; wr_data <= 8'h00; end 12: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h55; wr_data <= 8'h08; end 13: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h96; wr_data <= 8'h20; end 14: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h98; wr_data <= 8'h03; end 15: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h98; wr_data <= 8'h02; end 16: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h9c; wr_data <= 8'h30; end 17: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h9d; wr_data <= 8'h61; end 18: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'ha2; wr_data <= 8'ha4; end 19: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'h43; wr_data <= 8'ha4; end 20: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'haf; wr_data <= 8'h16; end 21: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'hde; wr_data <= 8'h9c; end 22: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'he4; wr_data <= 8'h60; end 23: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'hfa; wr_data <= 8'h7d; end 24: if( done ) begin cmd <= 2'b00; wr_st <= wr_st + 1'b1; end else begin cmd <= 2'b01; addr <= 8'hba; wr_data <= 8'ha0; end 25: wr_st <= 25; default : wr_st <= 0; endcase endmodule // 01 00 ; Set N Value(6144) // 02 18 ; Set N Value(6144) // 03 00 ; Set N Value(6144) // 15 00 ; Input 444 (RGB or YCrCb) with Separate Syncs // 16 61 ; 44.1kHz fs, YPrPb 444 // 18 46 ; CSC disabled // 40 80 ; General Control Packet Enable // 41 10 ; Power Down control // 48 48 ; Reverse bus, Data right justified // 48 A8 ; Set Dither_mode - 12-to-10 bit // 4C 06 ; 12 bit Output // 55 00 ; Set RGB444 in AVinfo Frame // 55 08 ; Set active format Aspect // 96 20 ; HPD Interrupt clear // 98 03 ; ADI required Write // 98 02 ; ADI required Write // 9C 30 ; ADI required Write // 9D 61 ; Set clock divide // A2 A4 ; ADI required Write // 43 A4 ; ADI required Write // AF 16 ; Set HDMI Mode // BA 60 ; No clock delay // DE 9C ; ADI required write // E4 60 ; ADI required Write // FA 7D ; Nbr of times to search for good phase
文中所配置的adv7511 , 主要是根据:1631052044-ADV7511
文档中参数所配置, 用户也可以更改其中的一些选项, 达到自己的配置要求。
关于adv 7511 寄存器相关的详细解释, 可以查看:1631052092-ADV7511_Programming_Guide
文档。
i2c 控制主要是有一个wr_st 的状态机完成, 这个状态机一共有26步, 其中0 – 24 步 是将adv7511 相关的寄存器写入到硬件芯片中, 最后停留在状态25,整个adv7511 寄存器配置就结束了。