设计框图:

我们的设计主要是要在HDMI 显示器上显示彩条,只需先设计一个彩条数据输出(Pattern Generator)模块,然后设计一个配置ADV7513寄存器的模块即可,ADV7513芯片自动将并行的彩条数据转化为TMDS算法的、且是串行的、差分的数据传输到HDMI显示器端:

HDMI_top.v:

主要是例化几个模块:

module hdmi_top(
    input sys_clk,
    input sys_rst_n,
    input HDMI_TX_INT,
    inout HDMI_I2C_SCL,
   inout HDMI_I2C_SDA,

    output hdmi_de, 
    output hdmi_tx_hs, 
    output hdmi_tx_vs, 
    output hdmi_tx_clk, 
    output [23:0] hdmi_tx_data
);

//wire define
wire pixel_clk;
wire clk_locked;

//wire video_hs;
//wire video_vs;
//wire video_de;
//wire [23:0] video_rgb;

//*****************************************************
//** main code
//*****************************************************

//例化 PLL IP 核
pll_hdmi u_pll_clk(
    .rst       (~sys_rst_n),
    .refclk    (sys_clk),
    .outclk_0  (hdmi_tx_clk),                 //像素时钟
    .locked (clk_locked)
);

//例化 HDMI 控制模块

hdmi_ctrl hdmi_ctrl_inst (
    .clk                (hdmi_tx_clk),
    .rst_n              (clk_locked),
                       
    .hdmi_rgb            (hdmi_tx_data),
    .video_de                 (hdmi_de),
    .hdmi_hs              (hdmi_tx_hs),
    .hdmi_vs              (hdmi_tx_vs)
    );

     //HDMI I2C
I2C_HDMI_Config u_I2C_HDMI_Config (
    .iCLK(sys_clk),
    .iRST_N(sys_rst_n),
    .I2C_SCLK(HDMI_I2C_SCL),
    .I2C_SDAT(HDMI_I2C_SDA),
    .HDMI_TX_INT(HDMI_TX_INT)
     );
     
endmodule

 

 hdmi_ctrl.v:

设计一个分辨率是 1280*720的 彩条数据输出:
module hdmi_ctrl (

    input     wire                     clk,
    input     wire                         rst_n,

    output    reg        [23:0]      hdmi_rgb,
    output    reg                    hdmi_hs,
    output     reg                             hdmi_vs,
    output    wire                        video_de    //数据使能  
);


//1280*720分辨率时序参数

    localparam            HS_A    =    40;                // synchronous pulse, horizontal
    localparam            HS_B    =    220;                // back porch pulse
    localparam            HS_C    =    1280;                // display interval
    localparam            HS_D    =    110;                // Front porch
    localparam            HS_E    =    1650;                // horizontal cycles

    localparam            VS_A    =    5;                    // synchronous pulse, vertical
    localparam            VS_B    =    20;
    localparam            VS_C    =    720;    
    localparam            VS_D    =    5;    
    localparam            VS_E    =    750;    
    
    localparam            HS_WIDTH    =    11;
    localparam            VS_WIDTH    =    10;



    parameter            CNT_VS_R    = 205;                // 345 = 5+20+180, 25~205 行显示红色, 有效数据q段是720行,第一个180行是红
    parameter            CNT_VS_G    = 385;                //    205~385 是绿 第二个180行是绿
    parameter            CNT_VS_B    = 565;                //    665~985 是蓝 第三个180行是蓝,剩下的就是黑了
     
    reg        [HS_WIDTH - 1:0]        cnt_hs;                // counter for vertical synchronous signal
    reg        [VS_WIDTH - 1:0]        cnt_vs;                // counter for horizontal synchrous signal
    
    wire                    en_hs;                                //    dsiplay horizontal enable
    wire                    en_vs;                                // display vertical enable
    
    wire                    en_vs_r;                                // red stripe enable
    wire                    en_vs_g;                                // green stripe enable
     wire                    en_vs_b;                                // blue stripe enable

    always @ (posedge clk, negedge rst_n)
        if (!rst_n)
            cnt_hs <= 0;
        else
            if (cnt_hs < HS_E - 1)
                cnt_hs <= cnt_hs + 1'b1;
            else
                cnt_hs <= 0;
                
    always @ (posedge clk, negedge rst_n)
        if (!rst_n)
            cnt_vs <= 0;
        else
            if (cnt_hs == HS_E - 1)
                if (cnt_vs < VS_E - 1)
                    cnt_vs <= cnt_vs + 1'b1;
                else
                    cnt_vs <= 0;
            else
                cnt_vs <= cnt_vs;
                
    always @ (posedge clk, negedge rst_n)
        if (!rst_n)
            hdmi_hs <= 1'b1;
        else
            if (cnt_hs < HS_A - 1) //同步之前hdmi_hs信号都是低, 同步之后(a)hdmi_hs信号是高
                hdmi_hs <= 1'b0;
            else
                hdmi_hs <= 1'b1;
                
    always @ (posedge clk, negedge rst_n)
        if (!rst_n)
            hdmi_vs <= 1'b1;
        else
            if (cnt_vs < VS_A - 1) //同步之前hdmi_vs 信号都是低, 同步之后(a)hdmi_vs 信号是高
                hdmi_vs <= 1'b0;
            else
                hdmi_vs <= 1'b1;
        
    assign en_hs = (cnt_hs > HS_A + HS_B - 1)&& (cnt_hs < HS_E - HS_D);//en_hs 将有效数据c段标出来了,有效数据c段en_hs 才为高,否则为低
    assign en_vs = (cnt_vs > VS_A + VS_B - 1) && (cnt_vs < VS_E - VS_D);//en_vs 将有效数据q段标出来了,有效数据q段en_hs 才为高,否则为低
   
    assign en_vs_r = (cnt_vs > VS_A + VS_B  - 1) && (cnt_vs < CNT_VS_R);//场同步的第一个320行
    assign en_vs_g = (cnt_vs > CNT_VS_R  - 1) && (cnt_vs < CNT_VS_G);   //场同步的第二个320行
    assign en_vs_b = (cnt_vs > CNT_VS_G  - 1) && (cnt_vs < CNT_VS_B);   //场同步的第三个320行
    
    assign video_de = en_hs && en_vs;//将HDMI显示的有效像素点位置全部标注出来了
                    
    always @ (posedge clk, negedge rst_n)
        if (!rst_n)
            hdmi_rgb <= 24'b00000000_00000000_00000000;
        else
            if (video_de)
                if (en_vs_r)
                    hdmi_rgb <= 24'b00000000_00000000_11111111;                    // 红
                else if (en_vs_g)
                        hdmi_rgb <= 24'b00000000_11111111_00000000;                // 绿
                else if (en_vs_b)
                        hdmi_rgb <= 24'b11111111_00000000_00000000;                // 蓝
                else
                        hdmi_rgb <= 24'b00000000_00000000_00000000;                //黑
            else
                hdmi_rgb <= 24'b00000000_00000000_00000000;                        // 黑
endmodule

PLL 的设置:

通过查表得知,

 

 



1280*720分辨率的像素时钟就是74.25M

 

 

 

 

ADV7513的配置:

ADV7513芯片控制解读(中文版)——基于DE10-NANO开发板——C5G 开发板

I2C 代码详细解析: https://zhuanlan.zhihu.com/p/543472995?

 

引脚配置

根据DE10-Nano 的 manual或者是schematic 文件完成一下的引脚配置:

 

 

实验现象:

DE10-Nano 开发板 拔掉SD卡,MSEL 设置到10010, 接上HDMI 显示器,开机,下载sof文件得到现象如下:

 

 

 

 

 

 

相关阅读:
友晶科技FPGA开发板DE10-Nano的HDMI彩条实验(一)——HDMI简介
友晶科技FPGA开发板DE10-Nano的HDMI彩条实验(二)——TMDS算法
友晶科技FPGA开发板DE10-Nano的HDMI彩条实验(三)——DE10-Nano 的HDMI电路简介

ADV7513芯片控制解读(中文版)——基于DE10-NANO开发板——C5G 开发板

基于FPGA控制的ADV7513芯片的I2C代码解析

DE10-Nano 的HDMI显示彩条实验遇到显示器显示“超频”

友晶科技FPGA开发板DE10-NANO的HDMI 方块移动实验