• 【接口协议】基于 FPGA 的 HMDI 彩条显示实验


    目录

    HDMI 介绍

    HDMI 引脚定义

    TMDS 介绍

    编码模块

    代码实现

    并转串模块

    视频时序标准

    传输通道顶层

    顶层模块

    工程搭建


    HDMI 介绍

    HDMI,高清晰度多媒体接口(High Definition Multimedia Interface)是标准的数字化视频/音频接口技术,可用于机顶盒、DVD播放机、个人电脑与电视机。HDMI可以同时传送音频和影音信号,能高品质地传输未经压缩的高清视频和多声道音频数据,最高数据传输速度为 50Gbps 左右。

    HDMI 引脚定义

    常见的 HDMI 有19 根 pin,此外还有二十多跟 pin 脚的 HDMI 接口这里也只介绍此类常见的 HDMI接口,接口序号和定义如下:

    引脚

    信号

    引脚

    信号

    1

    数据2+

    11

    时钟屏蔽

    2

    数据2屏蔽

    12

    时钟-

    3

    数据2-

    13

    CEC

    4

    数据1+

    14

    保留

    5

    数据1屏蔽

    15

    SCL

    6

    数据1-

    16

    SDA

    7

    数据0+

    17

    DDC/CEC地

    8

    数据0屏蔽

    18

    +5v电源

    9

    数据0-

    19

    热插拔检测

    10

    时钟+

    TMDS 介绍

    过渡调制差分信号,也被称为最小化传输差分信号,是指通过异或及异或非等逻辑算法将原始信号数据转换成 10 位,前 8 位数据由原始信号经运算后获得,第9位指示运算的方式,第 10 位用来对应直流平衡(DC-balanced,就是指在编码过程中保证信道中直流偏移为零,电平转化实现不同逻辑接口间的匹配),转换后的数据以差分传动方式传送。

    下图为 HDMI 链路的框架图

    TMDS 的链路如下图所示,可以看到链路主要有两部分:source 和 sink 端,source 端为传输数据的起始端,sink 端为传输数据的目的端。同时链路由四条通道组成,分别为蓝色通道、、绿色通道、红色通道和时钟通道。

    蓝色通道

    蓝色通道包含8位的蓝色数据通道,两位的行同步和场同步信号,以及四位的音频信号。

    绿色通道

    绿色通道包含8位的绿色数据通道,两位的控制信号,以及四位的音频信号。

    红色通道

    红色通道包含8位的红色数据通道,两位的控制信号,以及四位的音频信号。

    时钟通道

    为什么要导读设立一个时钟通道呢?这是为了使source端和sink端的数据保持在同一个pixel clock下,便于数据的稳定发送和接收。

    在 source 端,每个通道的中还包含 Encoder 和 Serializer 模块,即编码模块和并转串模块,对应到 sink 端为解码模块和串转并模块。

    在编码阶段,编码器将视频源中的像素数据、HDMI的音频/附件数据,以及行、场同步信号分别编码成10位的字符流。

    在并串转换阶段将上述的10位字符流转换成串行数据流,并将其从三个差分输出通道发送出去。这个10:1的并转串过程所产生的串行速率是实际像素时钟速率的10倍。但是在并转串中采用的为DDR即双沿采样,因此时钟频率可以减小为原来的一半,也就是像素时钟的 5 倍。

    编码模块

    下图为 TMDS 的编码算法的流程示意图,每一个数据通道都通过编码算法,将 8 位的视、音频数据转换成最小化传输、直流平衡的 10 位数据。这使得数据的传输和恢复更加可靠。最小化传输差分信号是通过异或及异或非等逻辑算法将原始 8位信号数据转换成 10 位,前 8 为数据由原始信号经运算后获得,第 9 位指示运算的方式,第 10位用来对应直流平衡。这种算法可以减小传输信号过程的上冲和下冲,什么是上冲和下冲呢,顾名思义上冲就是由0转变为1,下冲就是由1转变为0,如果频繁的上下冲就会导致信号传输不稳定,而DC平衡使信号对传输线的电磁干扰减少,DC平衡指的是在码流中0和1的个数相当。总结来说,信号频繁的0、1变化和0和1数量不均衡都会影响信号的质量,编码的目的就在于此。

    代码实现

    这个编码代码可以直接调用Xilinx官网的,在例化此模块时,需要对每个通道分别进行例化。

    1. //
    2. //
    3. // Xilinx, Inc. 2008 www.xilinx.com
    4. //
    5. //
    6. //
    7. // File name : encode.v
    8. //
    9. // Description : TMDS encoder
    10. //
    11. // Date - revision : Jan. 2008 - v 1.0
    12. //
    13. // Author : Bob Feng
    14. //
    15. // Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
    16. // provided to you "as is". Xilinx and its licensors make and you
    17. // receive no warranties or conditions, express, implied,
    18. // statutory or otherwise, and Xilinx specifically disclaims any
    19. // implied warranties of merchantability, non-infringement,or
    20. // fitness for a particular purpose. Xilinx does not warrant that
    21. // the functions contained in these designs will meet your
    22. // requirements, or that the operation of these designs will be
    23. // uninterrupted or error free, or that defects in the Designs
    24. // will be corrected. Furthermore, Xilinx does not warrantor
    25. // make any representations regarding use or the results of the
    26. // use of the designs in terms of correctness, accuracy,
    27. // reliability, or otherwise.
    28. //
    29. // LIMITATION OF LIABILITY. In no event will Xilinx or its
    30. // licensors be liable for any loss of data, lost profits,cost
    31. // or procurement of substitute goods or services, or for any
    32. // special, incidental, consequential, or indirect damages
    33. // arising from the use or operation of the designs or
    34. // accompanying documentation, however caused and on any theory
    35. // of liability. This limitation will apply even if Xilinx
    36. // has been advised of the possibility of such damage. This
    37. // limitation shall apply not-withstanding the failure of the
    38. // essential purpose of any limited remedies herein.
    39. //
    40. // Copyright © 2006 Xilinx, Inc.
    41. // All rights reserved
    42. //
    43. //
    44. `timescale 1 ps / 1ps
    45. module encode (
    46. input clkin, // pixel clock input
    47. input rstin, // async. reset input (active high)
    48. input [7:0] din, // data inputs: expect registered
    49. input c0, // c0 input
    50. input c1, // c1 input
    51. input de, // de input
    52. output reg [9:0] dout // data outputs
    53. );
    54. // Counting number of 1s and 0s for each incoming pixel
    55. // component. Pipe line the result.
    56. // Register Data Input so it matches the pipe lined adder
    57. // output
    58. reg [3:0] n1d; //number of 1s in din
    59. reg [7:0] din_q;
    60. always @ (posedge clkin) begin
    61. n1d <= din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];
    62. din_q <= din;
    63. end
    64. ///
    65. // Stage 1: 8 bit -> 9 bit
    66. // Refer to DVI 1.0 Specification, page 29, Figure 3-5
    67. ///
    68. wire decision1;
    69. assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
    70. /*
    71. reg [8:0] q_m;
    72. always @ (posedge clkin) begin
    73. q_m[0] <=#1 din_q[0];
    74. q_m[1] <=#1 (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
    75. q_m[2] <=#1 (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
    76. q_m[3] <=#1 (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
    77. q_m[4] <=#1 (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
    78. q_m[5] <=#1 (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
    79. q_m[6] <=#1 (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
    80. q_m[7] <=#1 (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
    81. q_m[8] <=#1 (decision1) ? 1'b0 : 1'b1;
    82. end
    83. */
    84. wire [8:0] q_m;
    85. assign q_m[0] = din_q[0];
    86. assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
    87. assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
    88. assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
    89. assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
    90. assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
    91. assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
    92. assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
    93. assign q_m[8] = (decision1) ? 1'b0 : 1'b1;
    94. /
    95. // Stage 2: 9 bit -> 10 bit
    96. // Refer to DVI 1.0 Specification, page 29, Figure 3-5
    97. /
    98. reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_m
    99. always @ (posedge clkin) begin
    100. n1q_m <= q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
    101. n0q_m <= 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]);
    102. end
    103. parameter CTRLTOKEN0 = 10'b1101010100;
    104. parameter CTRLTOKEN1 = 10'b0010101011;
    105. parameter CTRLTOKEN2 = 10'b0101010100;
    106. parameter CTRLTOKEN3 = 10'b1010101011;
    107. reg [4:0] cnt; //disparity counter, MSB is the sign bit
    108. wire decision2, decision3;
    109. assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
    110. /
    111. // [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]
    112. /
    113. assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));
    114. // pipe line alignment
    115. reg de_q, de_reg;
    116. reg c0_q, c1_q;
    117. reg c0_reg, c1_reg;
    118. reg [8:0] q_m_reg;
    119. always @ (posedge clkin) begin
    120. de_q <= de;
    121. de_reg <= de_q;
    122. c0_q <= c0;
    123. c0_reg <= c0_q;
    124. c1_q <= c1;
    125. c1_reg <= c1_q;
    126. q_m_reg <= q_m;
    127. end
    128. ///
    129. // 10-bit out
    130. // disparity counter
    131. ///
    132. always @ (posedge clkin or posedge rstin) begin
    133. if(rstin) begin
    134. dout <= 10'h0;
    135. cnt <= 5'h0;
    136. end else begin
    137. if (de_reg) begin
    138. if(decision2) begin
    139. dout[9] <= ~q_m_reg[8];
    140. dout[8] <= q_m_reg[8];
    141. dout[7:0] <= (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
    142. cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);
    143. end else begin
    144. if(decision3) begin
    145. dout[9] <= 1'b1;
    146. dout[8] <= q_m_reg[8];
    147. dout[7:0] <= ~q_m_reg[7:0];
    148. cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
    149. end else begin
    150. dout[9] <= 1'b0;
    151. dout[8] <= q_m_reg[8];
    152. dout[7:0] <= q_m_reg[7:0];
    153. cnt <= cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
    154. end
    155. end
    156. end else begin
    157. case ({c1_reg, c0_reg})
    158. 2'b00: dout <= CTRLTOKEN0;
    159. 2'b01: dout <= CTRLTOKEN1;
    160. 2'b10: dout <= CTRLTOKEN2;
    161. default: dout <= CTRLTOKEN3;
    162. endcase
    163. cnt <= 5'h0;
    164. end
    165. end
    166. end
    167. endmodule

    并转串模块

    并串模块可以直接调用原语OSERDESE2,该原语可以将并行数据转为串行数据,支持的位宽为2-8、10、14,并且支持DDR还是SDR采样等模式配置,经过并转串原语出来的串行数据,由于TMDS的传输为差分信号,因此还需要将单端信号转变为差分信号,同样也可以借用原语实现,OBUFDS就可以实现这样的功能,将输出的单端信号转为差分信号。注意需要对每个通道进行例化。

    1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    2. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    3. // Author : Linest-5
    4. // File : serial10_1.v
    5. // Create : 2022-10-04 15:41:01
    6. // Revise : 2022-10-04 17:07:13
    7. // Module Name :
    8. // Description :
    9. // Editor : sublime text3, tab size (4)
    10. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    11. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    12. module serial10_1(
    13. input divclk, //并行时钟
    14. input serclk, //串行时钟
    15. input rst,
    16. input [9:0] din,
    17. output do_p,
    18. output do_n
    19. );
    20. reg init_rst;
    21. wire cascade_di1;
    22. wire cascade_di2;
    23. wire dout;
    24. always @(posedge divclk or posedge rst) begin
    25. if (rst) begin
    26. init_rst <= 'd1;
    27. end
    28. else begin
    29. init_rst <= 'd0;
    30. end
    31. end
    32. OBUFDS #(
    33. .IOSTANDARD("DEFAULT"), // Specify the output I/O standard
    34. .SLEW("SLOW") // Specify the output slew rate
    35. ) OBUFDS_inst (
    36. .O(do_p), // Diff_p output (connect directly to top-level port)
    37. .OB(do_n), // Diff_n output (connect directly to top-level port)
    38. .I(dout) // Buffer input
    39. );
    40. OSERDESE2 #(
    41. .DATA_RATE_OQ("DDR"), // DDR, SDR
    42. .DATA_RATE_TQ("SDR"), // DDR, BUF, SDR 控制OQ输出的buffer是输出还是三态
    43. .DATA_WIDTH(10), // Parallel data width (2-8,10,14)
    44. .INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1)
    45. .INIT_TQ(1'b0), // Initial value of TQ output (1'b0,1'b1)
    46. .SERDES_MODE("MASTER"), // MASTER, SLAVE
    47. .SRVAL_OQ(1'b0), // OQ output value when SR is used (1'b0,1'b1)
    48. .SRVAL_TQ(1'b0), // TQ output value when SR is used (1'b0,1'b1)
    49. .TBYTE_CTL("FALSE"), // Enable tristate byte operation (FALSE, TRUE)
    50. .TBYTE_SRC("FALSE"), // Tristate byte source (FALSE, TRUE)
    51. .TRISTATE_WIDTH(1) // 3-state converter width (1,4)
    52. )
    53. OSERDESE2_inst_M (
    54. .OFB(), // 1-bit output: Feedback path for data
    55. .OQ(dout), // 1-bit output: Data path output
    56. // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
    57. .SHIFTOUT1(),
    58. .SHIFTOUT2(),
    59. .TBYTEOUT(), // 1-bit output: Byte group tristate
    60. .TFB(), // 1-bit output: 3-state control
    61. .TQ(), // 1-bit output: 3-state control
    62. .CLK(serclk), // 1-bit input: High speed clock
    63. .CLKDIV(divclk), // 1-bit input: Divided clock
    64. // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
    65. .D1(din[0]),
    66. .D2(din[1]),
    67. .D3(din[2]),
    68. .D4(din[3]),
    69. .D5(din[4]),
    70. .D6(din[5]),
    71. .D7(din[6]),
    72. .D8(din[7]),
    73. .OCE(1'b1), // 1-bit input: Output data clock enable
    74. .RST(init_rst), // 1-bit input: Reset
    75. // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
    76. .SHIFTIN1(cascade_di1),
    77. .SHIFTIN2(cascade_di2),
    78. // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
    79. .T1(0),
    80. .T2(0),
    81. .T3(0),
    82. .T4(0),
    83. .TBYTEIN(0), // 1-bit input: Byte group tristate
    84. .TCE(0) // 1-bit input: 3-state clock enable
    85. );
    86. OSERDESE2 #(
    87. .DATA_RATE_OQ("DDR"), // DDR, SDR
    88. .DATA_RATE_TQ("SDR"), // DDR, BUF, SDR 控制OQ输出的buffer是输出还是三态
    89. .DATA_WIDTH(10), // Parallel data width (2-8,10,14)
    90. .INIT_OQ(1'b0), // Initial value of OQ output (1'b0,1'b1)
    91. .INIT_TQ(1'b0), // Initial value of TQ output (1'b0,1'b1)
    92. .SERDES_MODE("SLAVE"), // MASTER, SLAVE
    93. .SRVAL_OQ(1'b0), // OQ output value when SR is used (1'b0,1'b1)
    94. .SRVAL_TQ(1'b0), // TQ output value when SR is used (1'b0,1'b1)
    95. .TBYTE_CTL("FALSE"), // Enable tristate byte operation (FALSE, TRUE)
    96. .TBYTE_SRC("FALSE"), // Tristate byte source (FALSE, TRUE)
    97. .TRISTATE_WIDTH(1) // 3-state converter width (1,4)
    98. )
    99. OSERDESE2_inst_S (
    100. .OFB(), // 1-bit output: Feedback path for data
    101. .OQ(), // 1-bit output: Data path output
    102. // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
    103. .SHIFTOUT1(cascade_di1),
    104. .SHIFTOUT2(cascade_di2),
    105. .TBYTEOUT(), // 1-bit output: Byte group tristate
    106. .TFB(), // 1-bit output: 3-state control
    107. .TQ(), // 1-bit output: 3-state control
    108. .CLK(serclk), // 1-bit input: High speed clock
    109. .CLKDIV(divclk), // 1-bit input: Divided clock
    110. // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
    111. .D1(),
    112. .D2(),
    113. .D3(din[8]),
    114. .D4(din[9]),
    115. .D5(0),
    116. .D6(0),
    117. .D7(0),
    118. .D8(0),
    119. .OCE(1'b1), // 1-bit input: Output data clock enable
    120. .RST(init_rst), // 1-bit input: Reset
    121. // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
    122. .SHIFTIN1(),
    123. .SHIFTIN2(),
    124. // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
    125. .T1(0),
    126. .T2(0),
    127. .T3(0),
    128. .T4(0),
    129. .TBYTEIN(0), // 1-bit input: Byte group tristate
    130. .TCE(0) // 1-bit input: 3-state clock enable
    131. );
    132. endmodule

    视频时序标准

    这部分在 VGA 中讲过,不多叙述,可以在VESA查询不同分辨率和帧数所对应的参数

    VGA的时序驱动代码也在VGA中有,不同分辨率的参数设定都已经参数化,根据不同的情况更改参数即可。

    以下为 VGA 驱动设计系列博客直达链接。

    【接口协议】FPGA 驱动 VGA 显示实验(一)原理部分

    【接口协议】FPGA 驱动 VGA 显示实验(二)实验设计部分

    传输通道顶层

    在次顶层模块对编码模块和并转串模块进行例化,需要对每个通道都进行例化一遍。

    1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    2. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    3. // Author : Linest-5
    4. // File : hdmi_trans.v
    5. // Create : 2022-10-04 16:39:39
    6. // Revise : 2022-10-04 16:57:56
    7. // Module Name :
    8. // Description :
    9. // Editor : sublime text3, tab size (4)
    10. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    11. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    12. module hdmi_trans(
    13. input clk1x,
    14. input clk5x,
    15. input rst,
    16. input locked,
    17. input [7:0] vga_r,
    18. input [7:0] vga_g,
    19. input [7:0] vga_b,
    20. input de,
    21. input v_sync,
    22. input h_sync,
    23. output hdmi_clk_p,
    24. output hdmi_clk_n,
    25. output hdmi_chan0_p,
    26. output hdmi_chan0_n,
    27. output hdmi_chan1_p,
    28. output hdmi_chan1_n,
    29. output hdmi_chan2_p,
    30. output hdmi_chan2_n
    31. );
    32. wire sysrst;
    33. wire [9:0] do_red;
    34. wire [9:0] do_green;
    35. wire [9:0] do_blue;
    36. assign sysrst = rst | (~locked);
    37. encode inst_encode_red (
    38. .clkin (clk1x),
    39. .rstin (sysrst),
    40. .din (vga_r),
    41. .c0 (1'b0),
    42. .c1 (1'b0),
    43. .de (de),
    44. .dout (do_red)
    45. );
    46. encode inst_encode_green (
    47. .clkin (clk1x),
    48. .rstin (sysrst),
    49. .din (vga_g),
    50. .c0 (1'b0),
    51. .c1 (1'b0),
    52. .de (de),
    53. .dout (do_green)
    54. );
    55. encode inst_encode_blue (
    56. .clkin (clk1x),
    57. .rstin (sysrst),
    58. .din (vga_b),
    59. .c0 (h_sync),
    60. .c1 (v_sync),
    61. .de (de),
    62. .dout (do_blue)
    63. );
    64. serial10_1 inst_serial10_1_clk(
    65. .divclk (clk1x),
    66. .serclk (clk5x),
    67. .rst (sysrst),
    68. .din (10'b1111_0000),
    69. .do_p (hdmi_clk_p),
    70. .do_n (hdmi_clk_n)
    71. );
    72. serial10_1 inst_serial10_1_red(
    73. .divclk (clk1x),
    74. .serclk (clk5x),
    75. .rst (sysrst),
    76. .din (do_red),
    77. .do_p (hdmi_chan2_p),
    78. .do_n (hdmi_chan2_n)
    79. );
    80. serial10_1 inst_serial10_1_green(
    81. .divclk (clk1x),
    82. .serclk (clk5x),
    83. .rst (sysrst),
    84. .din (do_green),
    85. .do_p (hdmi_chan1_p),
    86. .do_n (hdmi_chan1_n)
    87. );
    88. serial10_1 inst_serial10_1_blue(
    89. .divclk (clk1x),
    90. .serclk (clk5x),
    91. .rst (sysrst),
    92. .din (do_blue),
    93. .do_p (hdmi_chan0_p),
    94. .do_n (hdmi_chan0_n)
    95. );
    96. endmodule

    顶层模块

    最后进行最顶层模块的书写,将通带次顶层模块和VGA时序模块及逆行例化,同时由于我使用的板子输入时钟为200M的差分时钟,所以还需要例化锁相环模块。

    1. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    2. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    3. // Author : Linest-5
    4. // File : hdmi_top.v
    5. // Create : 2022-10-04 20:54:00
    6. // Revise : 2022-10-04 21:16:21
    7. // Module Name :
    8. // Description :
    9. // Editor : sublime text3, tab size (4)
    10. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    11. /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    12. `timescale 1ns / 1ps
    13. module hdmi_top(
    14. input clk_p,
    15. input clk_n,
    16. output hdmi_clk_p,
    17. output hdmi_clk_n,
    18. output hdmi_chan0_p,
    19. output hdmi_chan0_n,
    20. output hdmi_chan1_p,
    21. output hdmi_chan1_n,
    22. output hdmi_chan2_p,
    23. output hdmi_chan2_n
    24. );
    25. wire clk1x;
    26. wire clk5x;
    27. wire locked;
    28. wire [7:0] vga_r;
    29. wire [7:0] vga_g;
    30. wire [7:0] vga_b;
    31. wire de;
    32. wire v_sync;
    33. wire h_sync;
    34. diff2single inst_diff2single(
    35. // Clock out ports
    36. .clk_out1(clk1x), // output clk_out1
    37. .clk_out2(clk5x), // output clk_out2
    38. // Status and control signals
    39. .locked(locked), // output locked
    40. // Clock in ports
    41. .clk_in1_p(clk_p), // input clk_in1_p
    42. .clk_in1_n(clk_n)); // input clk_in1_n
    43. hdmi_trans inst_hdmi_trans (
    44. .clk1x (clk1x),
    45. .clk5x (clk5x),
    46. .rst (0),
    47. .locked (locked),
    48. .vga_r (vga_r),
    49. .vga_g (vga_g),
    50. .vga_b (vga_b),
    51. .de (de),
    52. .v_sync (v_sync),
    53. .h_sync (h_sync),
    54. .hdmi_clk_p (hdmi_clk_p),
    55. .hdmi_clk_n (hdmi_clk_n),
    56. .hdmi_chan0_p (hdmi_chan0_p),
    57. .hdmi_chan0_n (hdmi_chan0_n),
    58. .hdmi_chan1_p (hdmi_chan1_p),
    59. .hdmi_chan1_n (hdmi_chan1_n),
    60. .hdmi_chan2_p (hdmi_chan2_p),
    61. .hdmi_chan2_n (hdmi_chan2_n)
    62. );
    63. VGA_TIMING inst_VGA_TIMING (
    64. .sclk (clk1x),
    65. .rst_n (locked),
    66. .po_vga_r (vga_r),
    67. .po_vga_g (vga_g),
    68. .po_vga_b (vga_b),
    69. .po_de (de),
    70. .po_v_sync (v_sync),
    71. .po_h_sync (h_sync)
    72. );
    73. endmodule

    工程搭建

    在 Vivado 对工程进行搭建,将几个文件导入,并添加相应的 IP 模块即可。

    以下为实验工程的模块间框图

    最后绑定管脚并生成比特流文件,烧录至FPGA中,将HDMI输出口接到带有HDMI口的显示器,就可以看到在显示屏上呈现彩条。

  • 相关阅读:
    Java并发编程:如何正确使用 volatile、synchronized 和 final 关键字
    报表开发工具Reports and Dashboards新版本2022.3发布|附下载
    初识Java
    【41. 最短编辑距离(线性DP)】
    JavaScript计算两个时间相差多少个小时的封装函数
    C++ 静态断言 static_assert
    【Linux】提升yum下载速度
    元宇宙区块链协议Meta0宣布与Polygon建立合作关系
    HBuilder创建uniapp默认项目导入uview(胎教)
    Java主流分布式解决方案多场景设计与实战
  • 原文地址:https://blog.csdn.net/m0_61298445/article/details/127352819