问答 店铺
热搜: ZYNQ FPGA discuz

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

微信扫一扫 分享朋友圈

已有 43 人浏览分享

开启左侧

HDMI-IP项目-主讲HDMI数据岛时序-连载六

[复制链接]
43 0
1 HDMI数据岛概述

HDMI数据岛(Data Island)是视频消隐期间传输辅助数据的同步数据包区域,在音频传输中,系统通过数据岛将多通道数字音频(如LPCMDolby Atmos等)封装成音频样本包,配合音频时钟恢复信息,在水平和垂直消隐期精准嵌入视频流间隙,实现高达32通道、192kHz采样率的无损音频同步传输,其特有的音频时钟再生机制可消除时基误差,确保音画同步精度在±2个像素时钟周期内。

2 HDMI数据岛时序
640?wx_fmt=png&from=appmsg

HDMI 编码器除了对 DVI 的相关信号进行编码,还需要对音频信号和一些附加的控制信号(InfoFrames)进行编码。上图展示了一个完整的HDMI 视频流的结构图。主要包括以下 8 段数据:

1)控制数据包前导码:Data Island Preamble。数据包前导码指示接下来的数据为控制数据包,包括辅助数据和音频数据。这个前导码包括 8 个连续的相同控制令牌,并且只在绿色通道和红色通道有效。

2)控制数据包隔离带(前):Data Island Guardband (Leading)。收发器的一种同步方式——在控制数据包前导码和控制数据包之间的 2 个像素宽的隔离像素。

3)有效的控制数据:Active Aux/Audio Data,包括音频数据和辅助控制数据。音频数据编码方式为 10bit TERC4(TMDS 降错码)TERC4 编码方式包括 16 个特定的4b/10b 编码,只在绿色通道和红色通道进行传输。

4)控制数据包隔离带(后):Data Island Guardband (Trailing)。收发器的一种同步方式——在控制数据包和视频前导码之间的 2 个像素宽的隔离像素。

5)有效视频前导码:Video Preamble。数据包前导码指示接下来的数据为有效的视频数据包。这个前导码包括 8 个连续的相同控制令牌,并且只在绿色通道和红色通道有效。

6)视频隔离带(前):Video Guardband (Leading)。收发器的一种同步方式——在视频前导码和视频数据之间的 2 个像素宽的隔离像素。

7)有效视频数据:Active Video Data。视频数据采用和 DVI 相同的 8b/10b 编码方式。

8)视频隔离带(后):Video GuardbandLeading)。收发器的一种同步方式:在有效视频数据和控制数据前导码之间的 2 个像素宽的隔离像素。

控制令牌同样是通过HDMI 编码器来控制的,控制令牌有以下作用:

1)在蓝色通道提供场行同步信息。

2)指示控制数据包前导码消音区间的起始时刻。

3)在绿色和红色通道输出保留的控制令牌{C0,C1}

4)指示控制包的{C0,C1}状态。

5)在绿色和红外通道输出控制数据前导码。

DVI 编码器类似,场行同步信号 HSYNC VSYNC 在蓝色通道区间被传送。

DVI 编码器不同的是 HDMI 的编码器利用另外两个通道,即红色通道和绿色通道传输控制令牌。

控制令牌在后面TMDS编码课程再详细讲解,本节课重点实现数据岛时序模块。

3 HDMI数据岛时序代码

在设计这部分代码的时候,我们考虑两种情况,所以需要设计两个方案:

方案一:没有输入源数据时,依靠像素时钟输入就可以产生时序,配合模拟产生的TPG测试图像模块,方便单独测试hdmi_tx模块。

方案二:有输入源数据时,比如hdmi_rx模块,依靠像素时钟以及HSVSDE以及通道数据输入可以产生同步时序。

3.1 hdmi_tpg_video_source.v模块

hdmi_tpg_video_source.v模块是基于CTA-861-G标准的HDMI 720P@60Hz视频时序发生器,通过像素/行计数器精确生成符合HDMI规范的同步信号(Hsync/Vsync)、有效数据窗口(DE)及消隐期控制。其核心功能包括:在水平消隐期(HBlank)头部嵌入数据岛传输标识(前导码/保护带/有效窗口)用于辅助数据传输,在消隐期尾部生成视频数据岛标识,同时通过参数化时序配置(总周期1650像素/750行)实现标准分辨率输出,为HDMI编码器提供完整的视频时序基准和数据岛传输使能信号。

  1. // HDMI视频时序发生器(720P@60Hz)符合CTA-861-G规范  
  2. module hdmi_tpg_video_source   
  3. //=============== CTA-861-G 720P 时序参数 ================//  
  4. #(  
  5.     // 水平时序(单位:像素)  
  6.     parameter H_TOTAL  = 1650,   // 总周期 = 有效 + 消隐(1280 + 370)  
  7.     parameter H_SA     = 40,     // 水平同步脉宽(Sync Active)  
  8.     parameter H_FP     = 110,    // 水平前沿(Front Porch)  
  9.     parameter H_BP     = 220,    // 水平后沿(Back Porch)  
  10.     parameter H_ACTIVE = 1280,   // 有效像素区宽度  
  11.    
  12.     // 垂直时序(单位:行)  
  13.     parameter V_TOTAL  = 750,    // 总行数 = 有效 + 消隐(720 + 30)  
  14.     parameter V_SA     = 5,      // 垂直同步脉宽  
  15.     parameter V_FP     = 5,      // 垂直前沿  
  16.     parameter V_BP     = 20,     // 垂直后沿  
  17.     parameter V_ACTIVE = 720     // 有效像素区高度  
  18. )  
  19. (  
  20.     // 原始信号  
  21.     input  wire I_pixel_clk,      // 74.25MHz差分时钟(通过MMCM生成)  
  22.     input  wire I_reset_n,        // 全局异步复位(低有效)   
  23.    
  24.     // HDMI时序输出组  
  25.     output reg  O_vsync,          // 垂直同步(低有效,衔接VBLANK)  
  26.     output reg  O_hsync,          // 水平同步(低有效,衔接HBLANK)  
  27.     output reg  O_de,               // 有效视频数据窗口  
  28.     // 视频数据区标识(HDMI数据岛周期)  
  29.     output reg  O_video_data_island_preamble, // 视频前导码(8 pixel)  
  30.     output reg  O_video_guardband,            // 视频保护带(2 pixel)   
  31.     // 数据岛区标识(用于传输Auxiliary数据)  
  32.     output reg  O_data_island_preamble,   // 数据岛前导码(8 pixel)  
  33.     output reg  O_data_island_guardband,  // 双保护带(2 pixel * 2)  
  34.     output reg  O_data_island_active      // 数据岛传输窗口  
  35. );  
  36. //=============== 基于CTA标准的时序计算 ================//  
  37. // 注:各阶段时序位置关系:Active -> Front Porch -> Sync -> Back Porch  
  38. // 水平时序边界计算(像素坐标基准)  
  39. localparam H_BLANK_START = H_ACTIVE;         // 水平消隐起始点(有效区结束位置)  
  40. localparam H_SYNC_START  = H_BLANK_START + H_FP;   // 同步脉冲起始位置(前沿结束)  
  41. localparam H_SYNC_END    = H_SYNC_START + H_SA;    // 同步脉冲结束位置  
  42. localparam H_BLANK_END   = H_TOTAL - 1;     // 行扫描结束点(水平总周期-1)  
  43. // 垂直时序边界计算(行扫描基准)  
  44. localparam V_BLANK_START = V_ACTIVE;         // 垂直消隐起始行(有效区结束行)  
  45. localparam V_SYNC_START  = V_BLANK_START + V_FP;  // 垂直同步起始行(前沿结束)  
  46. localparam V_SYNC_END    = V_SYNC_START + V_SA;   // 垂直同步结束行  
  47. localparam V_BLANK_END   = V_TOTAL - 1;           // 帧扫描结束行(垂直总周期-1)  
  48. //=============== 数据岛容量计算 ================//  
  49. /* 分配策略:在HBlank区间安排数据岛传输时段,包含:  
  50.    - 8像素前导码  
  51.    - 2像素起始保护带  
  52.    - N x 32像素数据包   
  53.    - 2像素结束保护带  
  54.    - 保留12像素控制时段  
  55. */  
  56. localparam ISLAND_MAX_PACKETS = (H_TOTAL - H_ACTIVE - 8 - 2 - 2 -8 -2)/32 -1;  // 最大可用数据包数  
  57. localparam ISLAND_PACKET_NUM  = (ISLAND_MAX_PACKETS > 18) ? 18 : ISLAND_MAX_PACKETS; // 上限18包(HDMI规范限制)  
  58. //=============== 计数器逻辑 ================//  
  59. reg [11:0] pixel_counter; // 水平像素计数器(0~1649)  
  60. reg [9:0]  line_counter;   // 垂直行计数器(0~749)  
  61. // 消隐区状态信号  
  62. wire in_vblank ;   // 垂直消隐期标志(1=处于垂直消隐区)  
  63. // 垂直消隐状态更新(每像素周期检测)  
  64. assign    in_vblank = (line_counter >= V_BLANK_START && line_counter <= V_BLANK_END);  
  65. // 有效视频窗口生成(Active Video)  
  66. // 有效条件:水平有效区且不在垂直消隐期  
  67. always @(posedge I_pixel_clk)  
  68.     O_de <= (pixel_counter >= 0 && pixel_counter <= H_BLANK_START-1)&& !in_vblank;  
  69. // 像素计数器逻辑(行扫描控制)  
  70. always @(posedge I_pixel_clk or negedge I_reset_n)  
  71.     if (!I_reset_n ) pixel_counter <= 0;         // 异步复位清零  
  72.     else pixel_counter <= (pixel_counter == H_BLANK_END ) ? 0 : pixel_counter + 1;  // 循环计数  
  73. // 行计数器逻辑(帧扫描控制)  
  74. always @(posedge I_pixel_clk or negedge I_reset_n)  
  75.     if (!I_reset_n ) line_counter <= 0;          // 异步复位清零  
  76.     else if (pixel_counter == H_BLANK_END -10)      // 行结束条件  
  77.         line_counter <= (line_counter == V_BLANK_END ) ? 0 : line_counter + 1;  // 垂直递增/循环  
  78.     else   
  79.         line_counter <= line_counter;            // 保持当前行数  
  80. //=============== 时序信号生成 ================//  
  81. // Vertical Sync Generator(低电平有效)  
  82. always @(posedge I_pixel_clk)  
  83.     O_vsync <= (line_counter >= V_SYNC_START) && (line_counter < V_SYNC_END);  
  84. // Horizontal Sync Generator(低电平有效)  
  85. always @(posedge I_pixel_clk)  
  86.     O_hsync <= (pixel_counter >= H_SYNC_START) && (pixel_counter < H_SYNC_END);  
  87. //=============== 视频数据岛标识 ================//  
  88. /* HBlank区尾部结构:  
  89.    [视频前导码8pix] -> [视频保护带2pix] -> [控制时段12pix] -> ... */  
  90. // 视频前导码生成(消隐区结束前10个像素)  
  91. always @(posedge I_pixel_clk) begin  
  92.     O_video_data_island_preamble <= (pixel_counter >= H_BLANK_END - 9) && (pixel_counter <= H_BLANK_END - 2) && !in_vblank;  
  93. end  
  94. // 视频保护带生成(消隐区最后2个像素)  
  95. always @(posedge I_pixel_clk) begin   
  96.     O_video_guardband <= (pixel_counter >= H_BLANK_END - 1) && (pixel_counter <= H_BLANK_END) && !in_vblank;  
  97. end   
  98. //=============== 数据岛传输标识 ================//  
  99. /* HBlank区头部结构:  
  100.    [数据岛前导码8pix] -> [起始保护带2pix] -> [数据包N*32pix] -> [结束保护带2pix] */  
  101. always @(posedge I_pixel_clk) begin  
  102.     // 前导码阶段(消隐开始后48~55像素)  
  103.     O_data_island_preamble <= (pixel_counter >= H_BLANK_START + 48) && (pixel_counter < H_BLANK_START + 56);  
  104.    
  105.     // 双保护带检测(起始和结束各2像素)  
  106.     O_data_island_guardband <=   
  107.         // 起始保护带(56~57像素)  
  108.         ((pixel_counter >= H_BLANK_START + 56) && (pixel_counter < H_BLANK_START + 58)) ||  
  109.         // 结束保护带(数据包传输结束后)  
  110.         ((pixel_counter >= H_BLANK_START + 56 + 2 + (ISLAND_PACKET_NUM*32)) &&   
  111.          (pixel_counter < H_BLANK_START + 56 + 2 + (ISLAND_PACKET_NUM*32) + 2));  
  112.    
  113.     // 有效数据传输窗口(保护带之后的数据包区)  
  114.     O_data_island_active <= (pixel_counter >= H_BLANK_START + 58) && (pixel_counter < H_BLANK_START + 58 + (ISLAND_PACKET_NUM*32));  
  115. end  
  116. endmodule
复制代码
3.2 hdmi_video_sync.v模块

hdmi_video_sync.v模块是专为HDMI视频同步处理设计的核心单元,其通过两级同步机制消除输入视频信号(VSync/HSync/DE/RGB)的亚稳态风险,并基于像素/行计数器精确匹配CTA-861-G标准下的720P@60Hz时序规范。在水平消隐期(HBlank)起始阶段,模块生成包含前导码(8像素)、保护带(2像素)及有效数据包区的数据岛控制信号;消隐期尾部则插入视频前导码与保护带,同时输出延迟2个时钟周期的视频数据与使能信号。

该设计确保HDMI编码器能够在消隐窗口内准确嵌入音频包、信息帧等辅助数据,实现音视频时序的严格同步与无缝传输。

  1. //====================================================================  
  2. // HDMI视频时序同步器(CTA-861-G兼容)  
  3. // 设计特性:  
  4. // 1. 纯时序逻辑设计  2. 单always单寄存器  3. 完整条件分支  
  5. // 4. 独立同步寄存器  5. 严格中文注释  
  6. //====================================================================  
  7. `timescale 1ns / 1ps  
  8. module hdmi_video_sync #(  
  9.     // 水平时序(单位:像素)  
  10.     parameter H_TOTAL  = 1650,   // 总周期 = 有效 + 消隐(1280 + 370)  
  11.     parameter H_SA     = 40,     // 水平同步脉宽(Sync Active)  
  12.     parameter H_FP     = 110,    // 水平前沿(Front Porch)  
  13.     parameter H_BP     = 220,    // 水平后沿(Back Porch)  
  14.     parameter H_ACTIVE = 1280,   // 有效像素区宽度  
  15.    
  16.     // 垂直时序(单位:行)  
  17.     parameter V_TOTAL  = 750,    // 总行数 = 有效 + 消隐(720 + 30)  
  18.     parameter V_SA     = 5,      // 垂直同步脉宽  
  19.     parameter V_FP     = 5,      // 垂直前沿  
  20.     parameter V_BP     = 20,     // 垂直后沿  
  21.     parameter V_ACTIVE = 720     // 有效像素区高度  
  22. )(  
  23.     //====================== 系统接口 ======================//  
  24.     input  wire        I_pixel_clk,    // 74.25MHz像素时钟  
  25.     input  wire        I_reset_n,      // 低电平有效复位  
  26.    
  27.     //====================== 视频输入接口 ======================//  
  28.     input  wire        I_vsync,        // 输入场同步  
  29.     input  wire        I_hsync,        // 输入行同步  
  30.     input  wire        I_de,           // 数据使能  
  31.     input  wire [23:0] I_hdmi_data,    // RGB视频数据  
  32.    
  33.     //====================== 输出接口 ======================//  
  34.     output reg         O_vsync,        // 同步后场同步  
  35.     output reg         O_hsync,        // 同步后行同步  
  36.     output reg         O_de,           // 有效数据指示  
  37.     output reg  [23:0] O_hdmi_data,     // 同步后视频数据  
  38.    
  39.     //====================== 控制信号 ======================//  
  40.     output reg         O_data_island_preamble,    // 数据岛前导  
  41.     output reg         O_data_island_guardband,   // 数据岛保护  
  42.     output reg         O_data_island_active,      // 数据岛有效  
  43.     output reg         O_video_data_island_preamble, // 视频前导  
  44.     output reg         O_video_guardband          // 视频保护  
  45. );  
  46. //=============== 数据岛容量计算 ================//  
  47. /* 分配策略:在HBlank区间安排数据岛传输时段,包含:  
  48.    - 8像素前导码  
  49.    - 2像素起始保护带  
  50.    - N x 32像素数据包   
  51.    - 2像素结束保护带  
  52.    - 保留12像素控制时段  
  53. */  
  54. localparam ISLAND_MAX_PACKETS = (H_TOTAL - H_ACTIVE - 8 - 2 - 2 -8 -2 -2) / 32 -1;  // 最大可用数据包数  
  55. localparam ISLAND_PACKET_NUM  = (ISLAND_MAX_PACKETS > 18) ? 18 : ISLAND_MAX_PACKETS; // 上限18包(HDMI规范限制)
  56. localparam H_ISLAND_SHEFT  = 48;     // 有效期结束后,数据岛数据偏移  
  57. localparam ISLAND_PACKET_CUNT =  ISLAND_PACKET_NUM * 32;
  58. localparam H_BLANK_VAILD   = H_SA + H_BP -1;      
  59. localparam H_ISLAND_BEGIN  = H_SA + H_BP + H_ACTIVE + H_ISLAND_SHEFT;     // 有效期结束后,数据岛数据偏移
  60. localparam ISLAND_PACKET_CUNT_NEXT = ISLAND_PACKET_NUM * 32 - (H_TOTAL - H_ISLAND_BEGIN -10);
  61. //=============== 边沿检测信号 ================//  
  62. wire w_hsync_rising ;  // 行同步上升沿  
  63. wire w_vsync_rising ;  // 场同步上升沿  
  64. wire w_de_rising;      // 数据使能上升沿  
  65. //=============== 同步寄存器链 ================//  
  66. reg r_sync_vsync0, r_sync_vsync1;   // VSYNC两级同步  
  67. reg r_sync_hsync0, r_sync_hsync1;   // HSYNC两级同步  
  68. reg r_sync_de0, r_sync_de1;         // DE两级同步  
  69. reg [23:0] r_sync_data0;            // 视频数据一级同步  
  70. //=============== 计数器和状态寄存器 ================//  
  71. reg [11:0] r_pixel_counter;  // 水平像素计数器(0~1649)
  72. reg [10:0] r_line_counter;    // 垂直行计数器(0~749)  
  73. reg in_vblank;                // 垂直消隐期标志  
  74. reg r_start_flag;             // 同步启动标志  
  75. //====================================================================  
  76. // 同步边沿检测逻辑  
  77. //====================================================================  
  78. assign w_hsync_rising = (r_sync_hsync1 == 1'b0) && (r_sync_hsync0 == 1'b1);  // 检测HSYNC上升沿  
  79. assign w_vsync_rising = (r_sync_vsync1 == 1'b0) && (r_sync_vsync0 == 1'b1);  // 检测VSYNC上升沿  
  80. assign w_de_rising    = (r_sync_de1 == 1'b0) && (r_sync_de0 == 1'b1);        // 检测DE上升沿  
  81. assign w_de_fulling   = (r_sync_de1 == 1'b1) && (r_sync_de0 == 1'b0);        // 检测DE下降沿  
  82. //====================================================================  
  83. // 同步启动控制(检测到任意同步信号边沿后启动)  
  84. //====================================================================  
  85. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  86.     if (!I_reset_n)   
  87.        r_start_flag <= 1'b0;  
  88.     else if (w_hsync_rising|w_vsync_rising|w_de_rising)   
  89.        r_start_flag <= 1'b1;   
  90.     else   
  91.        r_start_flag <= r_start_flag;  
  92. end  
  93. //====================================================================  
  94. // 三级同步寄存器(消除亚稳态)  
  95. //====================================================================  
  96. // VSYNC同步链  
  97. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  98.     if (!I_reset_n) begin  
  99.         r_sync_vsync0 <= 1'b0;   
  100.         r_sync_vsync1 <= 1'b0;   
  101.     end else begin  
  102.         r_sync_vsync0 <= I_vsync;   // 第一级同步  
  103.         r_sync_vsync1 <= r_sync_vsync0; // 第二级同步  
  104.     end  
  105. end  
  106. // HSYNC同步链  
  107. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  108.     if (!I_reset_n) begin  
  109.         r_sync_hsync0 <= 1'b0;  
  110.         r_sync_hsync1 <= 1'b0;  
  111.     end else begin  
  112.         r_sync_hsync0 <= I_hsync;   // 第一级同步  
  113.         r_sync_hsync1 <= r_sync_hsync0; // 第二级同步  
  114.     end  
  115. end  
  116. // DE同步链  
  117. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  118.     if (!I_reset_n) begin  
  119.         r_sync_de0 <= 1'b0;   
  120.         r_sync_de1 <= 1'b0;  
  121.     end else begin  
  122.         r_sync_de0 <= I_de;        // 第一级同步  
  123.         r_sync_de1 <= r_sync_de0;  // 第二级同步  
  124.     end  
  125. end  
  126. // 视频数据同步(一级缓冲)  
  127. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  128.     if (!I_reset_n) begin  
  129.         r_sync_data0 <= 24'b0;   
  130.     end else begin  
  131.         r_sync_data0 <= I_hdmi_data;  // 数据同步延迟1周期  
  132.     end  
  133. end  
  134. //====================================================================  
  135. // 像素计数器(水平方向计数)  
  136. // 复位条件:全局复位或DE上升沿清零  
  137. //====================================================================  
  138. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  139.     if (!I_reset_n)   
  140.         r_pixel_counter <= 12'd0;  
  141.     else if (r_start_flag) begin  
  142.         if (w_hsync_rising)   
  143.             r_pixel_counter <= 12'd0;       // 有效数据开始清零  
  144.         else   
  145.             r_pixel_counter <= r_pixel_counter + 12'd1; // 持续递增  
  146.     end  
  147.     else   
  148.         r_pixel_counter <= 12'd0;   
  149. end  
  150. //====================================================================  
  151. // 行计数器(垂直方向计数)  
  152. // 复位条件:全局复位或VSYNC上升沿清零  
  153. //====================================================================  
  154. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  155.     if (!I_reset_n)   
  156.         r_line_counter <= 11'd0;  
  157.     else if(r_start_flag) begin  
  158.         if (w_vsync_rising)   
  159.             r_line_counter <= 11'd0;        // 垂直同步清零  
  160.         else if (w_hsync_rising)   
  161.             r_line_counter <= r_line_counter + 11'd1;  // 行结束递增  
  162.         else   
  163.             r_line_counter <= r_line_counter;  
  164.     end  
  165.     else   
  166.         r_line_counter <= 11'd0;  
  167. end  
  168. //====================================================================  
  169. // 消隐期检测逻辑  
  170. //====================================================================  
  171. // 垂直消隐检测(V_ACTIVE行之后)  
  172. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  173.     if (!I_reset_n) begin  
  174.         in_vblank <= 1'b0;  
  175.     end else begin  
  176.         if ((r_line_counter >= V_SA  + V_BP + V_ACTIVE) && (r_line_counter < V_TOTAL)||
  177.             r_line_counter >=0 && (r_line_counter < V_SA  + V_BP))
  178.          begin  
  179.             in_vblank <= 1'b1;  
  180.         end else begin  
  181.             in_vblank <= 1'b0;  
  182.         end  
  183.     end  
  184. end  
  185. //====================================================================  
  186. // 主输出信号同步(延迟2周期输出)  
  187. //====================================================================  
  188. // 垂直同步输出  
  189. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  190.     if (!I_reset_n) begin  
  191.         O_vsync <= 1'b0;  
  192.     end else begin  
  193.         O_vsync <= r_sync_vsync0;  // 同步后延迟1周期  
  194.     end  
  195. end  
  196. // 水平同步输出  
  197. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  198.     if (!I_reset_n) begin  
  199.         O_hsync <= 1'b0;  
  200.     end else begin  
  201.         O_hsync <= r_sync_hsync0;  // 同步后延迟1周期  
  202.     end  
  203. end  
  204. // 数据使能输出  
  205. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  206.     if (!I_reset_n) begin  
  207.         O_de <= 1'b0;  
  208.     end else begin  
  209.         O_de <= r_sync_de0;        // 同步后延迟1周期  
  210.     end  
  211. end  
  212. // 视频数据输出  
  213. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  214.     if (!I_reset_n) begin  
  215.         O_hdmi_data <= 24'h0;  
  216.     end else begin  
  217.         O_hdmi_data <= r_sync_data0;  // 同步后延迟1周期  
  218.     end  
  219. end  
  220. //====================================================================  
  221. // 视频数据岛标识生成  
  222. //====================================================================  
  223. // 视频前导码生成(行消隐区尾部8像素)  
  224. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  225.     if (!I_reset_n) begin  
  226.         O_video_data_island_preamble <= 1'b0;  
  227.     end else begin  
  228.         // 在行结束前10~3像素生成前导码  
  229.         if ((r_pixel_counter >= H_BLANK_VAILD -10 && r_pixel_counter < H_BLANK_VAILD -2) & !in_vblank) begin  
  230.             O_video_data_island_preamble <= 1'b1;  
  231.         end else begin  
  232.             O_video_data_island_preamble <= 1'b0;  
  233.         end  
  234.     end  
  235. end  
  236. // 视频保护带生成(行结束前2像素)  
  237. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  238.     if (!I_reset_n) begin  
  239.         O_video_guardband <= 1'b0;  
  240.     end else begin  
  241.         if ( (r_pixel_counter >= H_BLANK_VAILD-2 && r_pixel_counter < H_BLANK_VAILD) & !in_vblank) begin  
  242.             O_video_guardband <= 1'b1;  
  243.         end else begin  
  244.             O_video_guardband <= 1'b0;  
  245.         end  
  246.     end  
  247. end  
  248. //====================================================================  
  249. // 数据岛标识生成  
  250. //====================================================================  
  251. // 数据岛前导码生成(行消隐区头部8像素)  
  252. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  253.     if (!I_reset_n) begin  
  254.         O_data_island_preamble <= 1'b0;  
  255.     end else begin  
  256.         // 在有效区结束后的47~55像素生成  
  257.         if ((r_pixel_counter >=  H_ISLAND_BEGIN  && r_pixel_counter < H_ISLAND_BEGIN + 8) ) begin  
  258.             O_data_island_preamble <= 1'b1;  
  259.         end else begin  
  260.             O_data_island_preamble <= 1'b0;  
  261.         end  
  262.     end  
  263. end  
  264. // 数据岛保护带生成(前后各2像素)  
  265. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  266.     if (!I_reset_n) begin  
  267.         O_data_island_guardband <= 1'b0;  
  268.     end else begin  
  269.         // 起始保护带(55~57像素)  
  270.         if ((r_pixel_counter >= H_ISLAND_BEGIN + 8) && (r_pixel_counter < H_ISLAND_BEGIN + 10)||   
  271.         // 结束保护带(数据包传输后)  
  272.             (r_pixel_counter >= ISLAND_PACKET_CUNT_NEXT) && (r_pixel_counter < ISLAND_PACKET_CUNT_NEXT + 2)) begin  
  273.             O_data_island_guardband <= 1'b1;  
  274.         end else begin  
  275.             O_data_island_guardband <= 1'b0;  
  276.         end  
  277.     end  
  278. end  
  279. // 数据岛有效区生成(32像素/包 * N包)  
  280. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  281.     if (!I_reset_n) begin  
  282.         O_data_island_active <= 1'b0;  
  283.     end else begin  
  284.         // 在保护带之后的有效数据传输窗口  
  285.         if ((r_pixel_counter >=H_ISLAND_BEGIN + 10) && (r_pixel_counter < H_TOTAL-1)||
  286.             (r_pixel_counter >= 0) && (r_pixel_counter < ISLAND_PACKET_CUNT_NEXT)||
  287.             w_hsync_rising) begin  
  288.             O_data_island_active <= 1'b1;  
  289.         end else begin  
  290.             O_data_island_active <= 1'b0;  
  291.         end  
  292.     end  
  293. end  
  294. endmodule
复制代码
4 HDMI数据岛时序仿真4.1 hdmi_tpg_video_source.v模块仿真
640?wx_fmt=png&from=appmsg

从上图可以看到除了常见的O_vsync(场同步信号)、O_hsync(行同步信号)、O_de(有效视频数据)信号之外,还生成了O_video_data_island_preamble(有效视频前导码)、O_video_guardband(视频隔离带)、O_data_island_preamble(控制数据包前导码)、O_data_island_guardband(控制数据包隔离带)、O_data_island_active(有效的控制数据)。

把其中一个数据岛时序放大,各个信号的占用像素单位为:

O_video_data_island_preamble(有效视频前导码):8×像素

O_video_guardband(视频隔离带):2×像素

O_data_island_preamble(控制数据包前导码):8×像素

O_data_island_guardband(控制数据包隔离带):2×像素

O_data_island_active(有效的控制数据):N×32×像素(N为最大包数)

640?wx_fmt=png&from=appmsg
4.2 hdmi_video_sync.v模块仿真
640?wx_fmt=png&from=appmsg

从上图,通过输入的I_vsyncI_hsyncI_deI_hdmi_data[23:0]信号,同步出需要的所有信号,信号规则如前一模块中所讲,不重复赘述。

需要注意,I_vsyncI_hsyncI_deO_vsyncO_hsyncO_de之间处理用了两个时钟周期,数据信号注意同步。

640?wx_fmt=png&from=appmsg
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

0

关注

0

粉丝

303

主题
精彩推荐
热门资讯
网友晒图
图文推荐

  • 微信公众平台

  • 扫描访问手机版