Quick Start
- 准备环境:安装 Vivado 2024.2(或更高版本),确认板卡为 Xilinx Artix-7(如 XCTA100T)或 Kintex-7,并连接 HDMI 子板(如 ADV7511)。
- 获取源码:从成电国芯 FPGA 云课堂下载 HDMI 参考工程(含 TMDS 编码器、PLL 配置、时序约束)。
- 打开工程:在 Vivado 中打开
hdmi_demo.xpr,确认顶层模块为hdmi_top。 - 运行综合:点击 Run Synthesis,等待完成(约 2–5 分钟,取决于机器性能)。
- 添加时序约束:打开
hdmi_timing.xdc,确认已包含 TMDS 时钟周期约束(如 148.5 MHz 对应 1080p60)。 - 运行实现:点击 Run Implementation,观察时序报告(Timing Summary)中 WNS(最差负时序裕量)应为正值。
- 生成比特流:点击 Generate Bitstream,下载到 FPGA 板卡。
- 验证现象:连接 HDMI 显示器,应显示 1920×1080@60Hz 的测试彩条图案;若画面闪烁或黑屏,检查时钟与约束。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| FPGA 器件 | Xilinx Artix-7 XCTA100T-2CSG324C | 低成本、支持 TMDS 差分对;示例以 7 系列为准 | Kintex-7 / Spartan-7(需调整 PLL 参数) |
| EDA 版本 | Vivado 2024.2 | 提供原生 HDMI 时序约束模板;2026 年仍主流 | Vivado 2023.1 / ISE(不推荐,约束语法差异大) |
| 仿真器 | Vivado Simulator(XSIM) | 集成在 Vivado 中,无需额外安装 | ModelSim / Questa(需手动编译库) |
| 时钟源 | 板载 50 MHz 晶振 | 通过 PLL 倍频至 148.5 MHz(1080p60 像素时钟) | 外部差分时钟(如 100 MHz) |
| 复位 | 低电平有效全局复位(~rst_n) | 确保初始状态稳定 | 高电平复位(需反转逻辑) |
| HDMI 子板 | ADV7511(Analog Devices) | 支持 HDMI 1.4a,最高 1080p60 | SiI9134 / 自建 TMDS 输出(需更高速 IO) |
| 约束文件 | .xdc 格式 | 包含 TMDS 时钟周期、输入延迟、输出延迟约束 | SDC(Synopsys)格式(Vivado 兼容) |
| 接口依赖 | HDMI 连接线 + 1080p 显示器 | 用于上板验证 | 逻辑分析仪(仅调试) |
目标与验收标准
完成本工程后,应达成以下可量化指标:
- 功能点:输出 1920×1080@60Hz 彩条信号(红、绿、蓝、白四色交替),HDMI 显示器稳定显示无闪烁。
- 性能指标:像素时钟 148.5 MHz(±100 ppm),TMDS 差分对数据速率 1.485 Gbps(每通道)。
- 资源占用:LUT ≤ 800,FF ≤ 600,BRAM ≤ 2(以 Artix-7 为例)。
- Fmax:综合后时序报告显示 WNS ≥ 0 ns(最差负时序裕量非负),且无 setup/hold 违例。
- 波形特征:仿真中 TMDS 数据通道(如 red_out)在像素时钟沿对齐,无毛刺;上板后显示器无雪花或行场不同步。
实施步骤
1. 工程结构
推荐目录结构如下(以 Vivado 工程为例):
hdmi_demo/
├── hdmi_top.v # 顶层模块(实例化 PLL、TMDS 编码、输出缓冲)
├── tmds_encoder.v # TMDS 编码器(RGB 转 10 位串行)
├── pll_wrapper.v # PLL 配置(50 MHz → 148.5 MHz)
├── pattern_gen.v # 彩条生成模块
├── hdmi_timing.xdc # 时序约束文件
├── hdmi_top_tb.v # 仿真测试平台
└── vivado_project/ # Vivado 工程目录逐行说明
- 第 1 行:
hdmi_demo/为工程根目录,建议用 Git 管理。 - 第 2 行:
hdmi_top.v是顶层模块,负责连接所有子模块和 IO 引脚。 - 第 3 行:
tmds_encoder.v实现 TMDS 编码算法(8b/10b 编码),将 RGB 数据转换为 10 位串行流。 - 第 4 行:
pll_wrapper.v例化 Xilinx MMCM/PLL,将板载 50 MHz 倍频至 148.5 MHz 像素时钟和 742.5 MHz 串行时钟。 - 第 5 行:
pattern_gen.v生成测试彩条(红、绿、蓝、白),简化调试。 - 第 6 行:
hdmi_timing.xdc包含所有时序约束,是本文重点。 - 第 7 行:
hdmi_top_tb.v用于行为仿真,验证像素时钟和同步信号。 - 第 8 行:
vivado_project/由 Vivado 自动生成,无需手动创建。
2. 关键模块:TMDS 编码器
TMDS 编码器将 8 位 RGB 数据转换为 10 位串行流,并嵌入同步信号。以下为核心代码(简化版,仅演示红色通道):
module tmds_encoder (
input wire clk_pixel, // 148.5 MHz 像素时钟
input wire rst_n, // 低电平复位
input wire [7:0] red_in, // 8 位红色数据
input wire de, // 数据使能(高电平有效)
output reg [9:0] tmds_out // 10 位 TMDS 编码输出
);
// 内部信号
reg [3:0] ones_count;
wire [9:0] encoded;
// 实例化 8b/10b 编码核心(此处简化为直接映射)
assign encoded = de ? {red_in, 2'b00} : 10'b0000000000;
// 输出寄存器(降低扇出)
always @(posedge clk_pixel or negedge rst_n) begin
if (!rst_n)
tmds_out <= 10'd0;
else
tmds_out <= encoded;
end
endmodule逐行说明
- 第 1 行:定义模块
tmds_encoder,端口包括像素时钟、复位、8 位红色输入、数据使能以及 10 位 TMDS 输出。 - 第 2 行:
clk_pixel为 148.5 MHz 像素时钟,用于同步所有逻辑。 - 第 3 行:
rst_n为低电平有效复位,确保初始状态。 - 第 4 行:
red_in为 8 位红色数据输入,来自彩条生成模块。 - 第 5 行:
de为数据使能信号,高电平时表示有效像素数据。 - 第 6 行:
tmds_out为 10 位寄存器输出,驱动 TMDS 差分对。 - 第 8 行:声明内部信号
ones_count(4 位计数器,用于 DC 平衡,本例未使用)。 - 第 9 行:声明
encoded线网,用于暂存编码结果。 - 第 11 行:简化编码逻辑:若
de为高,将红色数据拼接两位 0 作为 10 位输出;否则输出全 0(对应消隐区)。 - 第 13 行:时序逻辑,在像素时钟上升沿或复位下降沿触发。
- 第 14 行:若复位有效,输出清零。
- 第 15–16 行:否则将
encoded赋值给tmds_out,完成寄存。 - 第 18 行:结束模块定义。
3. PLL 配置
PLL 用于将板载 50 MHz 时钟倍频至 148.5 MHz 像素时钟和 742.5 MHz 串行时钟(5 倍频)。在 Vivado 中通过 Clocking Wizard IP 核生成,关键参数如下:
| 参数 | 值 | 说明 |
|---|---|---|
| 输入时钟频率 | 50 MHz | 板载晶振 |
| 输出时钟 1 (clk_pixel) | 148.5 MHz | 像素时钟,用于 TMDS 编码和同步 |
| 输出时钟 2 (clk_serial) | 742.5 MHz | 串行时钟,用于 OSERDES 输出 |
| MMCM 倍频系数 | M = 8, D = 1, O0 = 2, O1 = 10 | 50 × 8 / 1 / 2 = 200? 实际需调整 |
注意:上表仅为示例,实际参数需根据器件手册计算。建议使用 Clocking Wizard 的“自动计算”功能,确保输出频率在 MMCM 允许范围内(如 Artix-7 的 VCO 范围为 600–1200 MHz)。
4. 时序约束(核心)
时序约束是 HDMI 接口设计成败的关键。以下为 hdmi_timing.xdc 的完整内容:
# 时钟约束
create_clock -name clk_pixel -period 6.734 [get_ports clk_pixel]
create_clock -name clk_serial -period 1.347 [get_ports clk_serial]
# 生成时钟约束(从 PLL 输出)
create_generated_clock -name gen_clk_pixel -source [get_pins pll_inst/CLKIN1] -divide_by 1 -multiply_by 1 [get_pins pll_inst/CLKOUT0]
create_generated_clock -name gen_clk_serial -source [get_pins pll_inst/CLKIN1] -divide_by 1 -multiply_by 1 [get_pins pll_inst/CLKOUT1]
# 输入延迟约束(假设外部数据在时钟上升沿后 0.5 ns 到达)
set_input_delay -clock [get_clocks clk_pixel] -min -add_delay 0.5 [get_ports red_in]
set_input_delay -clock [get_clocks clk_pixel] -max -add_delay 1.0 [get_ports red_in]
# 输出延迟约束(TMDS 输出到 HDMI 连接器)
set_output_delay -clock [get_clocks clk_serial] -min -add_delay 0.2 [get_ports tmds_out_p]
set_output_delay -clock [get_clocks clk_serial] -max -add_delay 0.8 [get_ports tmds_out_p]
# 伪路径约束(跨时钟域)
set_false_path -from [get_clocks clk_pixel] -to [get_clocks clk_serial]逐行说明
- 第 1 行:注释,说明本节为时钟约束。
- 第 2 行:为像素时钟端口创建主时钟,周期 6.734 ns(对应 148.5 MHz)。
- 第 3 行:为串行时钟端口创建主时钟,周期 1.347 ns(对应 742.5 MHz)。
- 第 5 行:注释,说明生成时钟约束。
- 第 6 行:从 PLL 输出引脚创建生成时钟
gen_clk_pixel,源为 PLL 输入时钟。 - 第 7 行:类似地,创建串行时钟的生成时钟。
- 第 9 行:注释,说明输入延迟约束。
- 第 10 行:设置输入延迟最小值 0.5 ns(数据相对于时钟上升沿的到达时间)。
- 第 11 行:设置输入延迟最大值 1.0 ns。
- 第 13 行:注释,说明输出延迟约束。
- 第 14 行:设置输出延迟最小值 0.2 ns(数据输出到外部器件的建立时间要求)。
- 第 15 行:设置输出延迟最大值 0.8 ns。
- 第 17 行:注释,说明伪路径约束。
- 第 18 行:将像素时钟域到串行时钟域的路径设为伪路径,避免工具分析不必要的跨时钟域路径。
5. 仿真验证
编写测试平台 hdmi_top_tb.v,验证像素时钟、同步信号和 TMDS 输出波形。关键检查点:
- 像素时钟频率是否为 148.5 MHz(周期 6.734 ns)。
- 行同步(hsync)和场同步(vsync)脉冲宽度是否符合 1080p60 标准(hsync 44 像素时钟,vsync 5 行)。
- TMDS 输出在数据使能(de)为高时,编码值是否与输入 RGB 对应。
验证结果
上板验证后,预期结果如下:
- HDMI 显示器显示稳定的彩条图案(红、绿、蓝、白交替),无闪烁或雪花。
- Vivado 时序报告显示 WNS ≥ 0 ns,无 setup/hold 违例。
- 资源占用:LUT ≤ 800,FF ≤ 600,BRAM ≤ 2。
排障指南
| 现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 显示器无信号 | PLL 未锁定或时钟频率错误 | 检查 PLL 锁定信号(locked);用示波器测量 clk_pixel 频率 |
| 画面闪烁或雪花 | 时序约束不足或输出延迟不匹配 | 检查 WNS;调整输出延迟约束值;确保 TMDS 差分对布线等长 |
| 颜色错误 | TMDS 编码逻辑错误或数据位序颠倒 | 仿真检查 encoded 值;确认 RGB 通道映射正确 |
| 行场不同步 | 同步信号时序错误 | 检查 hsync/vsync 脉冲宽度和极性;对照 VESA 标准 |
扩展建议
- 支持更高分辨率:将像素时钟提升至 297 MHz(4K@30Hz),需更换更高性能 FPGA(如 Kintex-7)并调整 PLL 和约束。
- 音频嵌入:在 TMDS 数据岛周期插入音频数据包,需增加音频时钟和 I2S 接口。
- 动态彩条:修改 pattern_gen.v 实现滚动或渐变彩条,增加调试灵活性。
参考资源
- VESA 标准:VESA Monitor Timing Standard (Version 1.0, 2024)
- Xilinx UG472:7 Series FPGAs Clocking Resources
- Xilinx UG903:Vivado Design Suite User Guide: Using Constraints
- ADV7511 数据手册:Analog Devices ADV7511: HDMI Transmitter
附录:常见问题
- Q: Vivado 报错“No clocks defined”:检查 .xdc 文件中 create_clock 语法是否正确,确保时钟端口名称与顶层模块一致。
- Q: 综合后 WNS 为负值:尝试降低时钟频率(如 74.25 MHz 对应 720p),或优化代码逻辑(减少组合逻辑层级)。
- Q: 显示器显示“不支持模式”:确认 EDID 读取正确,或使用 HDMI 分析仪检查时序参数。





