一、初衷

HDMI是之前项目的一部分,本来不打算上传博客的,最近我们专业课设开始,恰好可以选择完成HDMI显示,也重新整理一下之前的项目,对于课设,这只是实现了基本功能,附加条件等过几天再更;希望这篇博客能帮助更多的初学者,结尾附代码;

二、开发平台

这个项目开发板我使用的是Xilinx的zynq-7030,读者可进行更改管脚进行更换;调用了vivado的pll以及ROM的IP;读者需要进行配置,在此,我就不做介绍,请自行百度;

三、项目介绍

先将图片转为coe文件存入ROM中,从ROM中读取24位真彩数据通过HDMI进行显示,显示的大小设置为1280*1024,如下所示:

图片大小为500*500;读者可根据需要自行更改;

由于我正在一家公司实习,开发板无法使用,故没有展示环节,代码曾经下过开发板了,可以正常使用;故只提供仿真波形,如果有问题可以留言,我看到就会回复;

四、HDMI接口

英文全称:H-High,D-Definition,M-Multimedia,I-Interface;高清晰度多媒体接口。

HDMI的数据传输有TMDS0,TMDS1,TMDS2三个通道,每个通道的传输流程都是一样的:

  

如上图所示,发送端将8bit的数据进入TMDS编码器,得到抗干扰性强的10bit TMDS信号,然后再进行串行化输出,在接收端收到串行的HDMI信号后,进行信号复原,得到10bit的TMDS信号,最后用TMDS解码器解码得到原来的8bit数据。

本项目使用的是1.3版本的HDMI接口,它支持的最大速率为10.2Gbps,而1.3版本的一个HDMI包括3个TMDS数据通道和1个TMDS时钟通道。什么是TMDS呢?

——TMDS(Transition Minimized Differential signal),最小化传输差分信号。

下图能很好的解释差分信号的优势:

它能很好的屏蔽噪声的影响;

实际上,我们只需要完成发送端这部分,即:

第一步:将8位并行RED数据发送到TMDS Tx。

   第二步:进行最小化传输处理,加上第9位,即编码过程。第9位数据称为编码位。

    第三步:并/串转换。

第四步:串行转差分

对第二步进行补充:每个数据通道都通过编码算法(异或、异或非等),将8位数据转换成10位数据,前8位数据由原始信号经运算后获得,第9位指示运算的方式,第10位用来对应直流平衡。通过这种算法,会使得数据的传输和恢复更加可靠。

对传输速率及时钟的一些补充:

PCLK:像素时钟
以1920x1080p/60hz为例:1920*1080*60=124.4MHz
以1280x720p/60hz为例:1280*720*60=55.3MHz

带宽:1s内传输的数据量(bit)

4K频率需要的带宽:选最常用的3840x2160分辨率,色深的话常用的是8位,RGB三色就是24bit,我们的目标是60Hz刷新率(60fps)→→→ 3840*2160*24bit*60fps=11.94Gbps

HDMI1.3/1.4版本像素时钟高达340MHz,即最大带宽是:
       →→→ 340MHz*10bit(10bit编码)*3(3个数据通道)=10.2Gbps

但是由于HDMI采用的是8bit/10bit编码方式,实际效率是理论值的80%,所以10.2Gbps能传输的最大视频带宽是10.2*0.8=8.1Gbps

借鉴:(38条消息) HDMI接口简介---分辨率 时钟频率 lane速率计算_打怪升级ing的博客-CSDN博客_hdmi带宽计算https://blog.csdn.net/weixin_42229404/article/details/80461700

则本项目

-   频率:1280*1024*60 = 78.6Mhz,为什么不一样?我觉得可能是图像无效区也应该是进去;

- 实际频率:1688*1066*60 = 107.9Mhz,与定义的相同;

-  速率:108*10*3 = 3.24Gpbs;

五、代码讲解

       (1)顶层:

由于我使用的开发板输入的是差分时钟,所以输入时钟是两对;

注意观察可以发现,有个540M的时钟;由于将并行的10bit数据转换为串行的数据,时钟频率需要快10倍;但是是差分输出,所以只需要5倍时钟,即540M;

//**************************************************************************
// *** 名称 : hdmixs_top
// *** 作者 : 不想上体育课
// *** 博客 : https://blog.csdn.net/m0_47220307?type=blog
// *** 日期 : 2022.09
// *** 描述 : top
//**************************************************************************`timescale 1ns / 1ps
module hdmixs_top(input                                        sys_clk_n ,//差分时钟输入input                                        sys_clk_p ,input                                        sys_rst_n ,output                                       tmds_clk_n,//TMDS时钟通道output                                       tmds_clk_p,output         [2:0]                         tmds_data_n,//TMDS数据通道output         [2:0]                         tmds_data_p);wire                                             rst_n   ;
wire                                             clk_out1;
wire                                             clk_out2;
wire                                             locked;
wire                                             hdmi_hs;
wire                                             hdmi_vs;
wire              [10:0]                          w_x_pixel;
wire              [10:0]                          w_y_pixel;
// wire [15:0] pixel_data;
wire                                             hdmi_de;
wire              [23:0]                         rgb_data;
wire                                             tmds_oen;//TMDS输出使能
wire              [23:0]                         pixel_data;assign rst_n=sys_rst_n&locked;               //在保证时钟稳定的情况下,才保证正常工作
assign clk_out1 = sys_clk_n;
assign clk_out2 = sys_clk_p;clk_wiz_0 clk_div(.clk_out1                                  (clk_108M         ),   //输出108MHZ的频率.clk_out2                                  (clk_540M         ), .reset                                     (1'b0             ), .locked                                    (locked           ),.clk_in1_p                                 (sys_clk_p        ),.clk_in1_n                                 (sys_clk_n        )
);hdmixs_driver dri(.clk_out1                                  (clk_108M         ),.rst_n                                     (rst_n            ),.pixel_data                                (pixel_data       ),.hdmi_hs                                   (hdmi_hs          ),.hdmi_vs                                   (hdmi_vs          ),.hdmi_de                                   (hdmi_de          ),.vedio_rgb                                 (rgb_data         ),.x_pixel                                   (w_x_pixel        ),.y_pixel                                   (w_y_pixel        )
);hdmixs_display dis(.clk_out1                                  (clk_108M         ),.rst_n                                     (rst_n            ),.x_pixel                                   (w_x_pixel        ),.y_pixel                                   (w_y_pixel        ),.pixel_data                                (pixel_data       )
);rgb_to_hdmi urtg(.clk_out1                                  (clk_108M         ),  //输出108MHZ的频率.clk_out2                                  (clk_540M         ), .rst_n                                     (rst_n            ),.hdmi_de                                   (hdmi_de          ),.pixel_data                                (rgb_data         ),.hdmi_hs                                   (hdmi_hs          ),.hdmi_vs                                   (hdmi_vs          ),.tmds_clk_n                                (tmds_clk_n       ),.tmds_clk_p                                (tmds_clk_p       ),.tmds_oen                                  (tmds_oen         ),.tmds_data_n                               (tmds_data_n      ),.tmds_data_p                               (tmds_data_p      )
);endmodule

       (2) 显示驱动设置:

此模块可以定义显示的屏幕设置,以及输出当前行列计数值和图像数据;

//**************************************************************************
// *** 名称 : hdmixs_driver
// *** 作者 : 不想上体育课
// *** 博客 : https://blog.csdn.net/m0_47220307?type=blog
// *** 日期 : 2022.09
// *** 描述 : 显示大小设置
//**************************************************************************`timescale 1ns / 1ps
module hdmixs_driver(input                    clk_out1  ,input                    rst_n     ,input      [23:0]        pixel_data,output      reg          hdmi_de   ,output                   hdmi_hs   ,   output                   hdmi_vs   ,output     [23:0]        vedio_rgb ,output     [ 10:0]       y_pixel   ,  //y像素坐标output     [ 10:0]       x_pixel      //x像素坐标);//1280*1024@60Hz 108Mhz
parameter Hor_Total_Time              =      11'd1688;        //
parameter Hor_Sync                    =      10'd112;     //
parameter Hor_Back_Porch              =      10'd248;     //
parameter Hor_Addr_Time               =      11'd1280;        //
parameter Hor_Front_Porch             =      10'd48;      //parameter Ver_Total_Time              =      11'd1066;      //
parameter Ver_Sync                    =      10'd3;           //
parameter Ver_Back_Porch              =      10'd38;      //
parameter Ver_Addr_Time               =      11'd1024;        //
parameter Ver_Front_Porch             =      10'd1;           // //行列计数器
reg [10:0] x_cnt;
reg [10:0] y_cnt;always@(posedge clk_out1 or negedge rst_n)beginif(!rst_n)begin x_cnt<= 11'd0;y_cnt<= 11'd0;end else if(x_cnt==Hor_Total_Time)begin x_cnt<= 11'd0;if(y_cnt==Ver_Total_Time)y_cnt<=11'd0;elsey_cnt<= y_cnt+1'b1;endelse x_cnt<= x_cnt + 1'b1;endassign hdmi_hs=(x_cnt < Hor_Sync)?1'b0:1'b1;
assign hdmi_vs=(y_cnt < Ver_Sync)?1'b0:1'b1;always@(*)     //使能、以及得到像素坐标beginhdmi_de<=(x_cnt>(Hor_Sync + Hor_Back_Porch)&&x_cnt<=(Hor_Sync+Hor_Back_Porch+Hor_Addr_Time)&&y_cnt>(Ver_Sync+Ver_Back_Porch)&&y_cnt<=(Ver_Sync+Ver_Back_Porch+Ver_Addr_Time));endassign vedio_rgb=(hdmi_de)?pixel_data:24'd0;
assign x_pixel=(hdmi_de)?(x_cnt-(Hor_Sync + Hor_Back_Porch)):10'd0;        //行像素坐标
assign y_pixel=(hdmi_de)?(y_cnt-(Ver_Sync + Ver_Back_Porch)):10'd0;       //列像素坐标endmodule

     (3)图像显示模块

此模块可以设置需要显示的图片大小及位置,并输出图像;

//**************************************************************************
// *** 名称 : hdmixs_display
// *** 作者 : 不想上体育课
// *** 博客 : https://blog.csdn.net/m0_47220307?type=blog
// *** 日期 : 2022.09
// *** 描述 : 显示图像区域设置
//**************************************************************************
`timescale 1ns / 1ps
module hdmixs_display(input           wire                clk_out1  ,input           wire                rst_n     ,input           wire    [10:0]      x_pixel   ,input           wire    [10:0]      y_pixel   ,output          reg     [23:0]      pixel_data
);parameter height = 10'd500, width  = 10'd500;
parameter pos_x0 = 320, pos_y0 = 272;// picture  wire               rom_rd_en0;        //读ROM使能信号
wire [32:0]        total;
wire [23:0]        rom_data0;reg  [23:0]        rom_addr0;  //读ROM有效信号 assign total = height*width;assign rom_rd_en0 =(x_pixel > pos_x0)&&(x_pixel<=pos_x0+width)&&(y_pixel>pos_y0)&&(y_pixel<=pos_y0+height)?1'b1:1'b0;       //first picture locationalways @(posedge clk_out1 or  negedge rst_n)begin if(!rst_n)beginpixel_data  <=  24'b0;endelse if(rom_rd_en0)pixel_data  <=  rom_data0;elsepixel_data  <=  24'h000_000;endalways@(posedge clk_out1 or negedge rst_n)beginif(!rst_n)rom_addr0<=24'd0;else if(rom_rd_en0)beginif(rom_addr0<total-1'b1)rom_addr0<=rom_addr0+1'b1;else rom_addr0<=24'd0;endelse rom_addr0<=rom_addr0;endblk_mem_gen_0 rom1(.addra(rom_addr0),.ena(1),.clka(clk_out1),.douta(rom_data0)); endmodule

        (4)rgb2hdmi模块

这个模块例化了其他两个子模块;实现了8bit/10bit,以及并行转串行;并使用原语OBUFDS进行串行转差分;

//**************************************************************************
// *** 名称 : rgb_to_hdmi
// *** 作者 : 不想上体育课
// *** 博客 : https://blog.csdn.net/m0_47220307?type=blog
// *** 日期 : 2022.09
// *** 描述 : 差分输出
//**************************************************************************`timescale 1ns / 1ps
module rgb_to_hdmi(input                     clk_out1    ,input                     clk_out2    ,input                     rst_n       ,input                     hdmi_de     ,input     [24:0]          pixel_data  ,input                     hdmi_hs     ,input                     hdmi_vs     ,output                    tmds_clk_n  ,output                    tmds_clk_p  ,  output                    tmds_oen    ,  output     [2:0]          tmds_data_n ,output     [2:0]          tmds_data_p );wire        [9:0]             clk_10bit;wire                          syn_rst;wire        [9:0]             encode_red;wire        [9:0]             encode_green;wire        [9:0]             encode_blue;wire        [2:0]             serial_data;wire                          serial_out_clk;assign clk_10bit=10'b11111_00000;
assign tmds_oen=1'b1;asyn_to_syn syn(
.clk(clk_out1),
.rst_n(rst_n),
.syn_rst(syn_rst)
);encoder r(.clkin(clk_out1),    .rstin(syn_rst),   .din(pixel_data[23:16]),    .c0(1'b0),     .c1(1'b0),      .de(hdmi_de),      .dout(encode_red)
);encoder g(.clkin(clk_out1),    .rstin(syn_rst),   .din(pixel_data[15:8]),    .c0(1'b0),     .c1(1'b0),      .de(hdmi_de),      .dout(encode_green)
);encoder b(.clkin(clk_out1),    .rstin(syn_rst),   .din(pixel_data[7:0]),    .c0(hdmi_hs),     .c1(hdmi_vs),      .de(hdmi_de),      .dout(encode_blue)
);serializer red(.paralell_data(encode_red),.paralell_clk(clk_out1),.reset(syn_rst),.serial_clk(clk_out2),.serial_data_out(serial_data[2])
);serializer green(.paralell_data(encode_green),.paralell_clk(clk_out1),.reset(syn_rst),.serial_clk(clk_out2),.serial_data_out(serial_data[1])
);serializer blue(.paralell_data(encode_blue),.paralell_clk(clk_out1),.reset(syn_rst),.serial_clk(clk_out2),.serial_data_out(serial_data[0])
);serializer clk(.paralell_data(clk_10bit),.paralell_clk(clk_out1),.reset(syn_rst),.serial_clk(clk_out2),.serial_data_out(serial_out_clk)
);OBUFDS #(.IOSTANDARD("TMDS_33"), // Specify the output I/O standard.SLEW("SLOW") // Specify the output slew rate
) TMDS0 (.O(tmds_data_p[0]), // Diff_p output (connect directly to top-level port).OB(tmds_data_n[0]), // Diff_n output (connect directly to top-level port).I(serial_data[0]) // Buffer input
);OBUFDS #(.IOSTANDARD("TMDS_33"), // Specify the output I/O standard.SLEW("SLOW") // Specify the output slew rate
) TMDS1 (.O(tmds_data_p[1]), // Diff_p output (connect directly to top-level port).OB(tmds_data_n[1]), // Diff_n output (connect directly to top-level port).I(serial_data[1]) // Buffer input
);OBUFDS #(.IOSTANDARD("TMDS_33"), // Specify the output I/O standard.SLEW("SLOW") // Specify the output slew rate
) TMDS2 (.O(tmds_data_p[2]), // Diff_p output (connect directly to top-level port).OB(tmds_data_n[2]), // Diff_n output (connect directly to top-level port).I(serial_data[2]) // Buffer input
);OBUFDS #(.IOSTANDARD("TMDS_33"), // Specify the output I/O standard.SLEW("SLOW") // Specify the output slew rate
) TMDS_clk (.O(tmds_clk_p), // Diff_p output (connect directly to top-level port).OB(tmds_clk_n), // Diff_n output (connect directly to top-level port).I(serial_out_clk) // Buffer input
);endmodule

       (5)编码模块:

实现了8bit/10bit

//**************************************************************************
// *** 名称 : encoder
// *** 作者 : 不想上体育课
// *** 博客 : https://blog.csdn.net/m0_47220307?type=blog
// *** 日期 : 2022.09
// *** 描述 : 编码模块
//**************************************************************************
`timescale 1ns / 1ps
module encoder(input                  clkin,    // pixel clock inputinput                  rstin,    // async. reset input (active high)input      [7:0]       din,      // data inputs: expect registeredinput                  c0,       // c0 inputinput                  c1,       // c1 inputinput                  de,       // de inputoutput reg [9:0]       dout      // data outputs
);// Counting number of 1s and 0s for each incoming pixel// component. Pipe line the result.// Register Data Input so it matches the pipe lined adder// outputreg [3:0] n1d; //number of 1s in dinreg [7:0] din_q;always @ (posedge clkin) beginn1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];din_q <=#1 din;end///// Stage 1: 8 bit -> 9 bit// Refer to DVI 1.0 Specification, page 29, Figure 3-5///wire decision1;assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
/*reg [8:0] q_m;always @ (posedge clkin) beginq_m[0] <=#1 din_q[0];q_m[1] <=#1 (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);q_m[2] <=#1 (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);q_m[3] <=#1 (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);q_m[4] <=#1 (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);q_m[5] <=#1 (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);q_m[6] <=#1 (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);q_m[7] <=#1 (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);q_m[8] <=#1 (decision1) ? 1'b0 : 1'b1;end
*/wire [8:0] q_m;assign q_m[0] = din_q[0];assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);assign q_m[8] = (decision1) ? 1'b0 : 1'b1;/// Stage 2: 9 bit -> 10 bit// Refer to DVI 1.0 Specification, page 29, Figure 3-5/reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_malways @ (posedge clkin) beginn1q_m  <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];n0q_m  <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);endparameter CTRLTOKEN0 = 10'b1101010100;parameter CTRLTOKEN1 = 10'b0010101011;parameter CTRLTOKEN2 = 10'b0101010100;parameter CTRLTOKEN3 = 10'b1010101011;reg [4:0] cnt; //disparity counter, MSB is the sign bitwire decision2, decision3;assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);/// [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]/assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));// pipe line alignmentreg       de_q, de_reg;reg       c0_q, c1_q;reg       c0_reg, c1_reg;reg [8:0] q_m_reg;always @ (posedge clkin) beginde_q    <=#1 de;de_reg  <=#1 de_q;c0_q    <=#1 c0;c0_reg  <=#1 c0_q;c1_q    <=#1 c1;c1_reg  <=#1 c1_q;q_m_reg <=#1 q_m;end///// 10-bit out// disparity counter///always @ (posedge clkin or posedge rstin) beginif(rstin) begindout <= 10'h0;cnt <= 5'h0;end else beginif (de_reg) beginif(decision2) begindout[9]   <=#1 ~q_m_reg[8]; dout[8]   <=#1 q_m_reg[8]; dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);end else beginif(decision3) begindout[9]   <=#1 1'b1;dout[8]   <=#1 q_m_reg[8];dout[7:0] <=#1 ~q_m_reg;cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);end else begindout[9]   <=#1 1'b0;dout[8]   <=#1 q_m_reg[8];dout[7:0] <=#1 q_m_reg[7:0];cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);endendend else begincase ({c1_reg, c0_reg})2'b00:   dout <=#1 CTRLTOKEN0;2'b01:   dout <=#1 CTRLTOKEN1;2'b10:   dout <=#1 CTRLTOKEN2;default: dout <=#1 CTRLTOKEN3;endcasecnt <=#1 5'h0;endendendendmodule

       (6)并行数据转串行

使用原语OSERDESE2进行串行转差分操作;

//**************************************************************************
// *** 名称 : serializer
// *** 作者 : 不想上体育课
// *** 博客 : https://blog.csdn.net/m0_47220307?type=blog
// *** 日期 : 2022.09
// *** 描述 : 并行数据转串行
//**************************************************************************`timescale 1ns / 1ps
module serializer(input                reset       ,input                paralell_clk,    //并行input [9:0]          paralell_data,input                serial_clk,     //串行,比并行数据高output               serial_data_out);wire                    cascade1;wire                    cascade2;OSERDESE2 #(.DATA_RATE_OQ("DDR"),   // DDR, SDR.DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR.DATA_WIDTH(10),         // Parallel data width (2-8,10,14).SERDES_MODE("MASTER"), // MASTER, SLAVE.TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE).TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE).TRISTATE_WIDTH(1)      // 3-state converter width (1,4))OSERDESE2_MAS (.CLK(serial_clk),             // 1-bit input: High speed clock.CLKDIV(paralell_clk),       // 1-bit input: Divided clock.RST(reset),             // 1-bit input: Reset.OCE(1'b1),             // 1-bit input: Output data clock enable.OQ(serial_data_out),               // 1-bit output: Data path output// D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each).D1(paralell_data[0]),.D2(paralell_data[1]),.D3(paralell_data[2]),.D4(paralell_data[3]),.D5(paralell_data[4]),.D6(paralell_data[5]),.D7(paralell_data[6]),.D8(paralell_data[7]),.SHIFTOUT1(),.SHIFTOUT2(),.SHIFTIN1(cascade1),   .SHIFTIN2(cascade2),.OFB(),             // 1-bit output: Feedback path for data// T1 - T4: 1-bit (each) input: Parallel 3-state inputs.T1(1'b0),.T2(1'b0),.T3(1'b0),.T4(1'b0),.TBYTEIN(1'b0),     // 1-bit input: Byte group tristate.TCE(1'b0),              // 1-bit input: 3-state clock enable.TBYTEOUT(),   // 1-bit output: Byte group tristate.TFB(),             // 1-bit output: 3-state control.TQ()               // 1-bit output: 3-state control);OSERDESE2 #(.DATA_RATE_OQ("DDR"),   // DDR, SDR.DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR.DATA_WIDTH(10),         // Parallel data width (2-8,10,14).SERDES_MODE("SLAVE"), // MASTER, SLAVE.TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE).TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE).TRISTATE_WIDTH(1)      // 3-state converter width (1,4))OSERDESE2_SLA (.CLK(serial_clk),             // 1-bit input: High speed clock.CLKDIV(paralell_clk),       // 1-bit input: Divided clock.RST(reset),             // 1-bit input: Reset.OCE(1'b1),             // 1-bit input: Output data clock enable.OQ(),               // 1-bit output: Data path output// D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each).D1(1'b0),.D2(1'b0),.D3(paralell_data[8]),.D4(paralell_data[9]),.D5(1'b0),.D6(1'b0),.D7(1'b0),.D8(1'b0),.SHIFTOUT1(cascade1),.SHIFTOUT2(cascade2),.SHIFTIN1(),      .SHIFTIN2(),.OFB(),             // 1-bit output: Feedback path for data// T1 - T4: 1-bit (each) input: Parallel 3-state inputs.T1(1'b0),.T2(1'b0),.T3(1'b0),.T4(1'b0),.TBYTEIN(1'b0),     // 1-bit input: Byte group tristate.TCE(1'b0),              // 1-bit input: 3-state clock enable.TBYTEOUT(),   // 1-bit output: Byte group tristate.TFB(),             // 1-bit output: 3-state control.TQ()              // 1-bit output: 3-state control);endmodule

   (7)同步模块

对复位进行同步处理(异步复位,同步释放);

//**************************************************************************
// *** 名称 : asyn_to_syn
// *** 作者 : 不想上体育课
// *** 博客 : https://blog.csdn.net/m0_47220307?type=blog
// *** 日期 : 2022.09
// *** 描述 : 同步处理模块
//**************************************************************************
`timescale 1ns / 1ps
module asyn_to_syn(input      clk,input      rst_n,output     syn_rst);reg rst_1;
reg rst_2;assign syn_rst=rst_2;
always @(posedge clk or negedge rst_n)beginif(!rst_n)begin rst_1<=1'b1;rst_2<=1'b1;endelsebegin rst_1<=1'b0;rst_2<=rst_1;endendendmodule

六、Testbench编写

由于使用的是差分时钟,使用需要产生一个差分时钟:

//**************************************************************************
// *** 名称 : tb_hdmixs_top
// *** 作者 : 不想上体育课
// *** 博客 : https://blog.csdn.net/m0_47220307?type=blog
// *** 日期 : 2022.09
// *** 描述 : 测试模块
//**************************************************************************
·timescale 1ns/1ps
module tb_hdmixs_top();reg                                          sys_clk_n   ;
reg                                          sys_clk_p   ;
reg                                          sys_rst_n   ;wire                                         tmds_clk_n  ;//TMDS时钟通道
wire                                         tmds_clk_p  ;
wire           [2:0]                         tmds_data_n ;//TMDS数据通道
wire           [2:0]                         tmds_data_p ;initialbeginsys_clk_p = 1'b0;sys_clk_n = 1'b1;sys_rst_n <= 1'b0;#20sys_rst_n <= 1'b1;endalways #2.5 sys_clk_p = ~sys_clk_p;
always #2.5 sys_clk_n = ~sys_clk_n;hdmixs_top hdmixs_top_inst(.sys_clk_n   (sys_clk_n  ),.sys_clk_p   (sys_clk_p  ),.sys_rst_n   (sys_rst_n  ),.tmds_clk_n  (tmds_clk_n ),//TMDS时钟通道.tmds_clk_p  (tmds_clk_p ),.tmds_data_n (tmds_data_n),//TMDS数据通道.tmds_data_p (tmds_data_p));endmodule

七、Vivado仿真结果与COE对比

读取的数据与COE文件一致。

HDMI接口介绍及其代码相关推荐

  1. 常见视频接口介绍,VGA,YPbPr,DVI,HDMI,DisplayPort

    1,VGA(D-SUB) 这种是显示器最常见的,用了很多年,色域空间是RGB,也就是红绿蓝,模拟信号,无音频 插头是15针的,实际所需的最小针数应该是5针,也就是RGB三色信号,水平同步信号,垂直同步 ...

  2. VGA、DVI、HDMI、DP 接口介绍及优劣

    VGA.DVI.HDMI.DP 接口介绍及优劣   随着日新月异的发展,就目前显卡上面常见的输出接口而言,我们所熟知的有以下几种: VGA.DVI.HDMI和DP (DisplayPort). 这四种 ...

  3. 网络云盘项目——HTTP接口介绍、功能介绍、服务端/客户端代码解析

    一.本文目的 本项目分为6篇博客文章完成: 1.项目总体介绍:https://blog.csdn.net/qq_41453285/article/details/107871393. 2.Redis部 ...

  4. ROS学习笔记52--rosbag图片从compressed格式转raw格式代码实现接口介绍

    背景:操作rosbag,目的将图片的compressed格式转raw格式,让后进行操作.发现python并没有对应的工具接口实现,而image_transport接口用起来也没有时效性(总不能将bag ...

  5. VGA、DVI、HDMI等常见视频接口介绍

    HDMI 高清晰度多媒体接口(英文:High Definition Multimedia Interface,HDMI)是一种数字化视频/音频接口技术,是适合影像传输的专用型数字化接口,其可同时传送音 ...

  6. HDMI接口电路设计

    HDMI接口电路设计 - 知乎 HDMI硬件接口设计 - 走看看 HDMI是高清晰度多媒体接口的数字化视频.音频接口技术,它分为HDMI A Type.HDMI B Type.HDMI C Type. ...

  7. php如何实现用户报警,php封装实现钉钉机器人报警接口的示例代码

    php封装实现钉钉机器人报警接口的示例代码,的是,机器人,接口,本文,消息 php封装实现钉钉机器人报警接口的示例代码 易采站长站,站长之家为您整理了php封装实现钉钉机器人报警接口的示例代码的相关内 ...

  8. 实现一个对象验证库系列 -- 1) 接口介绍以及总体思路概述 (请大神批评)

    前情回顾: 上一篇 0) 目录以及库结构介绍 简单描述了下库的代码结构 本文将从接口部分阐述总体的思路 1) 接口介绍以及总体思路概述 如下图,我总共定义了10个Interface 这些实际可分为两类 ...

  9. vbyone接口引脚定义_一文了解A、B、C、D、E 5 种HDMI接口类型!网友:今天总算明白了...

    如今在电脑中,VGA模拟接口.DVI数字接口逐渐淘汰,而高清的HDMI已经成为目前主流视频接口.那么什么是HDMI接口?它有什么用?有哪些版本?有几种类型?HDMI接口的针脚是什么?带着众多问题下面帝 ...

最新文章

  1. OpenAI教GPT-3学会上网,「全知全能」的AI模型上线了
  2. 【Spring注解系列14】@Profile进行环境切换
  3. 非UI线程下页面处理:view的postInvalidate和post对消息处理的差异化
  4. Linux中添加和删除用户
  5. Taro+react开发(2)--简介2
  6. sql 计算单行数据字段空值比例_如何利用工具,迅猛定位低效SQL? | 1分钟系列...
  7. 《TensorFlow 2.0深度学习算法实战教材》学习笔记(二、回归问题和分类问题)
  8. 〖Linux〗zigbee实验之cc2430的cc debugger固件升级实录
  9. linux内核数据链路层,Linux网络内核数据帧的接收进程:数据链路层(概念篇)...
  10. ISO7637-2测试case汇总
  11. mysql pxc介绍_MySQL高可用——PXC简介
  12. html设置为壁纸win10,Win10让桌面壁纸自动换的设置方法(图文教程)
  13. java微信开发教程,Java微信公众平台开发(1) 接入微信公众平台
  14. 车牌识别系列(二)生成具有真实感的(realistic)车牌数据
  15. 大数据、物联网、云计算
  16. 高中数学40分怎么办_高二了数学40多分还有救吗?
  17. 【wordpress】文章编辑器插件
  18. android Wifi自动连接
  19. Min3D测试-在Android里面载入MMD模型-快速3D模型显示测试-By黑月君
  20. Python基础语法七:元组字典和集合

热门文章

  1. HTTPS://WWW.CNBLOGS.COM/ANDROID-JOKER/P/4414891.HTML https://www.cnblogs.com/android-joker/p/4414891
  2. C#中的Attribute详解(下)
  3. 攻防世界Mary_Morton wp
  4. matlab三角衍射,MATLAB模拟衍射利用基尔霍夫衍射公式
  5. python之Windows安装以及配置环境(全网最详细)
  6. Google Hack搜索技巧
  7. 微信小程序 腾讯位置服务地图选点和路线规划
  8. 软件工程课程设计——教务辅助管理系统
  9. NLP(二)文本生成 --VAE与GAN模型和迁移学习
  10. lightoj 1042 - Secret Origins 【数学】