HDMI LVDS 工程学习记录

该帖子内容已隐藏,请评论后查看

登录后继续评论

720p HDMI 透传工程 — 涵盖 TMDS 编解码、LVDS 差分 IO、SERDES 原语、相位对齐算法、跨时钟域设计


一、背景知识:HDMI 与 TMDS

1.1 HDMI 物理层

HDMI 使用 TMDS(Transition Minimized Differential Signaling) 串行差分传输,包含:

通道 内容 本工程速率(720p)
DATA[0](蓝) B[7:0] + HS + VS(消隐期) 742.5 Mbps
DATA[1](绿) G[7:0] 742.5 Mbps
DATA[2](红) R[7:0] 742.5 Mbps
CLK 像素时钟(74.25MHz编码为固定码 1111100000 74.25 MHz

1.2 TMDS 编码原理(8b10b,非标准)

TMDS 不是标准 8b10b,而是 DVI/HDMI 专用编码方案:

 原始 8bit 像素数据
    ↓ 第一步:异或/同或(选择 1 个数少的结果),得到 9bit
    ↓ 第二步:DC 平衡(记录累计极性,决定是否取反),得到 10bit
 
 10bit 中:
  bit[9] = 是否取反
  bit[8] = 异或/同或选择位
  bit[7:0]= 编码后数据
 
 消隐期(HS/VS/DE=0):发送固定控制字(CTRL TOKEN)
  CTRLTOKEN0 = 10'b1101010100 (HS=0, VS=0)
  CTRLTOKEN1 = 10'b0010101011 (HS=1, VS=0)
  CTRLTOKEN2 = 10'b0101010100 (HS=0, VS=1)
  CTRLTOKEN3 = 10'b1010101011 (HS=1, VS=1)

要点:控制字(CTRL TOKEN)的特殊编码使其在统计上极不可能出现在正常像素数据中,接收端专门检测这些固定码型来进行字对齐相位校准

1.3 TMDS 接收时序关系

  串行数据 ─────┐
                ├──→ ISERDES (1:10解串) ──→ 10bit 并行 ──→ TMDS解码 ──→ 8bit 像素
  位时钟         │
 (742.5MHz) ────┘
    ↑
  pll_5x × 5
    ↑
  CLKIN (74.25MHz,来自TMDS CLK通道)

二、工程整体架构

A板(发送)

 video_pll(50→74.25MHz)
    ↓ pix_clk
 sync_vg → pattern_vg → rgb2tmds → LVDS TX → [HDMI线缆]
              ↑                       ↑
          视频时序         tmds_encoder + outputserdes

B板(接收透传)

 [HDMI线缆] → LVDS RX → tmds2rgb → [rx_vid_de/hs/vs/data]
                                        ↓
                              rgb2tmds → LVDS TX → [显示器]

三、TX 路径详解

3.1 视频时序生成(sync_vg

标准视频时序由水平/垂直计数器产生,720p@60Hz 参数:

 H_TOTAL=1650  H_ACT=1280  H_SYNC=40  H_BP=220  H_FP=110
 V_TOTAL=750   V_ACT=720   V_SYNC=5   V_BP=20   V_FP=5
 像素时钟=74.25MHz

输出:hs(水平同步)、vs(垂直同步)、de(数据有效)、act_x/y(当前像素坐标)

3.2 图案生成(pattern_vg

根据 act_xact_y 坐标生成 RGB 测试图案(彩条/渐变)。

3.3 TMDS 编码(tmds_encoder,每通道一个)

 // 消隐期:输出控制字
 // 有效期:8bit RGB → TMDS 8b10b 编码 → 10bit
 // 蓝色通道(i=0)特殊:pc0=HS,pc1=VS 编入控制字中

3.4 串行化(outputserdes

使用 MASTER+SLAVE 两片 GTP_OSERDES_E2 级联实现 10:1 DDR 并串转换:

 10bit 并行(pixelclk=74.25MHz)
    ↓ GTP_OSERDES_E2 (DDR10TO1)
 1bit 串行(serialclk=371.25MHz,DDR等效742.5Mbps)
    ↓ GTP_OUTBUFDS
 TMDS 差分输出 (LVDS25,VCCIO=2.5V)

关键:Slave 提供 bit[9:8],Master 提供 bit[7:0],通过 cascade 连接。CLK 通道固定发送 10'b1111100000(无需编码)。


四、RX 路径详解(核心难点)

4.1 时钟恢复(tmds_input_clk_serdes

 HDMI CLK 差分输入
    ↓ GTP_INBUFGDS(差分→单端)
    ↓ GTP_CLKBUFG(进全局时钟网络)
    ↓ pll_5x(74.25MHz → 74.25MHz + 371.25MHz)
          ↓             ↓
    tmds_clk_1x   tmds_clk_5x
    (像素时钟)       (串行采样时钟)

为什么需要 pll_5x:接收到的 74.25MHz TMDS 时钟只是像素级频率,ISERDES 需要 5 倍的 371.25MHz 来对 742.5Mbps 的数据进行 DDR 采样(371.25×2=742.5Msps)。

4.2 解串与延迟调整(tmds_input_data_serdes

 差分数据输入
    ↓ GTP_INBUFDS(差分→单端)
    ↓ GTP_IODELAY_E2(输入延迟,5ps/step,动态可调)
    ↓ GTP_ISERDES_E2 MASTER(捕获 bit[7:0])
      GTP_ISERDES_E2 SLAVE (捕获 bit[9:8])
    ↓ 数据位序翻转(GTP_OSERDES 输出是反序的)
    ↓ 10bit 并行数据

IDELAY 的作用:精细调整数据采样时刻,找到信号眼图中心。步长 5ps,范围 0-247 步(0-1235ps)。

BITSLIP 的作用:当 10bit 字边界对齐错误时,移动一个比特位,重新建立字对齐。最多需要 10 次 BITSLIP 遍历所有可能对齐。

4.3 相位对齐状态机(phasealign)—— 最复杂的模块

核心思路:利用 TMDS 消隐期发送的固定 CTRL TOKEN,自动搜索正确的 IDELAY 步数和 BITSLIP 次数。

 ┌─────────────────────────────────────────────────────┐
 │                   状态机执行流程                       │
 │                                                       │
 │   ST_RESET → ST_IDLE                                 │
 │                 │                                   │
 │         在这里等待 CTRL TOKEN 或 超时(50μs)         │
 │                 │                 │                 │
 │           token出现           超时,信号不对         │
 │                 ↓                 ↓                 │
 │             ST_TOKEN       ST_JITTER_ZONE           │
 │                 │                 ↓                 │
 │         稳定16个 pix_clk     ST_INC_DELAY             │
 │                 ↓           (delay_cnt+1)           │
 │           ST_ALIGN_PASS     ST_DELAY_OVERTEST       │
 │           (锁定完成✅)           │                   │
 │                           若delay<64: → ST_IDLE 重试 │
 │                           若delay=64: → ST_ALIGN_ERROR│
 │                                           ↓         │
 │                                       触发 BITSLIP   │
 │                                       复位重试最多10次 │
 └─────────────────────────────────────────────────────┘

两个关键时钟域的协作

  • pix_clk(74.25MHz):运行 FSM 主体,检测 TOKEN,计数 BITSLIP 延迟

  • clk_200m(200MHz):运行超时计数器(200MHz 更稳定,且时钟频率固定,pix_clk 失锁时不稳定)

  • 跨时钟域:timeout_rst_pix → 200m(2-flop同步),timeout_max_200m → pix(2-flop同步)

IDELAY 搜索参数(优化后):

 Findeye_MAXDelay = 64   // 64步×5ps = 320ps,>pll_5x最大偏移±270ps
 Timeout_total_cnt= 10000 // @200MHz=50μs,覆盖完整H-blank(4.99μs/行)

4.4 通道对齐(channel_align

三路通道(R/G/B)的 phasealign 完成时刻可能不同,传播延迟也有差异。需要 FIFO 补偿通道间延迟差:

 // 原理:
 // 1. 各自 phasealign 完成(all_pligned)后,各通道数据写入 FIFO
 // 2. 等待三通道都ready,统一开始读FIFO
 // 3. 读指针对齐保证三路数据时间对齐
 // GTP_FIFO18K_E1 原语,因位宽不能为10,用了 channel_fifo_10to10(自定义FIFO)

4.5 TMDS 解码(decoder

 // 消隐期:识别CTRL TOKEN → 输出 HS/VS,pvde=0
 // 有效期:反 TMDS 解码
 //   bit[7:0] = (bit[9]=1) ? ~data[7:0] : data[7:0]   // 反转还原
 //   反差分解码:(bit[8]=1)? XOR还原 : XNOR还原       // 差分解码
 // 输出:8bit 像素数据 + pvde + hs + vs

五、时钟架构总览

 sys_clk (50MHz)
 ├── pll_sys → clk_200m (200MHz)
 │   用途:① phasealign 超时计时 ② 热插拔恢复计数器
 
 └── video_pll → pix_clk (74.25MHz) + pix_clk_5x (371.25MHz)
    [仅A板使用,B板已移除]
 
 HDMI RX CLK 输入 (74.25MHz)
 └── pll_5x → tmds_clk_1x (74.25MHz) + tmds_clk_5x (371.25MHz)
    用途:① ISERDES 采样时钟
          ② B板 TX 编码器时钟(与RX同源,无需CDC)
          ③ LED 计数器时钟(指示RX锁定状态)

六、跨时钟域(CDC)设计要点

6.1 单信号跨域:2-flip同步器

 // 将 clk_200m 域的信号同步到 rx_pix_clk 域
 reg [1:0] sync_ff;
 always @(posedge rx_pix_clk or negedge async_rst) begin
     if (!async_rst)  sync_ff <= 2'b00;
     else             sync_ff <= {sync_ff[0], signal_200m};
 end
 wire signal_pix = sync_ff[1];

注意:若目标时钟(rx_pix_clk)可能停振(如 PLL 失锁),必须将导致时钟停止的信号加入 async reset sensitivity list,否则同步器会冻结,无法正确复位。

6.2 本工程中的 CDC 场景

信号 源域 目标域 方式
timeout_max clk_200m pix_clk 2-flop 同步
timeout_rst pix_clk clk_200m 2-flop 同步
rx_recovery_done clk_200m rx_pix_clk 2-flop + async rst(含 !rx_tmds_locked

七、关键 FPGA 原语说明

原语 作用 本工程参数
GTP_INBUFGDS 差分输入→全局时钟缓冲 CLK通道
GTP_INBUFDS 差分输入→单端 DATA通道,无时钟网络
GTP_CLKBUFG 全局时钟缓冲 CLK通道,进全局时钟网
GTP_IODELAY_E2 输入延迟,5ps/step DELAY_STEP_SEL="PARAMETER",动态控制
GTP_ISERDES_E2 串并转换,1:10,DDR MASTER+SLAVE级联,BITSLIP使能
GTP_OSERDES_E2 并串转换,10:1,DDR MASTER+SLAVE级联,DDR10TO1模式
GTP_OUTBUFDS 单端→差分输出 TMDS模式,LVDS25
PLL原语 时钟频率/相位合成 video_pll/pll_sys/pll_5x

八、IO 约束要点

使用紫光同创 PDS 工具的 .fdc 约束文件:

 # 创建时钟约束
 create_clock -name {sys_clk} [get_ports {sys_clk}] -period {20.000}
 
 # IO 属性约束
 define_attribute {p:tmds_data_p[2]} {PAP_IO_STANDARD} {LVDS25}
 define_attribute {p:tmds_data_p[2]} {PAP_IO_LOC} {K19}
 define_attribute {p:tmds_data_p[2]} {PAP_IO_VCCIO} {2.5}
LVDS TX 引脚 IO标准 VCCIO
tmds_data/clk _p/n LVDS25 2.5V
LVDS RX 引脚 IO标准 额外设置
i_rx_tmds_data/clk_p/n LVDS25 BUS_KEEPER=NONEDIFF_IN_TERM_MODE=OFF

九、调试手段

9.1 在线逻辑分析仪(PAP_MARK_DEBUG)

紫光同创 PDS 支持类似 Vivado ILA 的在线调试,在需要观测的信号上添加属性:

 wire [9:0] data_10bit_ori; /* synthesis PAP_MARK_DEBUG="true" */

综合后在 PDS 中配置抓取条件,可在 FPGA 运行时捕获内部信号波形,对 phasealign 调试非常有用。

9.2 LED 状态指示

 // LED 由 RX 恢复时钟(74.25MHz)驱动,闪烁频率约 0.7Hz
 assign led = pwm_cnt[29:25];
 // LED 均匀闪烁 → RX 时钟正常
 // LED 全亮/全灭 → pll_5x 未锁定或 clk 停振

十、设计要点与学习总结

序号 要点
1 TMDS 编码是 DVI/HDMI 专用,不是标准 8b10b,消隐期发固定 CTRL TOKEN
2 RX 时钟恢复=先用 INBUFGDS 接收差分时钟,再用 pll_5x 生成 5×采样时钟
3 ISERDES 解串后数据有位反转,需用 generate 语句对 10bit 做逐位翻转
4 IDELAY 调细采样点(5ps级),BITSLIP 调字对齐(1bit级),两者配合完成对齐
5 phasealign 用 CTRL TOKEN 作为”锚点”检测对齐,需保证每个延迟点的等待时间>一个消隐区间
6 B板透传:TX 时钟必须与 RX 恢复时钟同源,避免引入跨时钟域问题
7 热插拔复位:包含 pll_5x 失锁的复位信号,必须进入 async reset sensitivity list,防止时钟停振后寄存器冻结
8 RX 恢复计数器应使用始终稳定的时钟(200MHz),不应用可能停振的 rx_pix_clk
9 三通道独立对齐后,需 FIFO 做通道间时延补偿,再统一释放数据
10 IDELAY 搜索范围应覆盖 pll_5x 锁定后最大相位不确定性(约±270ps=54IDELAY步)
请登录后发表评论