Menu Close

HDMI FPGA 工程设计3(rom, I2C 控制)

HDMI工程中使用rom IP 作为lotus (莲花图像)的存储。 莲花图像为:24bit (RGB 888) 480 x 270 像素 ,所以rom IP 使用的资源大小如下:

ROM ip 及 coe 文件:

%title插图%num

其中 port A depth  为 480 x 270 , 在rom IP 初始化时,增加 coe 文件:

%title插图%num

关于一个计算机普通的文件如何转换为coe 文件, 可以查看相关的文章, 我们针对图像转coe 做了一个小的工程,帮助大家转换。

图片转MIF/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 寄存器配置就结束了。

Posted in FPGA, FPGA, Verilog, Verilog, Verilog语言编程与FPGA, 教材与教案, 文章

发表评论

相关链接