问答 店铺
热搜: ZYNQ FPGA discuz

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

微信扫一扫 分享朋友圈

已有 88 人浏览分享

开启左侧

HDMI-IP项目-主讲HDMI数据包类型-连载八

[复制链接]
88 0
1 HDMI数据包类型概述

HDMI数据岛包含多种标准化的数据包类型:音频采样包(传输多通道PCM或压缩音频流,含时钟再生信息确保音画同步)、信息帧包(携带色彩空间、HDR元数据、3D格式等视频参数)、辅助视频信息包(AVI InfoFrame定义视频分辨率与扫描方式)、控制包(传输CEC指令、EDID扩展显示识别数据及HDCP加密控制信号)以及动态元数据包(如Dolby Vision的动态亮度映射数据)等,这些数据包通过时分复用机制嵌入消隐期,实现音视频同步传输与设备间智能交互。

完整的数据包类型如图所示,图片来自于HDMI协议手册《High-Definition Multimedia Interface

640?wx_fmt=png&from=appmsg

当然我们并不需要包含所有数据包,下面我们提供所需数据包的详细介绍以及组包代码。

2 数据包类型
2.1音频时钟再生包(Audio Clock Regeneration Packet

音频时钟再生数据包包含音频时钟再生过程中使用的NCTS值。这四个子分组各自包含相同的音频时钟再生子分组。HDMI接收器应忽略音频时钟再生数据包报头的字节HB1HB2

2.1.1音频时钟再生数据包报头Audio Clock Regeneration Subpacket
640?wx_fmt=png&from=appmsg
2.1.2音频时钟再生子包Audio Clock Regeneration Subpacket
640?wx_fmt=png&from=appmsg
2.1.3音频时钟再生包(Audio Clock Regeneration Packet)代码

该模块是HDMI 1.4b音频时钟再生包生成器,核心功能包括:通过CTS(循环时间戳)和N值参数(CTS=128*N/Fs)重构音频时钟,将24位包头(含标识符0x01)和56位数据体(含CTS[23:0]N[19:0])分别进行BCH-8编码(包头BCH(32,24)生成8ECC,数据体BCH(64,56)生成8ECC),输出符合Section 5.3.3规范的五组BCH数据块(块4含包头+ECC,块3含数据体+ECC,块0-2保留填零)。

  1. ///////////////////////////////////////////////////////////////////////////////  
  2. //// HDMI 1.4b 音频时钟再生包生成器                                        ////  
  3. //// 功能:                                                               ////  
  4. //// 1. 生成符合HDMI 1.4b Section 5.3.3的音频时钟重构包                    ////  
  5. //// 2. CTS(循环时间戳)输入范围控制与验证                               ////  
  6. //// 3. BCH-8编码实现符合Section 5.3.2的ECC要求                           ////  
  7. ///////////////////////////////////////////////////////////////////////////////  
  8. module audio_clock_regeneration_packet (  
  9.     input  wire        I_pixel_clk,        // 74.25MHz主时钟(TMDS时钟频率)  
  10.     input  wire        I_reset_n,          // 异步复位(高电平有效)  
  11.    
  12.     input  wire [19:0] I_audio_CTS,        // 24-bit CTS值(按CT = 128*N/FS计算)  
  13.     input  wire [19:0] I_audio_N,          // 20-bit N值(FS = Tmds_Clk*N/(128*CT))  
  14.    
  15.     output reg  [31:0] O_BCH_block_4,      // BCH块4[头数据+ECC]  
  16.     output reg  [63:0] O_BCH_block_3,      // BCH块3[音频数据体]  
  17.     output reg  [63:0] O_BCH_block_2,      // BCH块2(保留区)  
  18.     output reg  [63:0] O_BCH_block_1,      // BCH块1(保留区)  
  19.     output reg  [63:0] O_BCH_block_0        // BCH块0(保留区)  
  20. );  
  21. //=======================================================================  
  22. // HDMI 1.4b规范定义参数  
  23. //=======================================================================  
  24. localparam [7:0] HEADER_HB0    = 8'h01; // 包头标识(0x01表示音频时钟包)  
  25. localparam [7:0] HEADER_HB1    = 8'h00; // 保留字段(必须置零)  
  26. localparam [7:0] HEADER_HB2    = 8'h00; // 保留字段(必须置零)  
  27. localparam [7:0] SB0_RESERVED  = 8'h00; // 数据体SB0固定保留  
  28. //=======================================================================  
  29. // 寄存器组声明  
  30. //=======================================================================  
  31. reg [7:0] r_header_hb0;    // 包头字节0(固定0x01)  
  32. reg [7:0] r_header_hb1;    // 包头字节1(保留)  
  33. reg [7:0] r_header_hb2;    // 包头字节2(保留)  
  34. reg [7:0] r_body_sb0;      // 数据体字节0(保留)  
  35. reg [7:0] r_body_sb1;      // 数据体字节1(CTS[19:16]高4位)  
  36. reg [7:0] r_body_sb2;      // 数据体字节2(CTS[15:8])  
  37. reg [7:0] r_body_sb3;      // 数据体字节3(CTS[7:0])  
  38. reg [7:0] r_body_sb4;      // 数据体字节4(N[19:16]高4位)  
  39. reg [7:0] r_body_sb5;      // 数据体字节5(N[15:8])  
  40. reg [7:0] r_body_sb6;      // 数据体字节6(N[7:0])  
  41. //=======================================================================  
  42. // 数据拼接组合逻辑  
  43. //=======================================================================  
  44. wire [23:0] w_header ;  // 24位包头数据  
  45. wire [55:0] w_body   ;  // 56位有效数据体  
  46. assign w_header = {r_header_hb2, r_header_hb1, r_header_hb0}; // 包头拼接  
  47. assign w_body   = {r_body_sb6, r_body_sb5, r_body_sb4, r_body_sb3, r_body_sb2, r_body_sb1, r_body_sb0}; // 数据体拼接  
  48. //=======================================================================  
  49. // 包头与数据体内容更新逻辑  
  50. // 根据HDMI规范Section 5.3.3构建数据结构:  
  51. //   - 包头:3字节(0x01 + 2字节保留)  
  52. //   - 数据体:7字节(CTS[23:0]占用3字节,N[19:0]占用3字节,SB0/SB3/SB6保留)  
  53. //=======================================================================  
  54. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  55.     if (!I_reset_n) begin  // 异步复位初始化  
  56.         r_header_hb0 <= 8'h0;  
  57.         r_header_hb1 <= 8'h0;  
  58.         r_header_hb2 <= 8'h0;  
  59.         r_body_sb0   <= 8'h0;  
  60.         r_body_sb1   <= 8'h0;  
  61.         r_body_sb2   <= 8'h0;  
  62.         r_body_sb3   <= 8'h0;  
  63.         r_body_sb4   <= 8'h0;  
  64.         r_body_sb5   <= 8'h0;  
  65.         r_body_sb6   <= 8'h0;  
  66.     end else begin          // 正常数据装载  
  67.         // 固定包头内容  
  68.         r_header_hb0 <= HEADER_HB0;                  // HB0 = 0x01(包类型标识)  
  69.         r_header_hb1 <= HEADER_HB1;                  // HB1 = 0x00(保留)  
  70.         r_header_hb2 <= HEADER_HB2;                  // HB2 = 0x00(保留)  
  71.         
  72.         // 数据体内容组装  
  73.         r_body_sb0  <= SB0_RESERVED;                 // SB0固定保留  
  74.         r_body_sb1  <= {4'b0000, I_audio_CTS[19:16]};// SB1高4位补零 + CTS[19:16]  
  75.         r_body_sb2  <= I_audio_CTS[15:8];            // SB2 = CTS[15:8]  
  76.         r_body_sb3  <= I_audio_CTS[7:0];             // SB3 = CTS[7:0]  
  77.         r_body_sb4  <= {4'b0000, I_audio_N[19:16]};  // SB4高4位补零 + N[19:16]  
  78.         r_body_sb5  <= I_audio_N[15:8];              // SB5 = N[15:8]  
  79.         r_body_sb6  <= I_audio_N[7:0];               // SB6 = N[7:0]  
  80.     end  
  81. end  
  82. //=======================================================================  
  83. // BCH错误校验码生成器  
  84. // 规范要求:  
  85. //   - 包头使用BCH(32,24)编码(24位数据+8位ECC)  
  86. //   - 数据体使用BCH(64,56)编码(56位数据+8位ECC)  
  87. //=======================================================================  
  88. wire [7:0] w_header_ecc, w_body_ecc;  
  89. BCH_32_24_encode u_BCH_32_24_encode(       // 包头BCH编码器  
  90.     .I_clk         (I_pixel_clk  ),       // 74.25MHz主时钟  
  91.     .I_data_in     (w_header     ),       // 24位包头数据  
  92.     .O_bch_ecc_out (w_header_ecc )        // 8位ECC校验码  
  93. );  
  94. BCH_64_56_encode u_BCH_64_56_encode(       // 数据体BCH编码器  
  95.     .I_clk         (I_pixel_clk),         // 74.25MHz主时钟  
  96.     .I_data_in     (w_body     ),         // 56位有效数据  
  97.     .O_bch_ecc_out (w_body_ecc )          // 8位ECC校验码  
  98. );  
  99. //=======================================================================  
  100. // BCH数据块输出组合  
  101. // 根据HDMI数据包结构:  
  102. //   - Block4: 包头(24b) + ECC(8b) = 32bits  
  103. //   - Block3: 数据体(56b) + ECC(8b) = 64bits  
  104. //   - Block2~0: 保留区(需填充0)  
  105. //=======================================================================  
  106. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  107.     if (!I_reset_n) begin  // 复位清零  
  108.         O_BCH_block_4 <= 32'b0;  
  109.         O_BCH_block_3 <= 64'b0;  
  110.         O_BCH_block_2 <= 64'b0;  
  111.         O_BCH_block_1 <= 64'b0;  
  112.         O_BCH_block_0 <= 64'b0;  
  113.     end else begin          // 正常输出  
  114.         // Block4:包头数据 + ECC(32位)  
  115.         O_BCH_block_4 <= {w_header_ecc, w_header};  
  116.         
  117.         // Block3:数据体 + ECC(64位)  
  118.         O_BCH_block_3 <= {w_body_ecc, w_body[55:0]};  
  119.         
  120.         // Block2~0:保留区填充0(规范要求未使用区域必须置零)  
  121.         O_BCH_block_2 <= 64'h0;  
  122.         O_BCH_block_1 <= 64'h0;  
  123.         O_BCH_block_0 <= 64'h0;  
  124.     end  
  125. end  
  126. endmodule
复制代码
2.2音频样本包(Audio Sample Packet

L-PCM和一些IEC 61937压缩音频格式使用音频样本包来传送。

音频样本包由一到四个音频样本组成。这些可以是不同的样本或不同的部分样本(6个通道中的2)。子分组的配置由报头中的layoutsample_present位决定。

2.2.1音频样本数据包报头(Audio Sample Packet Header
640?wx_fmt=png&from=appmsg

关于Layout值和Audio Packet的关系 ,协议中是这样介绍的。

640?wx_fmt=png&from=appmsg

在音频样本分组报头中有四个sample_present比特,每个子分组一个。这些指示子分组是否包含音频样本。

此外,如果在sample_flat.spX所代表的时间段内,源端没有可用的音频数据,则会设置四个sample _ flat . spx位。这可能发生在采样速率变化或临时流中断期间。当sample_flat.spX置位时,子包X继续代表一个采样周期,但不包含有用的音频数据。仅当相应的sample_present.spX位置位时,sample_flat.spX位才有效。

Layout0可用于从单个IEC 61937或单个双声道IEC 60958音频流中携带多达四个样本。

Layout1可用于携带具有三到八个L-PCM音频通道的一个音频样本(即两到四个IEC 60958)

如下图所示,本例程选择使用双通道,所以选择layout值为0。如果有多音频通道需求,可以修改为1

layout值为0时,有效Sample_Present位配置如下

640?wx_fmt=png&from=appmsg

选择把数据数据放在block_0上,所以把sample_ present.sp0 拉高

2.2.2音频样本子包Audio Sample Subpacket
640?wx_fmt=png&from=appmsg

SB0-SB5分别填入24位左右声道音频数据信息,如超过24位则舍弃低位数据,SB6中的内容,本课程并未涉及,所以不做详细介绍。

2.2.3音频样本包(Audio Sample Packet)代码

该模块是HDMI 1.4b音频采样包封装器,核心功能包括:将双声道24bit音频数据(小端模式拆分为6字节)与包头(类型0x02+控制字段)按规范封装,通过BCH(32,24)BCH(64,56)编码生成包头和数据体的8ECC校验码,采用XPM FIFO缓冲音频数据流并实现请求-应答握手协议,输出符合五组BCH数据块(块4含包头+ECC,块0含音频数据体+ECC,其余块填零)。

  1. `timescale 1ns / 1ps  
  2. //////////////////////////////////////////////////////////////////////////////////  
  3. // HDMI 1.4b音频采样包封装模块  
  4. // 功能特性:  
  5. // 1. 符合HDMI 1.4b规范Section 5.3.3音频采样包格式  
  6. // 2. 支持双声道24bit音频数据封装  
  7. // 3. 集成BCH(32,24)和BCH(64,56)错误校验码生成  
  8. // 4. 采用XPM FIFO实现数据流缓冲对齐  
  9. // 5. 支持音频包请求/应答握手协议  
  10. //////////////////////////////////////////////////////////////////////////////////  
  11. module audio_sample_packet_channel(  
  12.     input  wire        I_pixel_clk,      // 74.25MHz主时钟(TMDS时钟域)  
  13.     input  wire        I_reset_n,        // 异步复位(低电平有效)  
  14.    
  15.     //================= 音频输入接口 =================//  
  16.     input  wire        I_audio_valid,        // 音频数据有效脉冲(与数据对齐)  
  17.     input  wire [23:0] I_audio_left_data,    // 左声道24bit音频(补码格式)  
  18.     input  wire [23:0] I_audio_right_data,   // 右声道24bit音频(补码格式)  
  19.    
  20.     //================ 包控制接口 ====================//  
  21.     input  wire        I_audio_packet_req,   // 音频包请求信号(主机发起)  
  22.     output reg         O_audio_packet_valid, // 音频包有效指示(应答信号)  
  23.    
  24.     //============== BCH编码输出接口 ==================//  
  25.     output reg  [31:0] O_BCH_block_4, // BCH块4:[31:24]=包头ECC,[23:0]=包头  
  26.     output reg  [63:0] O_BCH_block_3, // BCH块3:保留区(固定0)  
  27.     output reg  [63:0] O_BCH_block_2, // BCH块2:保留区(固定0)  
  28.     output reg  [63:0] O_BCH_block_1, // BCH块1:保留区(固定0)  
  29.     output reg  [63:0] O_BCH_block_0  // BCH块0:[63:56]=数据体ECC,[55:0]=音频数据  
  30. );  
  31. //=======================================================================  
  32. // HDMI规范参数定义(Section 5.3.3 Audio Sample Packet)  
  33. //=======================================================================  
  34. localparam [7:0] HEADER_HB0    = 8'h02; // 包头类型(0x02=音频采样包)  
  35. localparam [7:0] HEADER_HB1    = {3'b000,1'b0,4'b0001}; // 控制字段:  
  36.     // [7:5]=000(保留),[4]=0(线性PCM),[3:0]=0001(双声道)  
  37. localparam [7:0] HEADER_HB2    = 8'h00; // 保留字段(必须置零)  
  38. localparam [7:0] SB_RESERVED   = 8'h00; // 数据体保留字段填充值  
  39. //=======================================================================  
  40. // 寄存器组声明  
  41. //=======================================================================  
  42. reg [7:0]   r_header_hb0;    // 包头字节0(类型标识)  
  43. reg [7:0]   r_header_hb1;    // 包头字节1(控制字段)  
  44. reg [7:0]   r_header_hb2;    // 包头字节2(保留)  
  45. reg [7:0]   r_body_sb0;      // 数据体字节0(左声道LSB)  
  46. reg [7:0]   r_body_sb1;      // 数据体字节1(左声道)  
  47. reg [7:0]   r_body_sb2;      // 数据体字节2(左声道MSB)  
  48. reg [7:0]   r_body_sb3;      // 数据体字节3(右声道LSB)  
  49. reg [7:0]   r_body_sb4;      // 数据体字节4(右声道)  
  50. reg [7:0]   r_body_sb5;      // 数据体字节5(右声道MSB)  
  51. reg [7:0]   r_body_sb6;      // 数据体字节6(保留)  
  52. reg [55:0]  r_body;          // 数据体缓冲(56bit)  
  53. //=======================================================================  
  54. // FIFO控制信号  
  55. //=======================================================================  
  56. reg         r_fifo_wr_en;     // FIFO写使能(一级缓冲)  
  57. reg         rr_fifo_wr_en;    // FIFO写使能(二级缓冲)  
  58. wire        w_rd_en;          // FIFO读使能  
  59. wire        w_fifo_full;      // FIFO满标志  
  60. wire        w_fifo_empty;     // FIFO空标志  
  61. wire [63:0] w_fifo_dout;      // FIFO输出数据(64bit)  
  62. //=======================================================================  
  63. // 数据拼接组合逻辑  
  64. //=======================================================================  
  65. wire [23:0] w_header = {r_header_hb2, r_header_hb1, r_header_hb0}; // 24bit包头  
  66. wire [55:0] w_body   = {r_body_sb6, r_body_sb5, r_body_sb4, r_body_sb3,  
  67.                         r_body_sb2, r_body_sb1, r_body_sb0};       // 56bit数据体  
  68. wire [63:0] w_BCH_block_0 = (~w_fifo_empty) ? w_fifo_dout : 64'h0; // FIFO数据输出  
  69. assign w_rd_en = (~w_fifo_empty) ? I_audio_packet_req : 1'b0;      // 读使能生成  
  70. //=======================================================================  
  71. // 音频包构造逻辑(按HDMI CTS 1.4b规范S6.3.4实现)  
  72. //=======================================================================  
  73. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  74.     if (!I_reset_n) begin    // 异步复位初始化  
  75.         // 包头复位  
  76.         r_header_hb0 <= 8'h0;  
  77.         r_header_hb1 <= 8'h0;  
  78.         r_header_hb2 <= 8'h0;  
  79.         
  80.         // 数据体复位  
  81.         r_body_sb0 <= 8'h0;  
  82.         r_body_sb1 <= 8'h0;  
  83.         r_body_sb2 <= 8'h0;  
  84.         r_body_sb3 <= 8'h0;  
  85.         r_body_sb4 <= 8'h0;  
  86.         r_body_sb5 <= 8'h0;  
  87.         r_body_sb6 <= 8'h0;  
  88.     end else begin          // 正常数据构造  
  89.         //----------------------------  
  90.         // 固定包头构造  
  91.         //----------------------------  
  92.         r_header_hb0 <= HEADER_HB0;   // 包类型标识(0x02)  
  93.         r_header_hb1 <= HEADER_HB1;   // 控制字段(双声道PCM)  
  94.         r_header_hb2 <= HEADER_HB2;   // 保留字段  
  95.         //----------------------------  
  96.         // 动态数据体构造(小端模式)  
  97.         //----------------------------  
  98.         // 左声道数据(24bit拆分为3字节)  
  99.         r_body_sb0 <= I_audio_left_data[7:0]   ;  // 字节0:LSB  
  100.         r_body_sb1 <= I_audio_left_data[15:8]  ;  // 字节1  
  101.         r_body_sb2 <= I_audio_left_data[23:16] ;  // 字节2:MSB  
  102.         
  103.         // 右声道数据(24bit拆分为3字节)  
  104.         r_body_sb3 <= I_audio_right_data[7:0]   ;  // 字节3:LSB  
  105.         r_body_sb4 <= I_audio_right_data[15:8]  ;  // 字节4  
  106.         r_body_sb5 <= I_audio_right_data[23:16] ;  // 字节5:MSB  
  107.         
  108.         // 保留字段处理  
  109.         r_body_sb6 <= SB_RESERVED;                // 字节6:固定填充0  
  110.     end  
  111. end  
  112. //=======================================================================  
  113. // 数据缓冲逻辑(二级寄存器消除亚稳态)  
  114. //=======================================================================  
  115. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  116.     if (!I_reset_n) begin  
  117.         r_fifo_wr_en <= 1'b0;  
  118.         rr_fifo_wr_en<= 1'b0;  
  119.     end else begin  
  120.         r_fifo_wr_en  <= I_audio_valid;    // 原始有效信号打拍  
  121.         rr_fifo_wr_en <= r_fifo_wr_en;     // 二级缓冲  
  122.     end  
  123. end  
  124. //=======================================================================  
  125. // BCH块输出组合逻辑  
  126. //=======================================================================  
  127. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  128.     if (!I_reset_n) begin  // 复位清零  
  129.         O_BCH_block_4 <= 32'b0;  
  130.         O_BCH_block_3 <= 64'b0;  
  131.         O_BCH_block_2 <= 64'b0;  
  132.         O_BCH_block_1 <= 64'b0;  
  133.         O_BCH_block_0 <= 64'b0;  
  134.     end else begin          // 正常输出  
  135.         // Block4:包头 + ECC(32bit)  
  136.         O_BCH_block_4 <= {w_header_ecc, w_header};  
  137.         
  138.         // Block3~1:保留区置零  
  139.         O_BCH_block_3 <= 64'h0;     
  140.         O_BCH_block_2 <= 64'h0;  
  141.         O_BCH_block_1 <= 64'h0;  
  142.         
  143.         // Block0:数据体 + ECC(64bit)  
  144.         O_BCH_block_0 <= w_BCH_block_0;  
  145.     end  
  146. end  
  147. //=======================================================================  
  148. // 包有效状态机(请求-应答握手协议)  
  149. //=======================================================================  
  150. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  151.     if (!I_reset_n) begin  
  152.         O_audio_packet_valid <= 1'b0;  
  153.     end else if (I_audio_packet_req && !w_fifo_empty) begin  
  154.         O_audio_packet_valid <= 1'b1;  // FIFO非空时响应请求  
  155.     end else begin  
  156.         O_audio_packet_valid <= 1'b0;  // 默认无效   
  157.     end  
  158. end  
  159. //=======================================================================  
  160. // BCH编码器实例化  
  161. //=======================================================================  
  162. BCH_32_24_encode u_BCH_32_24_encode(       // 包头BCH(32,24)编码器  
  163.     .I_clk         (I_pixel_clk  ),        // 74.25MHz时钟  
  164.     .I_data_in     (w_header     ),        // 24bit包头输入  
  165.     .O_bch_ecc_out (w_header_ecc )         // 8bit ECC输出  
  166. );  
  167. BCH_64_56_encode u_BCH_64_56_encode(       // 数据体BCH(64,56)编码器  
  168.     .I_clk         (I_pixel_clk),          // 74.25MHz时钟  
  169.     .I_data_in     (w_body     ),          // 56bit数据输入  
  170.     .O_bch_ecc_out (w_body_ecc )           // 8bit ECC输出  
  171. );  
  172. //=======================================================================  
  173. // XPM同步FIFO实例化(用于数据流缓冲)  
  174. //=======================================================================  
  175. xpm_fifo_sync #(   
  176.     .DOUT_RESET_VALUE    ("0"),       // 复位输出值  
  177.     .ECC_MODE            ("no_ecc"), // 禁用ECC模式  
  178.     .FIFO_MEMORY_TYPE    ("auto"),    // 自动选择存储类型  
  179.     .FIFO_READ_LATENCY   (1),         // 固定1周期读延迟  
  180.     .FIFO_WRITE_DEPTH    (1024),      // 深度1024(适应突发传输)  
  181.     .FULL_RESET_VALUE    (0),         // 复位时FULL=0  
  182.     .READ_DATA_WIDTH     (64),        // 64bit读数据  
  183.     .READ_MODE           ("fwft"),    // 首字直通模式  
  184.     .SIM_ASSERT_CHK      (0),         // 关闭仿真断言  
  185.     .WRITE_DATA_WIDTH    (64)         // 64bit写数据  
  186. ) u_audio_fifo (  
  187.     .rst        (!I_reset_n    ),     // 异步复位(低有效)  
  188.     .wr_clk     (I_pixel_clk   ),     // 写时钟  
  189.     .wr_en      (rr_fifo_wr_en ),     // 写使能(二级缓冲)  
  190.     .din        ({w_body_ecc, r_body}), // 输入数据[63:56]=ECC,[55:0]=数据体  
  191.     .full       (w_fifo_full   ),     // FIFO满标志  
  192.     .rd_en      (w_rd_en       ),     // 读使能(请求触发)  
  193.     .dout       (w_fifo_dout   ),     // 输出数据  
  194.     .empty      (w_fifo_empty  )      // FIFO空标志  
  195. );  
  196. endmodule
复制代码
2.3辅助视频信息(AVI)信息包(Auxiliary Video information (AVI) InfoFrame  Packet

HDMI信源通过辅助视频信息(AVI)信息帧指示当前视频流的各个方面。

如果信号源满足以下条件,则信号源应始终至少每两个视频场传输一次AVI信息帧:

• 能够传输AVI信息帧,

• 能够传输YCBCR像素编码,

• 能够传输除传输的视频格式的默认色度之外的任何色度,

• 曾经能够传输任何xvYCC或未来增强的色度,

• 曾经能够传输任何色域元数据包,

• 能够传输具有多个允许像素重复的任何视频格式。

AVI信息框架版本2的打包如下所示。

2.3.1AVI信息帧数据包报头(AVI InfoFrame Packet Header
640?wx_fmt=png&from=appmsg

Header包头是固定值,所以无需讨论

2.3.2AVI信息框架数据包内容AVI InfoFrame Packet Contents
640?wx_fmt=png&from=appmsg
640?wx_fmt=png&from=appmsg

HDMI协议手册《High-Definition Multimedia Interface》让我们通过《CEA-861-D》查询信息,打开《CEA-861-D6.4节。内容如下:

AVI InfoFrame 数据字节 1

640?wx_fmt=png&from=appmsg

AVI InfoFrame 数据字节 2

640?wx_fmt=png&from=appmsg

AVI InfoFrame 数据字节 3

640?wx_fmt=png&from=appmsg

AVI InfoFrame 数据字节 4

我们本课程使用的是1280×720p@59.94/60Hz,所以我们的Video Codes选择4

640?wx_fmt=png&from=appmsg

AVI InfoFrame 数据字节 5

640?wx_fmt=png&from=appmsg

本包的参数选择和参数介绍非常繁琐,感兴趣的可以自行查询《CEA-861-D》中详细内容介绍,本教程仅提供参照表格,重点部分代码中已经做参数处理,并不做详细介绍。

2.3.3AVI信息框架数据包(Auxiliary Video information (AVI) InfoFrame Packet)代码

该模块是HDMI AVI信息帧封装器,核心功能包括:根据CEA-861-F标准构建AVI信息帧结构(包头0x82标识+13字节数据体),动态生成视频格式(4:3/16:9)、色彩空间(RGB/BT601)和VIC码参数,通过BCH(32,24)BCH(64,56)编码分别对24位包头与56位数据体(含校验和、控制字段、VIC等)生成8ECC校验码,输出五组BCH编码块(块4含包头+ECC,块0含数据体+ECC,其余块填零),符合HDMI 1.4b CTS 6.5.2规范要求,用于在视频消隐期传输显示参数配置信息。

  1. `timescale 1ns / 1ps  
  2. //////////////////////////////////////////////////////////////////////////////////  
  3. // HDMI AVI信息帧封装模块(符合HDMI 1.4b CTS 6.5.2节规范)  
  4. // 功能特性:  
  5. // 1. 生成符合CEA-861-F标准的AVI信息帧  
  6. // 2. 支持视频格式、色彩空间、VIC码等参数配置  
  7. // 3. 集成BCH(32,24)和BCH(64,56)错误校验码生成  
  8. // 4. 严格遵循HDMI规范保留字段处理  
  9. //////////////////////////////////////////////////////////////////////////////////  
  10. module avi_info_frame_packet (  
  11.     //==================== 全局信号 ====================//  
  12.     input  wire        I_pixel_clk,        // 74.25MHz像素时钟  
  13.     input  wire        I_reset_n,          // 异步复位(低电平有效)  
  14.    
  15.     //================== 视频配置输入 ==================//  
  16.     input  wire [1:0]  I_video_format,     // 视频宽高比 00=4:3,01=16:9,10/11保留  
  17.     input  wire [1:0]  I_colorimetry,      // 色彩空间 00=RGB,01=BT601,10=BT709,11保留  
  18.     input  wire [6:0]  I_video_VIC,        // 7bit视频标识码(CEA-861-F表15)  
  19.    
  20.     //================= BCH编码输出 ====================//  
  21.     output reg  [31:0] O_BCH_block_4,       // BCH块4:[31:24]=包头ECC,[23:0]=包头  
  22.     output reg  [63:0] O_BCH_block_3,      // BCH块3:保留区(强制置零)  
  23.     output reg  [63:0] O_BCH_block_2,      // BCH块2:保留区(强制置零)  
  24.     output reg  [63:0] O_BCH_block_1,      // BCH块1:保留区(强制置零)  
  25.     output reg  [63:0] O_BCH_block_0        // BCH块0:[63:56]=数据体ECC,[55:0]=有效数据  
  26. );  
  27. //=======================================================================  
  28. // CEA-861-F标准参数定义(表8.8 AVI信息帧格式)  
  29. //=======================================================================  
  30. localparam [7:0] HEADER_HB0    = 8'h82; // 包头类型:0x82=AVI信息帧(固定值)  
  31. localparam [7:0] HEADER_HB1    = 8'h02; // 版本号:0x02=Version 2(HDMI 1.3+使用)  
  32. localparam [7:0] HEADER_HB2    = 8'h0D; // 数据长度:13字节(0x0D)  
  33. localparam [7:0] SB_RESERVED   = 8'h00; // 保留字段填充值(必须置零)  
  34. //=======================================================================  
  35. // 寄存器组声明  
  36. //=======================================================================  
  37. reg [7:0] r_header_hb0;    // 包头字节0(类型标识)  
  38. reg [7:0] r_header_hb1;    // 包头字节1(版本号)  
  39. reg [7:0] r_header_hb2;    // 包头字节2(数据长度)  
  40. reg [7:0] r_body_sb0;      // 数据体字节0(校验和)  
  41. reg [7:0] r_body_sb1;      // 数据体字节1(视频格式/激活标志)  
  42. reg [7:0] r_body_sb2;      // 数据体字节2(色彩空间/色深)  
  43. reg [7:0] r_body_sb3;      // 数据体字节3(保留字段)  
  44. reg [7:0] r_body_sb4;      // 数据体字节4(VIC码低7位)  
  45. reg [7:0] r_body_sb5;      // 数据体字节5(保留字段)  
  46. reg [7:0] r_body_sb6;      // 数据体字节6(保留字段)  
  47. //=======================================================================  
  48. // 数据拼接组合逻辑  
  49. //=======================================================================  
  50. wire [23:0] w_header = {r_header_hb2, r_header_hb1, r_header_hb0}; // 24bit包头  
  51. wire [55:0] w_body   = {r_body_sb6, r_body_sb5, r_body_sb4,       // 56bit数据体  
  52.                        r_body_sb3, r_body_sb2, r_body_sb1, r_body_sb0};  
  53. //=======================================================================  
  54. // AVI信息帧构造逻辑(CEA-861-F表8.8)  
  55. //=======================================================================  
  56. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  57.     if (!I_reset_n) begin  // 异步复位初始化  
  58.         r_header_hb0 <= 8'h0;  
  59.         r_header_hb1 <= 8'h0;  
  60.         r_header_hb2 <= 8'h0;  
  61.         r_body_sb0   <= 8'h0;  
  62.         r_body_sb1   <= 8'h0;  
  63.         r_body_sb2   <= 8'h0;  
  64.         r_body_sb3   <= 8'h0;  
  65.         r_body_sb4   <= 8'h0;  
  66.         r_body_sb5   <= 8'h0;  
  67.         r_body_sb6   <= 8'h0;  
  68.     end else begin        // 动态字段构造  
  69.         //---------------- 固定包头 ----------------  
  70.         r_header_hb0 <= HEADER_HB0;  // 类型标识  
  71.         r_header_hb1 <= HEADER_HB1;  // 版本号  
  72.         r_header_hb2 <= HEADER_HB2;  // 数据长度  
  73.         //---------------- 动态数据体 ----------------  
  74.         // SB0: 校验和 = 0x100 - (HB0+HB1+HB2+SB1+SB2+SB3+SB4+SB5)  
  75.         r_body_sb0 <= 8'd1 + ~(r_header_hb0 + r_header_hb1 + r_header_hb2 +  
  76.                               r_body_sb1 + r_body_sb2 + r_body_sb3 +  
  77.                               r_body_sb4 + r_body_sb5);  
  78.         // SB1: [7]=保留 [6:5]=视频格式 [4]=激活格式标志 [3:0]=保留  
  79.         r_body_sb1 <= {1'b0, I_video_format, 1'b1, 4'b0000};  // 激活标志固定为1  
  80.         // SB2: [7:6]=色彩空间 [5:4]=色深 [3:0]=保留  
  81.         r_body_sb2 <= {I_colorimetry, 2'b00, 4'b1000};       // 默认8bit色深  
  82.         r_body_sb3 <= 8'b0001_0000;   // SB3保留字段(按规范置位bit4)  
  83.         r_body_sb4 <= {1'b0, I_video_VIC}; // SB4[7]=保留,[6:0]=VIC码  
  84.         r_body_sb5 <= SB_RESERVED;    // SB5保留  
  85.         r_body_sb6 <= SB_RESERVED;    // SB6保留  
  86.     end  
  87. end  
  88. //=======================================================================  
  89. // BCH编码器实例化  
  90. //=======================================================================  
  91. wire [7:0] w_header_ecc, w_body_ecc;  
  92. BCH_32_24_encode u_BCH_32_24_encode(  // 包头BCH(32,24)编码器  
  93.     .I_clk         (I_pixel_clk),  
  94.     .I_data_in     (w_header),       // 24bit包头数据  
  95.     .O_bch_ecc_out (w_header_ecc)     // 8bit ECC校验码  
  96. );  
  97. BCH_64_56_encode u_BCH_64_56_encode(  // 数据体BCH(64,56)编码器  
  98.     .I_clk         (I_pixel_clk),  
  99.     .I_data_in     (w_body),         // 56bit有效数据  
  100.     .O_bch_ecc_out (w_body_ecc)      // 8bit ECC校验码  
  101. );  
  102. //=======================================================================  
  103. // BCH块输出组合逻辑  
  104. //=======================================================================  
  105. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  106.     if (!I_reset_n) begin  // 复位清零  
  107.         O_BCH_block_4 <= 32'b0;  
  108.         O_BCH_block_3 <= 64'b0;  
  109.         O_BCH_block_2 <= 64'b0;  
  110.         O_BCH_block_1 <= 64'b0;  
  111.         O_BCH_block_0 <= 64'b0;  
  112.     end else begin          // 正常输出  
  113.         O_BCH_block_4 <= {w_header_ecc, w_header};  // 包头+ECC(32bit)  
  114.         O_BCH_block_3 <= 64'h0;                     // 保留区置零  
  115.         O_BCH_block_2 <= 64'h0;  
  116.         O_BCH_block_1 <= 64'h0;  
  117.         O_BCH_block_0 <= {w_body_ecc, w_body};      // 数据体+ECC(64bit)  
  118.     end  
  119. end  
  120. endmodule
复制代码
2.4音频信息帧包(Audio InfoFrame Packet

源应使用IEC 60958信道状态位、IEC 61937突发信息和/或流数据(如果存在)以及音频信息帧来指示活动音频流的特征。

每当传输活动音频流时,应至少每两个视频场传输一次准确的音频信息帧。

音频信息帧传输可以在数据岛分组可以被传输的任何时间发生,包括在任何水平或垂直消隐周期期间。

2.4.1音频信息帧数据包报头(Audio InfoFrame Packet Header
640?wx_fmt=png&from=appmsg

Header包头是固定值,所以无需讨论

2.4.2音频信息帧数据包内容(Audio InfoFrame Packet contents
640?wx_fmt=png&from=appmsg

HDMI协议手册《High-Definition Multimedia Interface》让我们通过《CEA-861-D》查询信息,打开《CEA-861-D6.6节。内容如下:

音频信息帧数据字节1

640?wx_fmt=png&from=appmsg

音频信息帧数据字节2

640?wx_fmt=png&from=appmsg

我们要使用的主要信息就集中在第1和第2Byte中,根据表格信息做成参数查找表即可。

2.4.3音频信息帧包(Audio InfoFrame Packet)代码

该模块是HDMI音频信息帧封装器,主要功能包括:构建音频信息帧,将声道数(2-8通道)、采样率(如44.1kHz/48kHz)和采样深度(16/20/24bit)等参数封装为10字节数据体(含动态计算的补码校验和),通过BCH(32,24)BCH(64,56)编码分别对24位包头(类型0x84+版本0x01)与56位有效数据生成8ECC校验码,输出五组BCH数据块(块4含包头+ECC,块3含音频参数数据体+ECC,其余块填零),用于在视频消隐期传输音频配置信息,确保接收端能准确重建音频时钟与解码参数。

  1. `timescale 1ns / 1ps  
  2. //////////////////////////////////////////////////////////////////////////////////  
  3. // HDMI音频信息帧封装模块  
  4. // 功能特性:  
  5. // 1. 生成HDMI音频信息包(audio_info_frame_packet)  
  6. // 2. 支持多声道配置及多种采样率格式  
  7. // 3. 集成BCH(32,24)和BCH(64,56)前向纠错编码  
  8. //////////////////////////////////////////////////////////////////////////////////  
  9. module audio_info_frame_packet(  
  10.     //==================== 全局信号 ====================//  
  11.     input  wire        I_pixel_clk,        // 74.25MHz像素时钟
  12.     input  wire        I_reset_n,          // 异步复位(高电平有效)  
  13.    
  14.     //================== 音频配置输入 ==================//  
  15.     input  wire [2:0]  I_audio_sample_frequency, // 3bit采样率编码(000=44.1kHz, 001=48kHz,...)  
  16.     input  wire [2:0]  I_audio_channel_count,    // 3bit声道数(000=2ch,001=3ch,...,111=8ch)  
  17.     input  wire [1:0]  I_audio_sample_size,     // 2bit采样深度(00=16bit,01=20bit,10=24bit)  
  18.    
  19.     //=============== BCH编码输出接口 ==================//  
  20.     output reg  [31:0] O_BCH_block_4,       // BCH块4:[31:24]=包头ECC,[23:0]=包头  
  21.     output reg  [63:0] O_BCH_block_3,      // BCH块3:[63:56]=数据体ECC,[55:0]=有效数据  
  22.     output reg  [63:0] O_BCH_block_2,      // BCH块2:保留区(强制置零)  
  23.     output reg  [63:0] O_BCH_block_1,      // BCH块1:保留区(强制置零)  
  24.     output reg  [63:0] O_BCH_block_0       // BCH块0:保留区(强制置零)  
  25. );  
  26. //=======================================================================  
  27. // HDMI规范参数定义(CTS 1.4b S6.3.3音频信息帧数据包)  
  28. //=======================================================================  
  29. localparam [7:0] HEADER_HB0    = 8'h84; // 包头类型(0x84=音频信息帧数据包)  
  30. localparam [7:0] HEADER_HB1    = 8'h01; // 版本号(0x01=版本1)  
  31. localparam [7:0] HEADER_HB2    = 8'h0A; // 数据长度:10字节(0x0A)  
  32. localparam [7:0] SB_RESERVED   = 8'h00; // 保留字段填充值(必须置零)  
  33. //=======================================================================  
  34. // 寄存器组声明  
  35. //=======================================================================  
  36. reg [7:0] r_header_hb0;    // 包头字节0(类型标识)  
  37. reg [7:0] r_header_hb1;    // 包头字节1(版本号)  
  38. reg [7:0] r_header_hb2;    // 包头字节2(数据长度)  
  39. reg [7:0] r_body_sb0;      // 数据体字节0(校验和)  
  40. reg [7:0] r_body_sb1;      // 数据体字节1(声道配置)  
  41. reg [7:0] r_body_sb2;      // 数据体字节2(采样率/深度)  
  42. reg [7:0] r_body_sb3;      // 数据体字节3(保留字段)  
  43. reg [7:0] r_body_sb4;      // 数据体字节4(保留字段)  
  44. reg [7:0] r_body_sb5;      // 数据体字节5(保留字段)  
  45. reg [7:0] r_body_sb6;      // 数据体字节6(保留字段)  
  46. //=======================================================================  
  47. // 数据拼接组合逻辑  
  48. //=======================================================================  
  49. wire [23:0] w_header = {r_header_hb2, r_header_hb1, r_header_hb0}; // 24bit包头  
  50. wire [55:0] w_body   = {r_body_sb6, r_body_sb5, r_body_sb4,       // 56bit数据体  
  51.                        r_body_sb3, r_body_sb2, r_body_sb1, r_body_sb0};  
  52. //=======================================================================  
  53. // 音频信息帧构造逻辑(CTS 1.4b S6.3.3)  
  54. //=======================================================================  
  55. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  56.     if (!I_reset_n) begin  // 异步复位初始化  
  57.         r_header_hb0 <= 8'h0;  
  58.         r_header_hb1 <= 8'h0;  
  59.         r_header_hb2 <= 8'h0;  
  60.         r_body_sb0   <= 8'h0;  
  61.         r_body_sb1   <= 8'h0;  
  62.         r_body_sb2   <= 8'h0;  
  63.         r_body_sb3   <= 8'h0;  
  64.         r_body_sb4   <= 8'h0;  
  65.         r_body_sb5   <= 8'h0;  
  66.         r_body_sb6   <= 8'h0;  
  67.     end else begin        // 动态字段构造  
  68.         //---------------- 固定包头 ----------------  
  69.         r_header_hb0 <= HEADER_HB0;  // 包类型标识  
  70.         r_header_hb1 <= HEADER_HB1;  // 协议版本  
  71.         r_header_hb2 <= HEADER_HB2;  // 数据长度  
  72.         //---------------- 动态数据体 ----------------  
  73.         // SB0: 校验和 = 0x100 - (HB0+HB1+HB2+SB1+SB2+SB3+SB4+SB5)  
  74.         // 注:采用补码形式计算,等效于1 + ~(sum)  
  75.         r_body_sb0 <= 8'd1 + ~(r_header_hb0 + r_header_hb1 + r_header_hb2 +  
  76.                               r_body_sb1 + r_body_sb2 + r_body_sb3 +  
  77.                               r_body_sb4 + r_body_sb5);  
  78.         // SB1: [7:5]=保留位 [4:0]=音频声道数(0-7对应2-8声道)  
  79.         r_body_sb1 <= {3'b000, I_audio_channel_count};   
  80.         // SB2: [7:5]=保留位 [4:2]=采样率 [1:0]=采样深度  
  81.         r_body_sb2 <= {3'b000, I_audio_sample_frequency, I_audio_sample_size};  
  82.         r_body_sb3 <= SB_RESERVED;    // SB3保留  
  83.         r_body_sb4 <= SB_RESERVED;    // SB4保留  
  84.         r_body_sb5 <= SB_RESERVED;    // SB5保留  
  85.         r_body_sb6 <= SB_RESERVED;    // SB6保留  
  86.     end  
  87. end  
  88. //=======================================================================  
  89. // BCH编码器实例化  
  90. //=======================================================================  
  91. wire [7:0] w_header_ecc, w_body_ecc;  
  92. BCH_32_24_encode u_BCH_32_24_encode(  // 包头BCH(32,24)编码器  
  93.     .I_clk         (I_pixel_clk),  
  94.     .I_data_in     (w_header),       // 24bit包头数据  
  95.     .O_bch_ecc_out (w_header_ecc)     // 8bit ECC校验码  
  96. );  
  97. BCH_64_56_encode u_BCH_64_56_encode(  // 数据体BCH(64,56)编码器  
  98.     .I_clk         (I_pixel_clk),  
  99.     .I_data_in     (w_body),         // 56bit有效数据  
  100.     .O_bch_ecc_out (w_body_ecc)      // 8bit ECC校验码  
  101. );  
  102. //=======================================================================  
  103. // BCH块输出组合逻辑  
  104. //=======================================================================  
  105. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  106.     if (!I_reset_n) begin  // 复位清零  
  107.         O_BCH_block_4 <= 32'b0;  
  108.         O_BCH_block_3 <= 64'b0;  
  109.         O_BCH_block_2 <= 64'b0;  
  110.         O_BCH_block_1 <= 64'b0;  
  111.         O_BCH_block_0 <= 64'b0;  
  112.     end else begin          // 正常输出  
  113.         O_BCH_block_4 <= {w_header_ecc, w_header};  // 包头+ECC(32bit)  
  114.         O_BCH_block_3 <= {w_body_ecc, w_body};     // 数据体+ECC(64bit)  
  115.         O_BCH_block_2 <= 64'h0;                     // 保留区置零  
  116.         O_BCH_block_1 <= 64'h0;  
  117.         O_BCH_block_0 <= 64'h0;  
  118.     end  
  119. end  
  120. endmodule
复制代码
2.5通用控制包(General Control Packet

通用控制分组报头不包含数据。接收器应忽略字节HB1HB2。通用控制包主体应包含四个相同的子包。

2.5.1通用控制包报头(General Control Packet Header
640?wx_fmt=png&from=appmsg

Header包头是固定值,所以无需讨论

2.5.2通用控制子包(General Control Subpacket
640?wx_fmt=png&from=appmsg

AVMUTE值(0=静音黑屏)我们选择关闭AVMUTEClear_AVMUTE1Clear_AVMUTE0

色深(CD)

640?wx_fmt=png&from=appmsg

默认我们使用24bits

像素打包相位(PP)

640?wx_fmt=png&from=appmsg

默认选择0

2.5.3通用控制包(General Control Packet)代码

该模块是HDMI通用控制信息帧封装器,核心功能包括:根据HDMI 1.4b CTS 6.8节规范构建通用控制包(包头标识0x03),动态配置色深(24/30bpp等)、数据包相位偏移及AV静默控制(通过SB0字段的AVMUTE正反相标志),将控制参数封装为56位数据体(含7字节控制字段),通过BCH(32,24)BCH(64,56)编码分别对24位包头与56位有效数据生成8ECC校验码,输出五组BCH数据块(块4含包头+ECC,块0含控制参数数据体+ECC,其余块填零),用于在视频消隐期传输显示控制指令,实现色彩深度同步、数据包相位校准及音视频静默切换功能。

  1. `timescale 1ns / 1ps  
  2. //////////////////////////////////////////////////////////////////////////////////  
  3. // 通用控制信息帧封装模块(符合HDMI 1.4b规范第6.8节)  
  4. // 功能特性:  
  5. // 1. 生成通用控制包(General Control Packet)用于传输显示控制参数  
  6. // 2. 支持色彩深度、数据包相位等关键参数配置  
  7. // 3. 集成BCH(32,24)和BCH(64,56)前向纠错编码  
  8. // 关键参数说明:  
  9. // - 包头标识符0x03对应通用控制包(HDMI规范表5-8)  
  10. // - 数据包长度固定为0字节(HB1/HB2保留)  
  11. // - SB0控制字段定义见CTS 6.8.2节  
  12. //////////////////////////////////////////////////////////////////////////////////  
  13. module general_control_packet(  
  14.     //================= 系统接口 =================  
  15.     input  wire        I_pixel_clk,        // 74.25MHz像素时钟(TMDS时钟的1/2)  
  16.     input  wire        I_reset_n,          // 异步复位(低电平有效,CTS 6.8.1要求)  
  17.    
  18.     //================= 配置输入 ================  
  19.     input  wire [3:0]  I_ctrl_color_depth,     // 4bit色深配置(0000=24bpp,0001=30bpp,...)  
  20.     input  wire [3:0]  I_ctrl_packet_phase,    // 4bit相位配置(视频数据包偏移控制)  
  21.     input  wire        I_audio_video_valid,    // AV有效指示(0=静音/黑屏,1=正常输出)  
  22.    
  23.     //================= 数据包输出 ==============  
  24.     output reg  [31:0] O_BCH_block_4,       // BCH块4:[31:24]=包头ECC,[23:0]=包头  
  25.     output reg  [63:0] O_BCH_block_3,      // BCH块3:保留区(强制置零)  
  26.     output reg  [63:0] O_BCH_block_2,      // BCH块2:保留区(强制置零)  
  27.     output reg  [63:0] O_BCH_block_1,      // BCH块1:保留区(强制置零)  
  28.     output reg  [63:0] O_BCH_block_0       // BCH块0:[63:56]=数据体ECC,[55:0]=有效数据  
  29. );  
  30. //=======================================================================  
  31. // HDMI规范参数定义(CTS 6.8.2通用控制包格式)  
  32. //=======================================================================  
  33. localparam [7:0] HEADER_HB0    = 8'h03; // 包类型标识符(0x03=通用控制包)  
  34. localparam [7:0] HEADER_HB1    = 8'h00; // 保留字段(必须置零)  
  35. localparam [7:0] HEADER_HB2    = 8'h00; // 保留字段(必须置零)  
  36. localparam [7:0] SB_RESERVED   = 8'h00; // 保留字段填充值(必须置零)  
  37. //=======================================================================  
  38. // 寄存器组声明  
  39. //=======================================================================  
  40. reg [7:0] r_header_hb0;    // 包头字节0(类型标识)  
  41. reg [7:0] r_header_hb1;    // 包头字节1(保留)  
  42. reg [7:0] r_header_hb2;    // 包头字节2(保留)  
  43. reg [7:0] r_body_sb0;      // 数据体字节0(控制字段)  
  44. reg [7:0] r_body_sb1;      // 数据体字节1(相位/色深配置)  
  45. reg [7:0] r_body_sb2;      // 数据体字节2(保留)  
  46. reg [7:0] r_body_sb3;      // 数据体字节3(保留)  
  47. reg [7:0] r_body_sb4;      // 数据体字节4(保留)  
  48. reg [7:0] r_body_sb5;      // 数据体字节5(保留)  
  49. reg [7:0] r_body_sb6;      // 数据体字节6(保留)  
  50. //=======================================================================  
  51. // 数据拼接组合逻辑  
  52. //=======================================================================  
  53. wire [23:0] w_header = {r_header_hb2, r_header_hb1, r_header_hb0}; // 24bit包头  
  54. wire [55:0] w_body   = {r_body_sb6, r_body_sb5, r_body_sb4,       // 56bit数据体  
  55.                        r_body_sb3, r_body_sb2, r_body_sb1, r_body_sb0};  
  56. //=======================================================================  
  57. // 控制包构造逻辑(CTS 6.8.2节时序要求)  
  58. //=======================================================================  
  59. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  60.     if (!I_reset_n) begin  // 异步复位初始化  
  61.         r_header_hb0 <= 8'h0;  
  62.         r_header_hb1 <= 8'h0;  
  63.         r_header_hb2 <= 8'h0;  
  64.         r_body_sb0   <= 8'h0;  
  65.         r_body_sb1   <= 8'h0;  
  66.         r_body_sb2   <= 8'h0;  
  67.         r_body_sb3   <= 8'h0;  
  68.         r_body_sb4   <= 8'h0;  
  69.         r_body_sb5   <= 8'h0;  
  70.         r_body_sb6   <= 8'h0;  
  71.     end else begin        // 动态字段构造  
  72.         //---------------- 固定包头 ----------------  
  73.         r_header_hb0 <= HEADER_HB0;  // 类型标识符  
  74.         r_header_hb1 <= HEADER_HB1;  // 保留字段  
  75.         r_header_hb2 <= HEADER_HB2;  // 保留字段  
  76.         //---------------- 动态数据体 ----------------  
  77.         // SB0: [7:4]=保留 [3]=AVMUTE(0=静音黑屏)[2:1]=保留 [0]=AVMUTE反相  
  78.         // 注:CTS 6.8.2要求AVMUTE标志需同时设置正反相信号  
  79.         r_body_sb0 <= {4'b0000,I_audio_video_valid, 2'b00,  ~I_audio_video_valid};   
  80.         // SB1: [7:4]=相位配置 [3:0]=色深配置  
  81.         r_body_sb1 <= {I_ctrl_packet_phase, I_ctrl_color_depth};  
  82.         r_body_sb2 <= SB_RESERVED;   // SB2保留  
  83.         r_body_sb3 <= SB_RESERVED;    // SB3保留  
  84.         r_body_sb4 <= SB_RESERVED;    // SB4保留  
  85.         r_body_sb5 <= SB_RESERVED;    // SB5保留  
  86.         r_body_sb6 <= SB_RESERVED;    // SB6保留  
  87.     end  
  88. end  
  89. //=======================================================================  
  90. // BCH编码器实例化  
  91. //=======================================================================  
  92. wire [7:0] w_header_ecc, w_body_ecc;  
  93. BCH_32_24_encode u_BCH_32_24_encode(  // 包头BCH(32,24)编码器  
  94.     .I_clk         (I_pixel_clk),  
  95.     .I_data_in     (w_header),       // 24bit包头数据  
  96.     .O_bch_ecc_out (w_header_ecc)     // 8bit ECC校验码  
  97. );  
  98. BCH_64_56_encode u_BCH_64_56_encode(  // 数据体BCH(64,56)编码器  
  99.     .I_clk         (I_pixel_clk),  
  100.     .I_data_in     (w_body),         // 56bit有效数据  
  101.     .O_bch_ecc_out (w_body_ecc)      // 8bit ECC校验码  
  102. );  
  103. //=======================================================================  
  104. // BCH块输出组合逻辑(HDMI规范S5.3.2分组规则)  
  105. //=======================================================================  
  106. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  107.     if (!I_reset_n) begin  // 复位清零  
  108.         O_BCH_block_4 <= 32'b0;  
  109.         O_BCH_block_3 <= 64'b0;  
  110.         O_BCH_block_2 <= 64'b0;  
  111.         O_BCH_block_1 <= 64'b0;  
  112.         O_BCH_block_0 <= 64'b0;  
  113.     end else begin          // 正常输出  
  114.         O_BCH_block_4 <= {w_header_ecc, w_header};  // 包头+ECC(32bit)  
  115.         O_BCH_block_3 <= 64'h0;                     // 保留区置零  
  116.         O_BCH_block_2 <= 64'h0;  
  117.         O_BCH_block_1 <= 64'h0;  
  118.         O_BCH_block_0 <= {w_body_ecc, w_body};      // 数据体+ECC(64bit)  
  119.     end  
  120. end  
  121. endmodule
复制代码
3 数据包仿真
3.1音频时钟再生包(Audio Clock Regeneration Packet)仿真
640?wx_fmt=png&from=appmsg

固定数值输出,不过多解释

3.2音频样本包(Audio Sample Packet)仿真
640?wx_fmt=png&from=appmsg

输出数据信息与输入数据信息保持一致。

3.3辅助视频信息(AVI)信息包(Auxiliary Video information (AVI) InfoFrame  Packet)仿真
640?wx_fmt=png&from=appmsg

固定数值输出,不过多解释

3.4音频信息帧包(Audio InfoFrame Packet)仿真
640?wx_fmt=png&from=appmsg
3.5通用控制包(General Control Packet)仿真
640?wx_fmt=png&from=appmsg

固定数值输出,不过多解释


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

0

关注

0

粉丝

303

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

  • 微信公众平台

  • 扫描访问手机版