问答 店铺
热搜: ZYNQ FPGA discuz

QQ登录

只需一步,快速开始

微信登录

微信扫码,快速开始

微信扫一扫 分享朋友圈

已有 39 人浏览分享

开启左侧

HDMI-IP项目-主讲TMDS三通道数据拆分-连载十一

[复制链接]
39 0
1概述

经过前期对HDMI传输原理的系统性解析及HDMI_TX输出端IP核的实现,本课程正式进入系统功能扩展阶段。

基于已构建的HDMI图像输入输出IP架构,本节将重点集成音频解析模块,通过分离复合数据流中的音频信号实现音视频同步处理。该功能扩展完整遵循HDMI多媒体传输协议,为构建全功能音视频传输系统奠定技术基础,后续将围绕系统级联调试与功能验证展开深入探讨。

2数据拆分

在完成基于auto_delay_ctl.v IP核的通道数据对齐后,需依据视频前导码(Video Preamble)、数据岛前导码(Island Preamble)及其对应保护带(Guard Band)特征,从并行数据流中分离出island_datavideo_data

本设计采用通道2作为主时序基准,通过解析其前导码与保护带边界实现数据分类,通道0和通道1作为从属通道仅需保持与主通道的时序同步,通过延迟补偿确保跨通道数据相位一致性。该架构在降低多通道协同复杂度同时,保证了数据拆分的精确性和系统稳定性。

2.1 island_data_decode_master.v模块代码

该模块作为HDMI数据岛周期解码核心,基于四级流水线结构实现输入数据对齐,并采用含空闲、前导码检测、保护带识别及有效数据周期等七状态有限状态机,精准划分视频与数据岛传输阶段。依据HDMI 1.4a协议规范,通过TERC4解码将10位控制字符映射为4位数据岛信息,同步分离视频原始数据流。

输出端通过O_island_data_validO_video_data_valid双效验标志实现数据类型精确区分,结合保护带检测逻辑识别特定字符序列,确保接收端时序同步精度及数据传输可靠性。

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // 模块名称:island_data_decode_master
  4. // 功能描述:HDMI数据岛周期解码模块
  5. // 主要功能:
  6. //   1. 检测并解码HDMI数据岛周期中的TERC4编码数据
  7. //   2. 分离视频数据流和数据岛控制数据流
  8. //   3. 实现HDMI 1.4a协议第5章规定的数据周期转换
  9. // 设计要点:
  10. //   - 四级流水线结构处理时序对齐
  11. //   - 有限状态机实现协议状态转换
  12. //   - 通道参数化设计支持多通道配置
  13. //////////////////////////////////////////////////////////////////////////////////
  14. module island_data_decode_master  (
  15.     input  wire         I_pixel_clk,         // 像素时钟
  16.     input  wire         I_reset_n,           // 异步复位,低有效
  17.     input  wire [9:0]   I_hdmi_data_code,    // HDMI 10位编码数据输入
  18.     input  wire         I_island_data_vaild, // 数据岛有效标志,高有效
  19.     input  wire         I_video_data_vaild,  // 视频数据有效标志,高有效  
  20.     output reg  [3:0]   O_island_data,       // 解码后的4位数据岛数据
  21.     output reg          O_island_data_vaild, // 数据岛有效标志,高有效
  22.     output reg [9:0]    O_video_data,        // 视频数据输出
  23.     output reg          O_video_data_vaild,  // 视频数据有效标志,高有效
  24.     output reg          O_island_guardband    // 数据岛保护标志,高有效   
  25. );
  26. // ====================== 状态机参数定义 ======================
  27. // 依据HDMI 1.4a规范第5.2.3节设计状态转换
  28. parameter [2:0] ST_IDLE                 = 3'd0;  // 空闲状态,等待前导码
  29. parameter [2:0] ST_PREAMBLE_CHARGE      = 3'd1;  // 前导码检测
  30. parameter [2:0] ST_ISLAND_PREAMBLE      = 3'd2;  // 数据岛前导码检测
  31. parameter [2:0] ST_DATA_ISLAND_LEAD_GB  = 3'd3;  // 数据岛前导保护带检测
  32. parameter [2:0] ST_DATA_ISLAND_ACTIVE   = 3'd4;  // 数据岛有效数据周期
  33. parameter [2:0] ST_VIDEO_LEAD_GB        = 3'd5;  // 视频数据前导保护带检测
  34. parameter [2:0] ST_VIDEO_ACTIVE         = 3'd6;  // 视频数据有效周期
  35. // ====================== HDMI协议常量定义 ======================
  36. // 根据HDMI 1.4a规范表5-5定义各通道控制字符
  37. localparam [9:0] VIDEO_PREAMBLE         = 10'b0010101011;  // 通道2视频前导码
  38. localparam [9:0] DATA_ISLAND_PREAMBLE   = 10'b1101010100;  // 通道2数据岛前导码
  39. localparam [9:0] VIDEO_GUARD_BAND       = 10'b0011001101;  // 通道2视频保护带
  40. localparam [9:0] DATA_ISLAND_GUARD_BAND = 10'b1100110010;  // 通道2数据岛保护带
  41. localparam [9:0] CONTOL_DATA            = 10'b0010101011;  // 控制信号00
  42. // ====================== 寄存器声明 ======================
  43. reg [9:0] r_input_pipeline_0d;    // 3级输入流水线寄存器
  44. reg [9:0] r_input_pipeline_1d;    // 3级输入流水线寄存器
  45. reg [9:0] r_input_pipeline_2d;    // 3级输入流水线寄存器
  46. reg [9:0] r_video_data;
  47. reg [5:0] r_preamble_counter;        // 前导码连续检测计数器(0-7)
  48. reg [1:0] r_guardband_counter;       // 保护带检测计数器(0-2)
  49. reg [2:0] r_current_state;           // 当前状态寄存器
  50. reg [2:0] r_next_state;
  51. // ====================== 输入流水线处理 ======================
  52. // 四级流水线用于时序对齐,补偿状态机检测延迟
  53. always @(posedge I_pixel_clk) begin
  54.     r_input_pipeline_0d <= I_hdmi_data_code;  // 第一级:原始输入
  55.     r_input_pipeline_1d <= r_input_pipeline_0d;
  56.     r_input_pipeline_2d <= r_input_pipeline_1d;
  57.     end
  58. always @(posedge I_pixel_clk or negedge I_reset_n) begin
  59.     if (!I_reset_n)   // 异步复位初始化
  60.         r_preamble_counter <= 6'd0;
  61.     else if (((r_input_pipeline_1d == VIDEO_PREAMBLE) | (r_input_pipeline_1d == DATA_ISLAND_PREAMBLE)) & (r_input_pipeline_1d == r_input_pipeline_2d))
  62.         r_preamble_counter <= r_preamble_counter + 6'd1;   
  63.     else  
  64.         r_preamble_counter <= 6'd0;  
  65.     end
  66. always @(posedge I_pixel_clk or negedge I_reset_n) begin
  67.     if (!I_reset_n)   // 异步复位初始化
  68.         r_guardband_counter <= 2'd0;
  69.     else if (((r_input_pipeline_1d == DATA_ISLAND_GUARD_BAND) | (r_input_pipeline_1d == VIDEO_GUARD_BAND)) & (r_input_pipeline_1d == r_input_pipeline_2d))
  70.         r_guardband_counter <= r_guardband_counter + 2'd1;
  71.     else  
  72.         r_guardband_counter <= 2'd0;  
  73.     end
  74. // ====================== 主状态机控制器 ======================
  75. // 状态寄存器(时序逻辑)  
  76. always @(posedge I_pixel_clk or negedge I_reset_n) begin  
  77.     if (!I_reset_n) begin  
  78.         r_current_state <= ST_IDLE;  // 异步复位到空闲状态  
  79.     end else begin  
  80.         r_current_state <= r_next_state;  // 状态更新  
  81.     end  
  82. end
  83. always @(*) begin
  84.     case (r_current_state)
  85.         // 状态1:空闲状态,等待有效前导码
  86.         ST_IDLE: begin
  87.             if (r_input_pipeline_1d == VIDEO_PREAMBLE || r_input_pipeline_1d == DATA_ISLAND_PREAMBLE)
  88.                 r_next_state = ST_PREAMBLE_CHARGE;
  89.             else   
  90.                 r_next_state = ST_IDLE;
  91.         end
  92.         
  93.         ST_PREAMBLE_CHARGE: begin
  94.             if (r_input_pipeline_1d == VIDEO_PREAMBLE || r_input_pipeline_1d == DATA_ISLAND_PREAMBLE) //持续检测视频前导码
  95.                 r_next_state = ST_PREAMBLE_CHARGE;
  96.             else if (r_preamble_counter >= 6'd7 && r_input_pipeline_1d == VIDEO_GUARD_BAND)  // 连续视频前导码后面检测到视频保护带符合条件
  97.                 r_next_state =  ST_VIDEO_LEAD_GB ;
  98.             else if (r_preamble_counter >= 6'd7 && r_input_pipeline_1d == DATA_ISLAND_GUARD_BAND)  // // 连续数据岛前导码后面检测到数据岛保护带符合条件
  99.                 r_next_state =  ST_DATA_ISLAND_LEAD_GB ;
  100.             else
  101.                 r_next_state = ST_IDLE;
  102.         end
  103.         ST_DATA_ISLAND_LEAD_GB: begin
  104.             if (r_input_pipeline_1d == DATA_ISLAND_GUARD_BAND)
  105.                 r_next_state = ST_DATA_ISLAND_ACTIVE ;
  106.             else   // 保护带错误返回空闲
  107.                 r_next_state = ST_IDLE;
  108.         end
  109.         
  110.         // 状态4:数据岛有效数据周期
  111.         ST_DATA_ISLAND_ACTIVE: begin
  112.             if (r_input_pipeline_0d == DATA_ISLAND_GUARD_BAND && I_hdmi_data_code == DATA_ISLAND_GUARD_BAND)   // 检测后导保护带
  113.                 r_next_state =  ST_IDLE ;
  114.             else
  115.                 r_next_state = ST_DATA_ISLAND_ACTIVE;
  116.         end
  117.         
  118.         // 状态5:视频数据前导保护带检测
  119.         ST_VIDEO_LEAD_GB: begin
  120.             if (r_input_pipeline_1d == VIDEO_GUARD_BAND)
  121.                 r_next_state =  ST_VIDEO_ACTIVE ;
  122.             else
  123.                 r_next_state = ST_IDLE;
  124.         end
  125.         
  126.         // 状态6:视频数据有效周期
  127.         ST_VIDEO_ACTIVE: begin
  128.             if ((r_input_pipeline_0d == DATA_ISLAND_PREAMBLE ) || (r_input_pipeline_0d == CONTOL_DATA))   // 检测到新前导码切换
  129.                 r_next_state = ST_IDLE;
  130.             else
  131.                 r_next_state = ST_VIDEO_ACTIVE;
  132.         end
  133.         
  134.         default: r_next_state = ST_IDLE;  // 默认返回空闲状态
  135.     endcase
  136. end
  137. // ====================== TERC4解码模块 ======================
  138. always @(*) begin
  139.     if (I_island_data_vaild) begin
  140.         case (r_input_pipeline_2d)  // 使用流水线第3级数据进行解码
  141.             // TERC4编码映射表
  142.             10'b0011100101 : O_island_data = 4'b0000;  // 数据0
  143.             10'b1100011001 : O_island_data = 4'b0001;  // 数据1
  144.             10'b0010011101 : O_island_data = 4'b0010;  // 数据2
  145.             10'b0100011101 : O_island_data = 4'b0011;  // 数据3
  146.             10'b1000111010 : O_island_data = 4'b0100;  // 数据4
  147.             10'b0111100010 : O_island_data = 4'b0101;  // 数据5
  148.             10'b0111000110 : O_island_data = 4'b0110;  // 数据6
  149.             10'b0011110010 : O_island_data = 4'b0111;  // 数据7
  150.             10'b0011001101 : O_island_data = 4'b1000;  // 数据8
  151.             10'b1001110010 : O_island_data = 4'b1001;  // 数据9
  152.             10'b0011100110 : O_island_data = 4'b1010;  // 数据A
  153.             10'b0110001101 : O_island_data = 4'b1011;  // 数据B
  154.             10'b0111000101 : O_island_data = 4'b1100;  // 数据C
  155.             10'b1000111001 : O_island_data = 4'b1101;  // 数据D
  156.             10'b1100011010 : O_island_data = 4'b1110;  // 数据E
  157.             10'b1100001101 : O_island_data = 4'b1111;  // 数据F
  158.             default: O_island_data = 4'b0000;         // 无效编码默认处理
  159.         endcase
  160.     end else begin
  161.         O_island_data = 4'h0;        // 非数据岛周期输出清零
  162.     end
  163. end
  164. always @(posedge I_pixel_clk or negedge I_reset_n) begin
  165.     if (!I_reset_n)
  166.         O_island_data_vaild <= 1'b0;  // 有效标志清零
  167.     else if (r_current_state == ST_DATA_ISLAND_ACTIVE)
  168.         O_island_data_vaild <= 1'b1;  // 数据有效标志置位
  169.     else if (r_current_state != ST_DATA_ISLAND_ACTIVE)
  170.         O_island_data_vaild <= 1'b0;  // 数据有效标志置位置零
  171.     else   
  172.         O_island_data_vaild <= O_island_data_vaild;  // 信号保持
  173.     end
  174. // ====================== 视频数据处理模块 ======================
  175. always @(posedge I_pixel_clk or negedge I_reset_n) begin
  176.     if (!I_reset_n)
  177.         O_video_data_vaild <= 1'b0;  // 有效标志清零
  178.     else if (r_current_state == ST_VIDEO_ACTIVE)
  179.         O_video_data_vaild <= 1'b1;  // 数据有效标志置位
  180.     else if (r_current_state != ST_VIDEO_ACTIVE)
  181.         O_video_data_vaild <= 1'b0;  // 数据有效标志置位置零
  182.     else   
  183.         O_video_data_vaild <= O_video_data_vaild;  // 信号保持
  184.     end
  185. always @(posedge I_pixel_clk or negedge I_reset_n) begin
  186.     if (!I_reset_n)
  187.         O_video_data <= 10'h000;  // 有效标志清零
  188.     else  if(r_current_state == ST_VIDEO_ACTIVE)
  189.         O_video_data <= r_input_pipeline_1d;  // 数据有效标志置位
  190.     else
  191.         O_video_data <= 10'h000;
  192.     end
  193. always @(posedge I_pixel_clk or negedge I_reset_n) begin
  194.     if (!I_reset_n)
  195.         O_island_guardband <= 1'b0;  // 有效标志清零
  196.     else if ((r_current_state == ST_PREAMBLE_CHARGE) && (r_input_pipeline_1d == VIDEO_GUARD_BAND))
  197.         O_island_guardband <= 1'b1;  // 数据有效标志置位
  198.     else if ((r_current_state == ST_PREAMBLE_CHARGE) && (r_input_pipeline_1d == DATA_ISLAND_GUARD_BAND))
  199.         O_island_guardband <= 1'b1;  // 数据有效标志置位
  200.     else if ((r_current_state == ST_IDLE) && (r_input_pipeline_1d == DATA_ISLAND_GUARD_BAND))
  201.         O_island_guardband <= 1'b1;  // 数据有效标志置位
  202.     else if (r_guardband_counter == 2'd1)
  203.         O_island_guardband <= 1'b0;  // 数据有效标志置位置零
  204.     else   
  205.         O_island_guardband <= O_island_guardband;  // 信号保持
  206.     end
  207. endmodule
复制代码
2.2 island_data_decode_slave.v模块代码

该模块作为HDMI数据岛解码从属单元,基于三级流水线结构实现数据时序对齐。在数据岛有效周期(I_island_data_vaild)内,采用TERC4解码算法,依据HDMI 1.4a协议将10TMDS编码实时解析为4位数据岛信息;视频有效周期(I_video_data_vaild)则通过O_video_data通道直通原始10位像素数据。非有效周期自动透传控制字符(前导码/保护带)至O_control_data通道,实现视频流、数据岛包及控制信号的三通道并行输出,可高效集成于多通道HDMI接收系统的解码子系统。

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // 模块名称:island_data_decode_slave
  4. // 功能描述:HDMI数据岛周期解码模块
  5. // 主要功能:
  6. //   1. 检测并解码HDMI数据岛周期中的TERC4编码数据
  7. //   2. 分离视频数据流和数据岛控制数据流
  8. //   3. 实现HDMI 1.4a协议第5章规定的数据周期转换
  9. //////////////////////////////////////////////////////////////////////////////////
  10. module island_data_decode_slave  (
  11.     input  wire         I_pixel_clk,         // 像素时钟
  12.     input  wire         I_reset_n,           // 异步复位,低有效
  13.     input  wire [9:0]   I_hdmi_data_code,    // HDMI 10位编码数据输入
  14.     input  wire         I_island_data_vaild, // 数据岛有效标志,高有效
  15.     input  wire         I_video_data_vaild,  // 视频数据有效标志,高有效  
  16.     output reg  [3:0]   O_island_data,       // 解码后的4位数据岛数据
  17.     output wire [9:0]   O_video_data,        // 视频数据输出
  18.     output wire [9:0]   O_control_data       // 控制数据输出,包含前导码数据、保护带数据、空白数据
  19. );
  20. // ====================== 寄存器声明 ======================
  21. reg [9:0] r_input_pipeline_0d;    // 3级输入流水线寄存器
  22. reg [9:0] r_input_pipeline_1d;    // 3级输入流水线寄存器
  23. reg [9:0] r_input_pipeline_2d;    // 3级输入流水线寄存器
  24. // ====================== 输入流水线处理 ======================
  25. // 四级流水线用于时序对齐,补偿状态机检测延迟
  26. always @(posedge I_pixel_clk) begin
  27.     r_input_pipeline_0d <= I_hdmi_data_code;  // 第一级:原始输入
  28.     r_input_pipeline_1d <= r_input_pipeline_0d;
  29.     r_input_pipeline_2d <= r_input_pipeline_1d;
  30.     end
  31. // ====================== TERC4解码模块 ======================
  32. always @(*) begin
  33.     if (I_island_data_vaild) begin
  34.         case (r_input_pipeline_2d)  // 使用流水线第3级数据进行解码
  35.             // TERC4编码映射表
  36.             10'b0011100101 : O_island_data = 4'b0000;  // 数据0
  37.             10'b1100011001 : O_island_data = 4'b0001;  // 数据1
  38.             10'b0010011101 : O_island_data = 4'b0010;  // 数据2
  39.             10'b0100011101 : O_island_data = 4'b0011;  // 数据3
  40.             10'b1000111010 : O_island_data = 4'b0100;  // 数据4
  41.             10'b0111100010 : O_island_data = 4'b0101;  // 数据5
  42.             10'b0111000110 : O_island_data = 4'b0110;  // 数据6
  43.             10'b0011110010 : O_island_data = 4'b0111;  // 数据7
  44.             10'b0011001101 : O_island_data = 4'b1000;  // 数据8
  45.             10'b1001110010 : O_island_data = 4'b1001;  // 数据9
  46.             10'b0011100110 : O_island_data = 4'b1010;  // 数据A
  47.             10'b0110001101 : O_island_data = 4'b1011;  // 数据B
  48.             10'b0111000101 : O_island_data = 4'b1100;  // 数据C
  49.             10'b1000111001 : O_island_data = 4'b1101;  // 数据D
  50.             10'b1100011010 : O_island_data = 4'b1110;  // 数据E
  51.             10'b1100001101 : O_island_data = 4'b1111;  // 数据F
  52.             default: O_island_data = 4'b0000;         // 无效编码默认处理
  53.         endcase
  54.     end else begin
  55.         O_island_data = 4'h0;        // 非数据岛周期输出清零
  56.     end
  57. end
  58. assign O_video_data = I_video_data_vaild ? r_input_pipeline_2d: 10'h000;  // 视频数据输出连接
  59. assign O_control_data = (!I_video_data_vaild && !I_island_data_vaild) ? r_input_pipeline_2d: 10'b0;
  60. endmodule
复制代码
3模块仿真
3.1 island_data_decode_master.v模块仿真

主模块根据输入的原始数据拆分出数据岛有效数据和视频数据有效数据,同时提取出保护带信号。保护带信号可以用于从通道0中恢复出控制信号。这部分后续恢复控制信号时候再详细讲解。

640?wx_fmt=png&from=appmsg
3.2 island_data_decode_slave.v模块仿真

从模块根据从主模块输入的I_island_data_vaildI_video_data_vaild信号,对原始数据进行拆分,同时进行TERC4解码输出4位数据岛数据。

640?wx_fmt=png&from=appmsg


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

本版积分规则

0

关注

0

粉丝

303

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

  • 微信公众平台

  • 扫描访问手机版