问答 店铺
热搜: ZYNQ FPGA discuz

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

微信扫一扫 分享朋友圈

已有 53 人浏览分享

开启左侧

HDMI-IP项目-主讲HDMI数据岛分组构造(BCH块编码)-连载七

[复制链接]
53 0
1 数据岛分组构造概述

在上一讲中,我们阐述了数据岛的时序生成原理,本节课将深入探讨其时序阶段的数据传输机制。在HDMI协议框架下,数据岛通过“数据岛分组构造”实现信息封装与传输,其核心是将音频、视频及辅助数据按特定时序规则划分为独立的数据包(Packet)。每个数据包由前导码、包头、有效载荷及校验字段构成,并通过严格的同步信号与时钟相位对齐,确保数据在传输过程中保持时序一致性。

该设计不仅优化了带宽利用率,同时通过冗余校验机制保障了高可靠性,为高清多媒体传输提供了精准的底层支持。

2 数据岛分组构造原理
2.1BCH块编码

数据岛中的所有数据都包含在32个时钟包中。包由包头、包主体(由四个子包组成)和相关的纠错位组成。

每个子分组包括56比特的数据,并由附加的8比特BCH ECC奇偶校验位保护。

子分组0加上其相应的奇偶校验位构成了BCH0。该模块映射到通道1和通道2的位0。这样,BCH064位在32个像素的过程中被传送。同样,BCH1(子分组1加奇偶校验)被映射到信道12的比特1上。

主要的传输过程如下图所示

640?wx_fmt=png&from=appmsg

我们本讲的重点就是分析这张图,这张图来自于HDMI协议手册《High-Definition Multimedia Interface,这张图的上端很明显是对应的HDMI传输数据的三个通道,分别是Channel 0Channel 1Channel 2,在每一个Channel中,数据传输又分成4位,由此可知,数据岛数据在进入TMDS编码之前是4位传输的。

640?wx_fmt=png&from=appmsg

从上端我们可以确定,HDMI一共有三个通道,每个通道每次传输14位的数据岛数据,那下面就要看一下,这个4位数据岛数据每一位的组成。

就从上图可以看出,Channel 0D0位和D1位数据分别来自于HSYNCVSYNC,这个很好理解我们直接把HSYNCVSYNC信号接入Channel 0D0位和D1位即可。

640?wx_fmt=png&from=appmsg

Channel 0D2位开始,数据来自于BCH block 4,同时Channel 1D0D1D2D3以及Channel 2D0D1D2D3数据分别来自于BCH block 0~BCH block3。那我们就跳转到传输图的最下端,看一下BCH块数据的组成。

640?wx_fmt=png&from=appmsg

从上图可以看出,BCH block 0~BCH block 4块的数据来自于HDMI数据岛数据包,数据包分为报头字节(Packet Header)和子分组字节(Packet Body)。

报头字节表示为HB0HB1HB2,子分组字节表示为SB0~SB6由此我们可以得知,上图蓝色框内的数据来自于HDMI数据岛数据包。BCH block 4块数据来自于报头字节(Packet Header),包头字节一共24位。BCH block 0~BCH block 3的数据来自于HDMI数据岛数据包的子分组字节(Packet Body),子分组字节一共56位。

蓝色框外部还有最后一个数据(parity bits),这个8位的数据就是BCH ECC奇偶校验位。

下面我们看数据岛分组构造图上端和下端之间的数据转换传输。以BCH block0举例,BCH block0Packet Body+ECC奇偶校验位一共是64bit,按照奇偶位分别输出给Channel 1D0Channel 2D0。以此类推就把完整的64bit数据拆分成了两个32位的数据,其他BCH block1~BCH block3数据也是这么处理。

640?wx_fmt=png&from=appmsg

BCH block 4包含24位的Packet Header数据+8位的ECC奇偶校验位,一共包含32位的数据,正好可以直接传输给Channel 0D2

2.2 ECC奇偶校验

关于ECC奇偶校验的描述,HDMI协议手册《High-Definition Multimedia Interface中如下描述:

为了提高数据的可靠性和改进坏数据的检测,将纠错码(ECC)奇偶校验添加到每个包中。BCH(6456)BCH(3224)由多项式G(x)生成

G(x)=1+x6+x7+x8

640?wx_fmt=png&from=appmsg

这边编者对于ECC校验码的实现研究的也不多,直接使用的安路FPGA代码中的官方提供的ECC校验码计算方式,进过上板验证可以正确校验出结果。感兴趣的用户可以自行去研究实现原理,本章节就不再赘述。

3 hdmi_island_data_assemble模块代码

该模块为HDMI 720p@60Hz数据流封装核心,基于三级流水线架构实现视频时序与像素数据的精准同步。通过解析垂直同步(VSYNC)、水平同步(HSYNC)及数据使能(DE)信号,在消隐区间将BCH编码的辅助数据包(含音频、控制信息等)拆分为奇偶位流,经移位寄存器串行化处理。输出阶段依据HDMI 1.4通道规范,将视频前导码、保护带信号与数据流按通道规则组合:通道0传输包头及控制信号,通道1/2承载数据主体,最终在74.25MHz像素时钟驱动下完成全链路同步,严格满足协议时序与数据结构要求。

  1. `timescale 1ns / 1ps
  2. // HDMI 720P@60Hz 数据组装模块  
  3. // 功能:处理视频数据和辅助数据岛,生成符合HDMI 1.4规范的传输数据流  
  4. //====================================================================//  
  5. //  HDMI 720P@60Hz 数据岛组装核心模块  
  6. // 功能:根据HDMI 1.4规范组帧,处理视频数据+数据岛周期信号  
  7. // 特性:  
  8. //   1. 74.25MHz像素时钟  
  9. //   2. 配套720p60时序参数(1280x720@60Hz)  
  10. //   3. 三级流水线保证时序对齐  
  11. //   4. BCH块数据处理符合HDMI 1.4规范  
  12. //====================================================================//  
  13. module hdmi_island_data_assemble(  
  14.     //======================== 时钟域信号 ========================//  
  15.     input   wire        I_pixel_clk,        // 74.25MHz像素时钟  
  16.     input   wire        I_reset_n,          // 异步复位,高有效  
  17.    
  18.     //=================== 视频时序及数据输入 ====================//  
  19.     input   wire        I_vsync,        // 垂直同步信号  
  20.     input   wire        I_hsync,        // 水平同步信号  
  21.     input   wire        I_de,                // 视频有效数据周期标志  
  22.     input   wire        I_video_preamble,   // 视频前导周期标志  
  23.     input   wire        I_video_guard_band, // 视频保护带周期标志  
  24.     input   wire  [7:0] I_video_data_ch0,   // 视频通道0(蓝/亮度)  
  25.     input   wire  [7:0] I_video_data_ch1,   // 视频通道1(绿/色差)  
  26.     input   wire  [7:0] I_video_data_ch2,   // 视频通道2(红/色差)  
  27.    
  28.     //=================== 数据岛控制信号 ========================//  
  29.     input   wire        I_island_preamble,  // 数据岛前导周期  
  30.     input   wire        I_island_guard_band,// 数据岛保护带周期  
  31.     input   wire        I_island_period,    // 数据岛有效周期  
  32.    
  33.     //=================== BCH编码块输入 ========================//  
  34.     input   wire [63:0] I_BCH_block_0,  // 数据包块0(含包头和BCH校验)  
  35.     input   wire [63:0] I_BCH_block_1,  // 数据包块1  
  36.     input   wire [63:0] I_BCH_block_2,  // 数据包块2  
  37.     input   wire [63:0] I_BCH_block_3,  // 数据包块3  
  38.     input   wire [31:0] I_BCH_block_4,  // 数据包块4(最后32位)  
  39.    
  40.     //===================== 输出控制信号 =======================//  
  41.     output  wire        O_frame_start,       // 帧起始脉冲标志  
  42.     output  wire        O_island_packet_req, // 数据岛包请求  
  43.    
  44.     //==================== 输出视频时序信号 ====================//  
  45.     output  reg         O_vsync,            // 垂直同步(3拍延迟)  
  46.     output  reg         O_hsync,            // 水平同步(3拍延迟)  
  47.     output  reg         O_de,               // 视频有效周期  
  48.     output  reg         O_video_preamble,   // 视频前导周期  
  49.     output  reg         O_video_guard_band, // 视频保护带周期  
  50.     //==================== 输出视频数据通道 ====================//  
  51.     output  reg   [7:0] O_video_data_ch0,   // 通道0视频数据  
  52.     output  reg   [7:0] O_video_data_ch1,   // 通道1视频数据  
  53.     output  reg   [7:0] O_video_data_ch2,   // 通道2视频数据  
  54.    
  55.     //===================== 输出数据岛信号 =====================//  
  56.     output  reg         O_island_preamble,  // 数据岛前导周期  
  57.     output  reg         O_island_guard_band,// 数据岛保护带周期  
  58.     output  reg         O_island_period,    // 数据岛有效周期  
  59.    
  60.     //================= 数据岛通道输出(4bit/通道) ==============//  
  61.     output  reg[3:0]    O_island_data_ch0,  // 通道0:控制信号+包头  
  62.     output  reg[3:0]    O_island_data_ch1,  // 通道1:数据包低位  
  63.     output  reg[3:0]    O_island_data_ch2   // 通道2:数据包高位  
  64. );  
  65. //================================================================//  
  66. //                     参数定义及信号声明                         //  
  67. //================================================================//  
  68. localparam [4:0] PACKET_CNT_MAX = 5'd31;  // 数据岛包计数器最大值(32拍周期)  
  69. wire[31:0] w_CH1_D0_data;
  70. wire[31:0] w_CH1_D1_data;
  71. wire[31:0] w_CH1_D2_data;
  72. wire[31:0] w_CH1_D3_data;
  73. wire[31:0] w_CH2_D0_data;
  74. wire[31:0] w_CH2_D1_data;
  75. wire[31:0] w_CH2_D2_data;
  76. wire[31:0] w_CH2_D3_data;
  77. // 三级延迟寄存器组(对齐视频时序信号)  
  78. reg   vsync_delay_chain_d0;        // vsync延迟链  
  79. reg   vsync_delay_chain_d1;        // vsync延迟链  
  80. reg   vsync_delay_chain_d2;        // vsync延迟链  
  81. reg   hsync_delay_chain_d0;        // hsync延迟链  
  82. reg   hsync_delay_chain_d1;        // hsync延迟链  
  83. reg   hsync_delay_chain_d2;        // hsync延迟链
  84. reg   video_preamble_delay_d0;     // 视频前导周期延迟  
  85. reg   video_preamble_delay_d1;     // 视频前导周期延迟  
  86. reg   video_preamble_delay_d2;     // 视频前导周期延迟  
  87. reg   video_guard_delay_d0;        // 视频保护带延迟  
  88. reg   video_guard_delay_d1;        // 视频保护带延迟  
  89. reg   video_guard_delay_d2;        // 视频保护带延迟  
  90. reg   video_de_delay_d0;                 // 视频有效数据延迟  
  91. reg   video_de_delay_d1;                 // 视频有效数据延迟  
  92. reg   video_de_delay_d2;                 // 视频有效数据延迟  
  93. // 视频数据三级延迟
  94. reg [7:0] video_data_ch0_delay_d0;   // 通道0数据延迟  
  95. reg [7:0] video_data_ch0_delay_d1;   // 通道0数据延迟  
  96. reg [7:0] video_data_ch0_delay_d2;   // 通道0数据延迟  
  97. reg [7:0] video_data_ch1_delay_d0;   // 通道1数据延迟  
  98. reg [7:0] video_data_ch1_delay_d1;   // 通道1数据延迟  
  99. reg [7:0] video_data_ch1_delay_d2;   // 通道1数据延迟  
  100. reg [7:0] video_data_ch2_delay_d0;   // 通道2数据延迟  
  101. reg [7:0] video_data_ch2_delay_d1;   // 通道2数据延迟  
  102. reg [7:0] video_data_ch2_delay_d2;   // 通道2数据延迟  
  103. // 数据岛信号延迟链  
  104. reg  island_preamble_delay_d0;    // 数据岛前导延迟  
  105. reg  island_preamble_delay_d1;    // 数据岛前导延迟
  106. reg  island_preamble_delay_d2;    // 数据岛前导延迟
  107. reg  island_guard_delay_d0;       // 数据岛保护带延迟  
  108. reg  island_guard_delay_d1;       // 数据岛保护带延迟  
  109. reg  island_guard_delay_d2;       // 数据岛保护带延迟  
  110. reg  island_period_delay_d0;      // 数据岛有效周期延迟  
  111. reg  island_period_delay_d1;      // 数据岛有效周期延迟  
  112. reg  island_period_delay_d2;      // 数据岛有效周期延迟  
  113. reg [4:0]   island_packet_cnt;        // 数据岛包计数器(0-31)  
  114. reg         packet_req_delay_d0;      // 包请求信号延迟(同步用)  
  115. reg         packet_req_delay_d1;      // 包请求信号延迟(同步用)  
  116. // BCH块移位寄存器  
  117. // 复合通道移位寄存器组:  
  118. // [0] -> BCH块4(32位)  
  119. // [1-4] -> BCH块0-3低位(通道1)  
  120. // [5-8] -> BCH块0-3高位(通道2)                                                                  
  121.                                                                
  122. reg [31:0]  r_shift_ch0_d2;                                                                                         
  123. reg [31:0]  r_shift_ch1_d0;
  124. reg [31:0]  r_shift_ch1_d1;
  125. reg [31:0]  r_shift_ch1_d2;
  126. reg [31:0]  r_shift_ch1_d3;
  127. reg [31:0]  r_shift_ch2_d0;
  128. reg [31:0]  r_shift_ch2_d1;
  129. reg [31:0]  r_shift_ch2_d2;
  130. reg [31:0]  r_shift_ch2_d3;
  131. //================================================================//  
  132. //                     三级流水线延迟处理                         //  
  133. //================================================================//  
  134. // 作用:统一对齐所有控制信号和数据通道  
  135. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  136.     if(~I_reset_n) begin  
  137.         // 初始化所有延迟寄存器  
  138.         vsync_delay_chain_d0      <= 1'b0;  
  139.         vsync_delay_chain_d1      <= 1'b0;
  140.         vsync_delay_chain_d2      <= 1'b0;
  141.         hsync_delay_chain_d0      <= 1'b0;  
  142.         hsync_delay_chain_d1      <= 1'b0;  
  143.         hsync_delay_chain_d2      <= 1'b0;
  144.         video_preamble_delay_d0   <= 1'b0;  
  145.         video_preamble_delay_d1   <= 1'b0;  
  146.         video_preamble_delay_d2   <= 1'b0;  
  147.         video_guard_delay_d0      <= 1'b0;  
  148.         video_guard_delay_d1      <= 1'b0;  
  149.         video_guard_delay_d2      <= 1'b0;  
  150.         video_de_delay_d0     <= 1'b0;  
  151.         video_de_delay_d1     <= 1'b0;  
  152.         video_de_delay_d2     <= 1'b0;  
  153.         island_preamble_delay_d0  <= 1'b0;  
  154.         island_preamble_delay_d1  <= 1'b0;  
  155.         island_preamble_delay_d2  <= 1'b0;  
  156.         
  157.         island_guard_delay_d0     <= 1'b0;  
  158.         island_guard_delay_d1     <= 1'b0;  
  159.         island_guard_delay_d2     <= 1'b0;  
  160.         island_period_delay_d0    <= 1'b0;  
  161.         island_period_delay_d1    <= 1'b0;  
  162.         island_period_delay_d2    <= 1'b0;  
  163.         
  164.         // 初始化视频数据延迟通道  
  165.         video_data_ch0_delay_d0   <= 8'h0;  
  166.         video_data_ch0_delay_d1   <= 8'h0;  
  167.         video_data_ch0_delay_d2   <= 8'h0;  
  168.         video_data_ch1_delay_d0   <= 8'h0;  
  169.         video_data_ch1_delay_d1   <= 8'h0;  
  170.         video_data_ch1_delay_d2   <= 8'h0;  
  171.         video_data_ch2_delay_d0   <= 8'h0;  
  172.         video_data_ch2_delay_d1   <= 8'h0;  
  173.         video_data_ch2_delay_d2   <= 8'h0;  
  174.     end   
  175.     else begin  
  176.         // 同步信号链式移位  
  177.         vsync_delay_chain_d0   <= I_vsync;
  178.         vsync_delay_chain_d1   <= vsync_delay_chain_d0;
  179.         vsync_delay_chain_d2   <= vsync_delay_chain_d1;
  180.         hsync_delay_chain_d0   <= I_hsync;
  181.         hsync_delay_chain_d1   <= hsync_delay_chain_d0;
  182.         hsync_delay_chain_d2   <= hsync_delay_chain_d1;      
  183.         video_preamble_delay_d0   <= I_video_preamble;
  184.         video_preamble_delay_d1   <= video_preamble_delay_d0;
  185.         video_preamble_delay_d2   <= video_preamble_delay_d1;
  186.         // 视频控制信号移位  
  187.         video_guard_delay_d0   <= I_video_guard_band;
  188.         video_guard_delay_d1   <= video_guard_delay_d0;
  189.         video_guard_delay_d2   <= video_guard_delay_d1;
  190.         video_de_delay_d0   <= I_de;
  191.         video_de_delay_d1   <= video_de_delay_d0;
  192.         video_de_delay_d2   <= video_de_delay_d1;
  193.         
  194.         // 数据岛信号移位  
  195.         island_preamble_delay_d0   <= I_island_preamble;
  196.         island_preamble_delay_d1   <= island_preamble_delay_d0;
  197.         island_preamble_delay_d2   <= island_preamble_delay_d1;
  198.         island_guard_delay_d0   <= I_island_guard_band;
  199.         island_guard_delay_d1   <= island_guard_delay_d0;
  200.         island_guard_delay_d2   <= island_guard_delay_d1;
  201.         island_period_delay_d0   <= I_island_period;
  202.         island_period_delay_d1   <= island_period_delay_d0;
  203.         island_period_delay_d2   <= island_period_delay_d1;
  204.         
  205.         // 视频数据通道延迟(三级缓冲)  
  206.         video_data_ch0_delay_d0 <= I_video_data_ch0;  
  207.         video_data_ch0_delay_d1 <= video_data_ch0_delay_d0;  
  208.         video_data_ch0_delay_d2 <= video_data_ch0_delay_d1;  
  209.         
  210.         video_data_ch1_delay_d0 <= I_video_data_ch1;  
  211.         video_data_ch1_delay_d1 <= video_data_ch1_delay_d0;  
  212.         video_data_ch1_delay_d2 <= video_data_ch1_delay_d1;  
  213.         
  214.         video_data_ch2_delay_d0 <= I_video_data_ch2;  
  215.         video_data_ch2_delay_d1 <= video_data_ch2_delay_d0;  
  216.         video_data_ch2_delay_d2 <= video_data_ch2_delay_d1;  
  217.     end  
  218. end  
  219. //================================================================//  
  220. //                      帧起始检测逻辑                             //  
  221. // 说明:通过检测vsync上升沿标识帧开始(第3拍对比第2拍)  
  222. //================================================================//  
  223. assign O_frame_start = ~vsync_delay_chain_d1 & vsync_delay_chain_d2;  
  224. //================================================================//  
  225. //                  数据岛包周期计数器逻辑                         //  
  226. // 说明:当I_island_period有效时,0-31循环计数,产生包请求信号  
  227. //================================================================//  
  228. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  229.     if(~I_reset_n) begin  
  230.         island_packet_cnt <= 5'd0;  
  231.     end else begin  
  232.         // 包计数器逻辑  
  233.         if (I_island_period) begin  
  234.            if (island_packet_cnt == PACKET_CNT_MAX)
  235.             island_packet_cnt<= 'd0;
  236.            else  
  237.             island_packet_cnt <= island_packet_cnt + 1'b1;     
  238.             end
  239.         else   
  240.             island_packet_cnt <= 5'd0;            
  241.         end  
  242.     end
  243. // 包请求信号生成(周期起始时拉高)  
  244. assign O_island_packet_req = I_island_period && island_packet_cnt == 5'd0 ? 1'b1 : 1'b0;  
  245. always @(posedge I_pixel_clk or negedge I_reset_n)begin
  246.     if(~I_reset_n) begin  
  247.         packet_req_delay_d0 <= 1'b0;  
  248.         packet_req_delay_d1 <= 1'b0;
  249.     end
  250.             // 包请求信号延迟(同步)  
  251.     packet_req_delay_d0 <= O_island_packet_req;  
  252.     packet_req_delay_d1 <= packet_req_delay_d0;  
  253. end
  254. //================================================================//  
  255. //                  BCH数据块预处理(并行转串行)                 //  
  256. // 说明:将输入的64bit BCH块按奇偶位分开处理                     //  
  257. //================================================================//  
  258. assign w_CH1_D0_data = {
  259.     I_BCH_block_0[62],I_BCH_block_0[60],I_BCH_block_0[58],I_BCH_block_0[56] ,
  260.     I_BCH_block_0[54],I_BCH_block_0[52],I_BCH_block_0[50],I_BCH_block_0[48] ,
  261.     I_BCH_block_0[46],I_BCH_block_0[44],I_BCH_block_0[42],I_BCH_block_0[40] ,
  262.     I_BCH_block_0[38],I_BCH_block_0[36],I_BCH_block_0[34],I_BCH_block_0[32] ,
  263.     I_BCH_block_0[30],I_BCH_block_0[28],I_BCH_block_0[26],I_BCH_block_0[24] ,
  264.     I_BCH_block_0[22],I_BCH_block_0[20],I_BCH_block_0[18],I_BCH_block_0[16] ,
  265.     I_BCH_block_0[14],I_BCH_block_0[12],I_BCH_block_0[10],I_BCH_block_0[8]  ,
  266.     I_BCH_block_0[6] ,I_BCH_block_0[4] ,I_BCH_block_0[2] ,I_BCH_block_0[0]  };
  267. assign w_CH1_D1_data = {
  268.     I_BCH_block_1[62],I_BCH_block_1[60],I_BCH_block_1[58],I_BCH_block_1[56] ,
  269.     I_BCH_block_1[54],I_BCH_block_1[52],I_BCH_block_1[50],I_BCH_block_1[48] ,
  270.     I_BCH_block_1[46],I_BCH_block_1[44],I_BCH_block_1[42],I_BCH_block_1[40] ,
  271.     I_BCH_block_1[38],I_BCH_block_1[36],I_BCH_block_1[34],I_BCH_block_1[32] ,
  272.     I_BCH_block_1[30],I_BCH_block_1[28],I_BCH_block_1[26],I_BCH_block_1[24] ,
  273.     I_BCH_block_1[22],I_BCH_block_1[20],I_BCH_block_1[18],I_BCH_block_1[16] ,
  274.     I_BCH_block_1[14],I_BCH_block_1[12],I_BCH_block_1[10],I_BCH_block_1[8]  ,
  275.     I_BCH_block_1[6] ,I_BCH_block_1[4] ,I_BCH_block_1[2] ,I_BCH_block_1[0]  };
  276. assign w_CH1_D2_data = {
  277.     I_BCH_block_2[62],I_BCH_block_2[60],I_BCH_block_2[58],I_BCH_block_2[56] ,
  278.     I_BCH_block_2[54],I_BCH_block_2[52],I_BCH_block_2[50],I_BCH_block_2[48] ,
  279.     I_BCH_block_2[46],I_BCH_block_2[44],I_BCH_block_2[42],I_BCH_block_2[40] ,
  280.     I_BCH_block_2[38],I_BCH_block_2[36],I_BCH_block_2[34],I_BCH_block_2[32] ,
  281.     I_BCH_block_2[30],I_BCH_block_2[28],I_BCH_block_2[26],I_BCH_block_2[24] ,
  282.     I_BCH_block_2[22],I_BCH_block_2[20],I_BCH_block_2[18],I_BCH_block_2[16] ,
  283.     I_BCH_block_2[14],I_BCH_block_2[12],I_BCH_block_2[10],I_BCH_block_2[8]  ,
  284.     I_BCH_block_2[6] ,I_BCH_block_2[4] ,I_BCH_block_2[2] ,I_BCH_block_2[0]  };
  285. assign w_CH1_D3_data = {
  286.     I_BCH_block_3[62],I_BCH_block_3[60],I_BCH_block_3[58],I_BCH_block_3[56] ,
  287.     I_BCH_block_3[54],I_BCH_block_3[52],I_BCH_block_3[50],I_BCH_block_3[48] ,
  288.     I_BCH_block_3[46],I_BCH_block_3[44],I_BCH_block_3[42],I_BCH_block_3[40] ,
  289.     I_BCH_block_3[38],I_BCH_block_3[36],I_BCH_block_3[34],I_BCH_block_3[32] ,
  290.     I_BCH_block_3[30],I_BCH_block_3[28],I_BCH_block_3[26],I_BCH_block_3[24] ,
  291.     I_BCH_block_3[22],I_BCH_block_3[20],I_BCH_block_3[18],I_BCH_block_3[16] ,
  292.     I_BCH_block_3[14],I_BCH_block_3[12],I_BCH_block_3[10],I_BCH_block_3[8]  ,
  293.     I_BCH_block_3[6] ,I_BCH_block_3[4] ,I_BCH_block_3[2] ,I_BCH_block_3[0]  };
  294. assign w_CH2_D0_data = {
  295.     I_BCH_block_0[63],I_BCH_block_0[61],I_BCH_block_0[59],I_BCH_block_0[57] ,
  296.     I_BCH_block_0[55],I_BCH_block_0[53],I_BCH_block_0[51],I_BCH_block_0[49] ,
  297.     I_BCH_block_0[47],I_BCH_block_0[45],I_BCH_block_0[43],I_BCH_block_0[41] ,
  298.     I_BCH_block_0[39],I_BCH_block_0[37],I_BCH_block_0[35],I_BCH_block_0[33] ,
  299.     I_BCH_block_0[31],I_BCH_block_0[29],I_BCH_block_0[27],I_BCH_block_0[25] ,
  300.     I_BCH_block_0[23],I_BCH_block_0[21],I_BCH_block_0[19],I_BCH_block_0[17] ,
  301.     I_BCH_block_0[15],I_BCH_block_0[13],I_BCH_block_0[11],I_BCH_block_0[9]  ,
  302.     I_BCH_block_0[7] ,I_BCH_block_0[5] ,I_BCH_block_0[3] ,I_BCH_block_0[1]  };
  303. assign w_CH2_D1_data = {
  304.     I_BCH_block_1[63],I_BCH_block_1[61],I_BCH_block_1[59],I_BCH_block_1[57] ,
  305.     I_BCH_block_1[55],I_BCH_block_1[53],I_BCH_block_1[51],I_BCH_block_1[49] ,
  306.     I_BCH_block_1[47],I_BCH_block_1[45],I_BCH_block_1[43],I_BCH_block_1[41] ,
  307.     I_BCH_block_1[39],I_BCH_block_1[37],I_BCH_block_1[35],I_BCH_block_1[33] ,
  308.     I_BCH_block_1[31],I_BCH_block_1[29],I_BCH_block_1[27],I_BCH_block_1[25] ,
  309.     I_BCH_block_1[23],I_BCH_block_1[21],I_BCH_block_1[19],I_BCH_block_1[17] ,
  310.     I_BCH_block_1[15],I_BCH_block_1[13],I_BCH_block_1[11],I_BCH_block_1[9]  ,
  311.     I_BCH_block_1[7] ,I_BCH_block_1[5] ,I_BCH_block_1[3] ,I_BCH_block_1[1]  };
  312. assign w_CH2_D2_data = {
  313.     I_BCH_block_2[63],I_BCH_block_2[61],I_BCH_block_2[59],I_BCH_block_2[57] ,
  314.     I_BCH_block_2[55],I_BCH_block_2[53],I_BCH_block_2[51],I_BCH_block_2[49] ,
  315.     I_BCH_block_2[47],I_BCH_block_2[45],I_BCH_block_2[43],I_BCH_block_2[41] ,
  316.     I_BCH_block_2[39],I_BCH_block_2[37],I_BCH_block_2[35],I_BCH_block_2[33] ,
  317.     I_BCH_block_2[31],I_BCH_block_2[29],I_BCH_block_2[27],I_BCH_block_2[25] ,
  318.     I_BCH_block_2[23],I_BCH_block_2[21],I_BCH_block_2[19],I_BCH_block_2[17] ,
  319.     I_BCH_block_2[15],I_BCH_block_2[13],I_BCH_block_2[11],I_BCH_block_2[9]  ,
  320.     I_BCH_block_2[7] ,I_BCH_block_2[5] ,I_BCH_block_2[3] ,I_BCH_block_2[1]  };
  321. assign w_CH2_D3_data = {
  322.     I_BCH_block_3[63],I_BCH_block_3[61],I_BCH_block_3[59],I_BCH_block_3[57] ,
  323.     I_BCH_block_3[55],I_BCH_block_3[53],I_BCH_block_3[51],I_BCH_block_3[49] ,
  324.     I_BCH_block_3[47],I_BCH_block_3[45],I_BCH_block_3[43],I_BCH_block_3[41] ,
  325.     I_BCH_block_3[39],I_BCH_block_3[37],I_BCH_block_3[35],I_BCH_block_3[33] ,
  326.     I_BCH_block_3[31],I_BCH_block_3[29],I_BCH_block_3[27],I_BCH_block_3[25] ,
  327.     I_BCH_block_3[23],I_BCH_block_3[21],I_BCH_block_3[19],I_BCH_block_3[17] ,
  328.     I_BCH_block_3[15],I_BCH_block_3[13],I_BCH_block_3[11],I_BCH_block_3[9]  ,
  329.     I_BCH_block_3[7] ,I_BCH_block_3[5] ,I_BCH_block_3[3] ,I_BCH_block_3[1]  };
  330. //================================================================//  
  331. //                   串行移位寄存器处理逻辑                       //  
  332. // 说明:当包请求信号有效时加载数据,否则逐位右移  
  333. //================================================================//  
  334. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  335.     if(~I_reset_n) begin  
  336.         r_shift_ch0_d2 <= 32'd0;  
  337.         r_shift_ch1_d0 <= 32'd0;  
  338.         r_shift_ch1_d1 <= 32'd0;  
  339.         r_shift_ch1_d2 <= 32'd0;  
  340.         r_shift_ch1_d3 <= 32'd0;  
  341.         r_shift_ch2_d0 <= 32'd0;  
  342.         r_shift_ch2_d1 <= 32'd0;  
  343.         r_shift_ch2_d2 <= 32'd0;  
  344.         r_shift_ch2_d3 <= 32'd0;  
  345.     end   
  346.     else if(packet_req_delay_d1) begin  // 延迟两拍确保数据稳定  
  347.         // BCH块4直接载入  
  348.         r_shift_ch0_d2 <= I_BCH_block_4;  
  349.         
  350.         // 加载通道1(偶数位)  
  351.         r_shift_ch1_d0 <= w_CH1_D0_data;  
  352.         r_shift_ch1_d1 <= w_CH1_D1_data;  
  353.         r_shift_ch1_d2 <= w_CH1_D2_data;  
  354.         r_shift_ch1_d3 <= w_CH1_D3_data;  
  355.         
  356.         // 加载通道2(奇数位)  
  357.         r_shift_ch2_d0 <= w_CH2_D0_data;  
  358.         r_shift_ch2_d1 <= w_CH2_D1_data;  
  359.         r_shift_ch2_d2 <= w_CH2_D2_data;  
  360.         r_shift_ch2_d3 <= w_CH2_D3_data;  
  361.     end   
  362.     else begin  
  363.         // 全局右移(LSB优先发送)  
  364.         r_shift_ch0_d2 <= r_shift_ch0_d2 >> 1;  
  365.         r_shift_ch1_d0 <= r_shift_ch1_d0 >> 1;  
  366.         r_shift_ch1_d1 <= r_shift_ch1_d1 >> 1;  
  367.         r_shift_ch1_d2 <= r_shift_ch1_d2 >> 1;
  368.         r_shift_ch1_d3 <= r_shift_ch1_d3 >> 1;  
  369.         r_shift_ch2_d0 <= r_shift_ch2_d0 >> 1;  
  370.         r_shift_ch2_d1 <= r_shift_ch2_d1 >> 1;  
  371.         r_shift_ch2_d2 <= r_shift_ch2_d2 >> 1;  
  372.         r_shift_ch2_d3 <= r_shift_ch2_d3 >> 1;  
  373.     end  
  374. end  
  375. //================================================================//  
  376. //                数据岛通道数据组合输出逻辑                      //  
  377. // 说明:每个周期组合各移位寄存器的最低位构成4bit输出  
  378. //================================================================//  
  379. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  380.     if(~I_reset_n) begin  
  381.         O_island_data_ch0 <= 4'd0;  
  382.         O_island_data_ch1 <= 4'd0;  
  383.         O_island_data_ch2 <= 4'd0;  
  384.     end   
  385.     else begin  
  386.         // 通道0:控制位 + BCH4数据位[通道0协议映射]  
  387.         O_island_data_ch0 <= {1'b0                  ,    //  保留位
  388.                              r_shift_ch0_d2[0]      ,    //  BCH4数据LSB
  389.                              vsync_delay_chain_d2   ,    //  vsync
  390.                              hsync_delay_chain_d2   };   //  hsync
  391.         
  392.         // 通道1:BCH块0-3偶数位数据(从高位到低位D3-D0)  
  393.         O_island_data_ch1 <= {r_shift_ch1_d3[0]     ,   // D3最低有效位  
  394.                               r_shift_ch1_d2[0]     ,   // D2  
  395.                               r_shift_ch1_d1[0]     ,   // D1  
  396.                               r_shift_ch1_d0[0]     };  // D0  
  397.         
  398.         // 通道2:BCH块0-3奇数位数据(从高位到低位D3-D0)  
  399.         O_island_data_ch2 <= {r_shift_ch2_d3[0]     ,   // D3最高有效位  
  400.                               r_shift_ch2_d2[0]     ,   // D2  
  401.                               r_shift_ch2_d1[0]     ,   // D1  
  402.                               r_shift_ch2_d0[0]     };  // D0  
  403.     end  
  404. end  
  405. //================================================================//  
  406. //                 最终信号输出寄存器赋值                         //  
  407. // 说明:使用统一的三级延迟信号对齐所有输出路径  
  408. //================================================================//  
  409. always @(posedge I_pixel_clk) begin  
  410.         // 视频时序信号(第三拍延迟)  
  411.         O_vsync             <= vsync_delay_chain_d2;  
  412.         O_hsync             <= hsync_delay_chain_d2;  
  413.         O_video_preamble    <= video_preamble_delay_d2;  
  414.         O_video_guard_band  <= video_guard_delay_d2;  
  415.         O_de                <= video_de_delay_d2;  
  416.         
  417.         // 数据岛控制信号(第三拍延迟)  
  418.         O_island_preamble   <= island_preamble_delay_d2;  
  419.         O_island_guard_band <= island_guard_delay_d2;  
  420.         O_island_period     <= island_period_delay_d2;  
  421.         
  422.         // 视频数据通道(第三拍延迟)  
  423.         O_video_data_ch0    <= video_data_ch0_delay_d2;  
  424.         O_video_data_ch1    <= video_data_ch1_delay_d2;  
  425.         O_video_data_ch2    <= video_data_ch2_delay_d2;  
  426. end  
  427. endmodule
复制代码
4 hdmi_island_data_assemble模块仿真

本模块结合HDMI数据岛时序和I_vsyncI_hsyncI_de控制型号,对视频数据和数据岛数据进行重新整合,最终同步后,同步输出3×8bit的视频数据、3×4bit数据岛数据、数据岛时序、视频时序。

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

本版积分规则

0

关注

0

粉丝

303

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

  • 微信公众平台

  • 扫描访问手机版