ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

FPGA HDMI环路输出实战:从TMDS解串到视频显示

FPGA HDMI环路输出实战:从TMDS解串到视频显示 很多用FPGA做图像处理的朋友都有过类似的尴尬流水灯跑得飞起串口收发也没问题但一碰到视频数据就发怵——HDMI信号进来是一对差分线出来的却是一堆时序复杂的像素偏偏图像处理的所有价值都要从这一步开始。黑金的这个HDMI视频输入与环路输出实验恰恰是用来打通这条路的起手式让FPGA把外部视频源发来的HDMI数据接收进来再通过另一个HDMI口原样送出去全程不做任何图像处理。听起来简单但这一收一发之间涉及TMDS解码、通道对齐、EDID管理、时钟恢复、跨时钟域处理几乎把嵌入式视频系统的核心环节都过了一遍。这篇文章我想围绕这个实验把HDMI视频输入和环路输出背后的原理、板级设计要点、代码框架和调试经验完整拆开讲一遍。无论你是刚接触FPGA的新手还是准备用FPGA做视频采集、图像处理的老手只要需要面对HDMI输入这个环节这篇都适合你对照参考。1. 为什么建议先啃HDMI输入这块硬骨头很多教程把HDMI输入当成进阶内容一上来就讲图像处理算法。我个人的观点恰恰相反视频输入才是最容易劝退、也最值得先攻克的关口。环路输出实验恰好让你在还没写任何复杂算法之前就把这条最难的链路验证通。1.1 环路输出到底在做什么环路输出英文常叫Loop-through或Video Pass-through指的是视频信号进入设备后不经过处理、直接再输出到下一级设备的过程。在FPGA实验里做这个事核心不是让画面从A口进再从B口出而是要你在FPGA内部把HDMI的串行差分信号完整解析成并行像素数据再把这些像素数据重新编码成HDMI信号发出去。信号流看起来像这样HDMI源电脑、播放器 - FPGA开发板的HDMI输入座 - FPGA内部解串与解析 - FPGA内部重新串化 - HDMI输出座 - 显示器这里有个重点环路输出不是把HDMI座的引脚直接飞线连到另一个HDMI座。那样根本不算实验而且模拟电路层面的信号质量也无法保证。FPGA必须真实地完成一次信号的分解再重组。这个实验最大的价值是什么我概括为三点验证硬件链路从开发板上的HDMI座子、保护电路、电平转换到FPGA的高速IO引脚整条物理通路是否有问题。验证接收通路FPGA有没有能力恢复出正确的像素时钟能不能把串行数据解出正确的RGB像素。验证发送通路重新编码后的TMDS信号能不能让显示器正常出图。只要这三件事都成立后面你做任何图像处理都相当于在一条已经验证无误的流水线上加模块。1.2 为什么不用现成的视频采集芯片这里有必要聊一个方案选型问题因为很多同学会问市面上有ADV7611、SIL9022这类HDMI接收芯片直接把HDMI转成并行RGB或者BT.1120信号FPGA那边做起来简单多了为什么教程还要用FPGA直接解HDMI两种方案各有取舍。专用接收芯片方案的优点非常明显芯片内部已经完成了HDMI物理层的接收、通道对齐、EDID管理输出的是并行像素信号FPGA不用碰高速串行逻辑。缺点也明显你学到的是怎么接一颗芯片而不是HDMI信号到底怎么解出来的一旦遇到信号不稳定、分辨率不识别的问题手里没有排查工具只能靠猜。而且这类芯片价格不低一颗ADV7611的价格比很多入门级FPGA芯片还贵。直接用FPGA高速IO解串方案的优点是你被迫把HDMI协议吃透知道TMDS怎么编码、通道怎么对齐、时钟怎么恢复、EDID怎么响应。这些知识换个场景照样用得上比如做一个MIPI摄像头接口、接一块LVDS屏幕套路是相通的。代价是刚开始调试时比较痛苦因为要同时面对模拟信号质量、FPGA原语配置、初始化时序多个变量。黑金这个实验走的就是后一条路线让你直接面对协议本身。别被FPGA基础这几个字误导了这个实验可以说是模拟信号、高速数字电路和逻辑设计三者的交叉点值得花时间慢慢啃。2. 底层信号链从TMDS差分线到像素数据要把环路输出做好第一步不是写代码而是理解HDMI信号在物理层长什么样。这段不搞清楚后面调黑屏的时候会非常痛苦。2.1 TMDS编码和四个差分通道HDMI接口一共用到四对差分信号线其中三对是数据通道Data Channel 0、1、2一对是时钟通道Clock Channel。数据通道采用TMDS编码Transition Minimized Differential Signaling中文叫最小化传输差分信号。TMDS这个名字很容易让人误解成普通的差分信号但它的核心其实是编码每个像素的8bit颜色数据会经过一套特殊的编码算法变成10bit的数据再串行发送。编码的目的有两个一是把串行数据流的跳变次数控制在合理范围减少电磁干扰二是把时钟信息“嵌入”到数据流中方便接收端用同一个参考时钟去采样。正因为每8bit数据编码成10bitHDMI串行速率就直接和像素时钟挂钩像素时钟多少MHz每对差分线上的串行速率就是像素时钟x10。以最常用的1080P60Hz为例分辨率像素时钟每通道串行速率总数据率720P60Hz74.25MHz742.5Mbps2.2275Gbps1080P60Hz148.5MHz1.485Gbps4.455Gbps4K30Hz297MHz2.97Gbps8.91Gbps时钟通道传输的不是像素时钟本身而是像素时钟x10的串行时钟。接收端拿到这个时钟之后再用它去采样三对数据通道上的串行比特流。这意味着HDMI本质上是一种源同步接口发送端把数据和时钟一并送过来接收端不需要像恢复PCIE那样的无参考时钟CDR恢复时钟相对容易一些。但注意容易只是相对的还是有很多细节会坑人。24bit色深的RGB信号三个通道每个负责8bit编码后每通道每像素发10bit。像素时钟所对应的一个时钟周期内三对数据线上其实各发出了10bit数据。这就是为什么FPGA接收HDMI需要做1:10解串——把一根线上的高速串行数据变成10bit的并行数据。2.2 在FPGA里把串行数据拉回并行世界7系列FPGA接收HDMI信号经典的架构是用SelectIO原语直接接收而不是用GTX高速收发器。原因很简单HDMI的串行速率对GTX来说是低速的1080P才1.485GbpsGTX浪费而且GTX做BANK电压匹配和引脚约束也更麻烦。用IO口加原语的方式更灵活成本也低。接收通路的搭建一般分三步。第一步把差分时钟转成单端再接MMCM/PLL。时钟通道进来的是1.485GHz的差分时钟经过IBUFDS转成单端信号。这个频率已经超出MMCM直接输入范围所以通常要用MMCM的输入分频功能把频率先降下来。常用的做法是把串行时钟直接分频成像素时钟。比如148.5MHzx101.485GHzMMCM配置成输入1.485GHz输出148.5MHz分频比就是10。第二步每个数据通道做1:10解串。这里用到IDELAYE2和ISERDESE2。IDELAYE2用来对进来的串行数据做延迟微调让采样点落在眼图中央ISERDESE2完成10bit解串。因为HDMI有3个数据通道所以需要3组这样的模块。每组解串出来的10bit数据其中8bit是有效像素数据另外2bit来自编码冗余部分。第三步通道对齐。三对数据通道各自独立解串出来的10bit数据的字节边界不一定对齐。打个比方同一时刻三个通道分别解出了bit位错位的10bit数需要找到参考位置把它们挪齐。HDMI协议规定消隐区会周期性发送特定的对齐控制字符最常见的是ABA字符序列。接收端通过检测这个特征字符配合ISERDESE2里的Bitslip功能逐bit调整数据边界直到三个通道的字符边界统一。这一步没做好画面就是花屏或者直接没显示。我在调试时见过最多的问题就是把ISERDESE2的DATA_RATE改成DDR解出来的bit顺序对了但字节边界始终对不上最后发现是IDELAYE2的延迟量不够导致采样点落在跳变沿上。这个后面调试部分再展开。2.3 行场同步与DE有效区间解串完成之后FPGA里出现的不再是比特流而是标准的视频数据流。注意HDMI协议里行场同步信号并不单独占用引脚而是在数据通道的消隐期间通过控制字符传输接收端解出来之后会恢复成独立的信号。视频数据流里三个关键信号是DEData Enable高电平表示当前像素是有效像素低电平表示处于消隐期。HSYNC行同步指示每一行的开始位置。VSYNC场同步指示每一帧的开始位置。DE信号尤其重要因为后续做图像处理或者驱动LCD屏都靠它来判断当前输出的像素是不是有效数据。环路输出实验的输出端也复用这套信号体系DE和同步信号转换成了TMDS编码内的控制信号再传给显示器形式变了但信息没变。从这里开始HDMI从高速串行物理层问题变成了时序逻辑问题。后面的环路输出其实就是在像素时钟域里搬运DE、HSYNC、VSYNC和RGB数据。3. 硬件与初始化EDID和HPD是画面能出的前提很多人在FPGA逻辑上花了一堆功夫结果没画面最后发现根本不是逻辑问题而是硬件初始化没做好。HDMI输入比HDMI输出多了一个麻烦的地方作为显示器的一端你得先给视频源一个回应它才愿意出信号。3.1 开发板上的HDMI输入电路布局先看看开发板上HDMI输入这一路通常有哪些器件。黑金系列开发板的设计大同小异基本可以抽象成这样的链路HDMI输入座 - ESD静电保护器件 - TMDS电平转换/直连FPGA - EDID存储器EEPROM - 5V检测与HPD控制 - FPGAHDMI座子上除了四对TMDS差分线还有几个容易被忽略的引脚5V电源、HPD热插拔检测、DDC通道I2C总线也就是SDA和SCL、CEC消费电子控制。其中5V是视频源电脑显卡、播放器那边送过来的用来给接收端的EDID等电路供电。这套电路里有个设计细节值得留意HDMI源的5V输出能力很有限一般标准规定要能供50mA电流但不同显卡实际能力差异很大。如果板子上的EEPROM、LDO、电平转换全从这个5V取电很可能把源端的5V拉垮。所以很多开发板会用一个三极管或者负载开关让5V只负责检测信号存在真正给EDID EEPROM供电的电流被限定得很小。如果你自己画板子这个电源设计要特别注意不能贪功能把功耗撑太高。3.2 用I2C返回EDID让显卡认这个显示器视频源插入HDMI之后并不会马上发送视频信号。显卡会先通过DDC通道本质是I2C总线去读取接收端设备的EDIDExtended Display Identification Data扩展显示标识数据。EDID是一段标准化的数据长度通常为128字节里面存放着显示器/接收端支持的视频格式列表、厂商信息、物理尺寸、色深等。显卡读到这段数据后才知道要以什么分辨率、什么刷新率、什么色深输出信号。在这个实验里EDID有两条实现路径。一条是板子上直接焊接一颗EEPROM出厂时已经烧录好一份标准1080P EDID数据FPGA不需要参与只要保证硬件连接正常就行。另一条是FPGA自己用IO模拟I2C从设备动态响应显卡的EDID读取请求。后者的好处是灵活可以在运行中修改EDID数据也就是动态改变系统支持的分辨率列表。黑金的实验例程里通常既有板载EEPROM方案也有FPGA模拟EDID的参考设计。如果你用的是FPGA模拟EDID有几个细节要留意。I2C的地址固定在0x50。显卡读取EDID会先发一个地址0x50的写操作指定要读取的偏移地址然后紧跟一个读操作从0x50开始连续读数据。FPGA模拟这个流程要把1024字节块有些EDID扩展到256字节或更多完整地存下来并能响应。每读一段还要做checksum校验比如基础EDID块要求128字节的和模256为0。如果checksum不对显卡会拒绝使用这份EDID直接不输出信号。我见过有人把EDID数据里的分辨率描述符改错刷新率字段和像素时钟不匹配结果显卡只能输出一个640x480的低分辨率兼容模式环路输出画面虽然出来了但模糊得没法看。EDID表里的DTDDetailed Timing Descriptor每个字节都是严格定义的改之前一定要对着规范核对。3.3 热插拔检测HPD的处理HPDHot Plug Detect是一条从接收端到源端的电平信号线作用就是告诉视频源我这里已经接好了设备你可以开始读EDID并发信号了。典型的上电时序是这样的视频源插入后HDMI座的5V引脚给接收端供电。接收端检测到5V存在延时一段时间通常至少100ms等待各种电源稳定。接收端把HPD引脚拉高。视频源检测到HPD拉高认为设备就绪开始通过DDC读取EDID。EDID读取成功后视频源开始输出视频信号。如果FPGA里没做HPD的拉高逻辑或者引脚约束到错误的位置最常见的现象就是HDMI源那边明明检测到了设备但一直不出画面或者过几秒又断开。检测5V那根线时要注意HDMI座子的5V是外部源提供的电平是5V而FPGA的IO通常不是5V容忍所以必须经过分压或者电平转换后再接到FPGA引脚否则会有烧毁风险。4. 环路输出一帧画面怎么不加缓存地原样走一遍硬件链路和初始化搞清楚之后才轮到真正的FPGA逻辑。环路输出实验的代码结构其实不复杂但麻雀虽小五脏俱全。4.1 顶层架构环路输出的顶层模块可以分成三部分接收物理层、核心逻辑层、发送物理层。接收物理层做前面说的一系列事情IBUFDS接收差分时钟和差分数据、MMCM恢复像素时钟、ISERDESE2解串、IDELAYE2对齐逻辑恢复出并行像素数据和同步信号。核心逻辑层在环路输出实验里最简单就是一组寄存器打拍把DE、HSYNC、VSYNC、RGB数据同步到输出时钟域不做任何算法处理。发送物理层则是接收物理层的逆过程把并行像素数据编码成TMDS格式经过OSERDESE2做10:1串化再通过OBUFDS转成差分信号输出。顶层例化关系大致是这样module hdmi_loopthrough_top ( input wire hdmi_clk_p, // HDMI输入时钟通道 input wire hdmi_clk_n, input wire [2:0] hdmi_data_p, // HDMI输入数据通道 input wire [2:0] hdmi_data_n, output wire hdmi_out_clk_p, // HDMI输出时钟通道 output wire hdmi_out_clk_n, output wire [2:0] hdmi_out_data_p, // HDMI输出数据通道 output wire [2:0] hdmi_out_data_n, inout wire iic_sda, // DDC通道 inout wire iic_scl, input wire hdmi_5v_detect, // 5V检测 output wire hdmi_hpd // 热插拔检测 ); wire clk_pixel; wire clk_pixel_x5; wire [23:0] rx_rgb; wire rx_de, rx_hsync, rx_vsync; // 接收物理层恢复像素时钟并解串 hdmi_rx_phy u_rx_phy ( .clk_p (hdmi_clk_p), .clk_n (hdmi_clk_n), .data_p (hdmi_data_p), .data_n (hdmi_data_n), .pixel_clk (clk_pixel), .de (rx_de), .hsync (rx_hsync), .vsync (rx_vsync), .rgb (rx_rgb) ); // 核心逻辑层本实验为直通仅打拍同步 reg [23:0] tx_rgb_reg; reg tx_de_reg, tx_hsync_reg, tx_vsync_reg; always (posedge clk_pixel) begin tx_rgb_reg rx_rgb; tx_de_reg rx_de; tx_hsync_reg rx_hsync; tx_vsync_reg rx_vsync; end // 发送物理层串化差分输出 hdmi_tx_phy u_tx_phy ( .clk_p (hdmi_out_clk_p), .clk_n (hdmi_out_clk_n), .data_p (hdmi_out_data_p), .data_n (hdmi_out_data_n), .pixel_clk (clk_pixel), .de (tx_de_reg), .hsync (tx_hsync_reg), .vsync (tx_vsync_reg), .rgb (tx_rgb_reg) ); endmodule实际工程里hdmi_rx_phy和hdmi_tx_phy内部才是真正复杂的部分上面这个代码只是为了展示数据流关系。接收物理层内部除了解串还包含通道对齐状态机发送物理层内部包含TMDS编码器把8bit像素数据编码成10bit。4.2 为什么环路输出不该直接画一根直连线刚看完上面的代码可能有人觉得绕既然输出就是输入为什么不能直接把解串后的信号给串化器为什么要加寄存器打拍直接连过去的做法在仿真器里完全能跑通上板就未必了。核心原因是时序余量。HDMI接收恢复出来的像素时钟来自源端显卡的TMDS时钟通道经过传输线、板级器件、FPGA内部布线之后时钟本身的抖动和偏斜已经不可避免。发送端的串化器对时钟质量敏感如果直接拿这个抖动偏大的时钟去驱动发送逻辑高速输出信号的时序会恶化到显示器无法锁定。所以工程上通常做两件事一是所有并行信号在进入发送物理层之前必须用寄存器重新寄存一次消除组合逻辑路径上的毛刺二是对恢复出来的像素时钟做一次净化。常见的净化方式是通过MMCM/PLL重新生成比如配置成输入148.5MHz输出也是148.5MHz让PLL内部环路滤波器滤掉一部分高频抖动。MMCM输出时钟再同时驱动核心逻辑和发送物理层。这就带来一个前面提到过的问题如果输入分辨率会变化比如把视频源从1080P切到720P像素时钟也从148.5MHz跳到74.25MHz。接收物理层里恢复时钟的MMCM如果还是锁定时钟源频率那输出就不对了。所以真正的自适应分辨率方案里接收端和发送端必须共用一套时钟管理并且把MMCM配置成锁定范围覆盖常见分辨率的模式。这也是这个实验从基础走向进阶的一个重要拐点。4.3 跨时钟域和数据流方向环路输出实验的时钟关系相对简单只有一个源端的像素时钟域。真正要注意的是数据流方向不能搞反。接收物理层输出的DE、RGB等信号和恢复像素时钟同步发送物理层也直接使用同一个时钟所以不存在普通意义上的跨时钟域问题。但如果你按照我代码里的方式加了打拍寄存器就相当于在接收端和发送端之间插入了一级同步。这里有个小细节打拍寄存器和发送物理层的编码器都工作在同一个clk_pixel下但逻辑深度不同路径延迟也不同。做时序约束时要给这条数据路径留足余量否则版图布局一变就可能出现偶发花屏。分辨率固定时几乎不存在亚稳态问题因为信号本来就是同一个时钟域产生的。一旦改成自适应分辨率方案接收端恢复时钟可能在运行中切换这时就会有真正的跨时钟域问题处理不当会出现画面撕裂甚至FPGA内部逻辑复位。所以基础实验里最简单可靠的做法就是保证使用的数据都是来自同一个时钟域环路不需要加法但要做得干净。5. 实测踩坑一次从黑屏到出图的全过程记录这部分是我认为整个实验最有价值的内容。纸上谈兵再多不如看一次真实的排查链路。下面是一个很典型的案例现象就是完全黑屏两个屏幕都没画面。5.1 现象输入插上没反应当时拿一台笔记本通过HDMI线接到开发板开发板的环路输出再接一台显示器。笔记本识别到了设备但显示器没有任何画面开发板上也没有任何视频相关指示灯亮。开发板本身的FPGA程序已经跑起来串口打印也正常说明FPGA逻辑大概率是活的问题集中在HDMI通路。这个阶段先不要打开Vivado看仿真先做最基础的硬件检查。第一摸一下HDMI座子的金属外壳看有没有异常发热。发热不正常往往意味着电平转换芯片或ESD保护器件有短路。第二确认笔记本是否真的在输出信号。用没有环路功能的纯HDMI输入端显示器试一下笔记本确认笔记本的HDMI口本身没问题。第三用万用表量HDMI座子上5V引脚有没有电压。如果电脑那边检测到显示器的话5V应该已经送出来。实测发现5V是正常的说明物理连接没问题。接下来才进入FPGA调试。这里必须先想清楚一个逻辑在处理视频数据之前要先确认板卡是否成功欺骗了笔记本让笔记本认为这里有一台显示器。如果EDID链路有问题笔记本根本不会输出视频信号后面所有接收逻辑都白搭。5.2 分析思路先从电平和时钟查起我把ILA集成逻辑分析仪挂到I2C接口上触发条件设置为检测到SDA下降沿。跑了几分钟ILA里没有任何I2C波形。这说明笔记本根本没在尝试读取EDID。再查HPD信号。用I/O口把HPD的状态引出来发现一直是低电平。这就奇怪了因为5V都检测到了按照时序HPD应该被拉高。查代码发现HPD拉高逻辑里我误用一个内部复位信号去控制复位释放之后又把HPD拉低了。改掉这个逻辑把HPD改成检测到5V后延时100ms拉高并且保持再跑ILA里立刻出现I2C通信波形。这一轮踩坑说明什么HPD是很多初学者最容易忽略的细节。逻辑本身不复杂但一旦状态机里有个复位分支没有处理好就会让源端完全拒绝工作。EDID读取正常之后显示器仍然黑屏。这次把ILA挂到恢复出来的像素时钟上。我设计了一个计数器统计像素时钟的周期数用串口打出结果理论上1秒内应该数到148.5Mx某个数量级。实测打出的是74.25M的一半不到说明MMCM分频配置错了。检查MMCM配置发现我把分频系数换算成了像素时钟x2的中间频率实际上应该按串行时钟先分频到148.5MHz。改正确之后像素时钟稳定在148.5MHz计数器数值符合预期但画面仍然没有出来——这次是花屏满屏雪花。5.3 最终根因和解法花屏和黑屏是两个层面的问题。黑屏往往表示没信号或者信号完全无法锁定花屏则是信号已经进来了一部分只是数据没有正确对齐。这个案例里三个通道解串后的数据字节边界不一致导致RGB分量错位。检查发现IDELAYE2的延迟值设得太小采样点落在了串行数据的边沿附近恢复出来的数据不稳定。解决方法是做眼图扫描。在ILA里用固定延迟值连续采样观察解串出来的数据是否有连续错误逐步调整IDELAYE2的tap值找到一个所有通道都能稳定采样的窗口。不同通道因为布线长度差异需要的延迟值往往不一样所以要每个通道单独调。调通之后我还做过一个验证把3个通道的RGB数据故意接错重排制造了一次人为花屏然后顺着数据流一级一级查很快就定位到问题。这个习惯值得推荐环路输出实验出问题时先确认数据路径上的每一级信号是否符合预期而不是一上来看算法。另外提一个容易被忽略的点换HDMI线材也会引起显示异常。我调试HDMI环路时有一根看似挺粗的线材在1080P下一直有雪花换成短线后问题消失。HDMI线材质量在低速情况下影响不明显到1.485Gbps这个速率劣质线的眼图已经严重变差。6. 从环路到算法一条可继续深入的路线环路输出跑通之后这个实验的真正价值才开始释放。因为你现在掌握了一条视频进-像素数据-视频出的完整通路接下来要做的就是在通路中间任何一个位置放进自己的逻辑。6.1 在环路里插入第一段处理最简单的尝试是做灰度转换。在核心逻辑层加一个组合逻辑模块把RGB转YUV再取Y分量或者直接用加权公式输出灰度值wire [23:0] gray_out; assign gray_out {gray8, gray8, gray8}; wire [7:0] gray8; assign gray8 (rx_rgb[23:16] * 8d77 rx_rgb[15:8] * 8d150 rx_rgb[7:0] * 8d29) 8;这段代码直接替换掉之前打拍的直通逻辑接上显示器画面立刻变成灰度。从这个点开始你已经在做FPGA图像处理了。下一步可以把灰度模块换成边缘检测Sobel算子、色彩变换、亮度调节甚至二值化。每个算法模块的输入输出都是那套DERGB信号接口统一替换起来非常顺畅。注意加图像处理模块后一个像素的时序从输入到输出不可避免地要多出几拍延迟需要按流水线级数拍平打拍延迟否则帧头会被截断出现图像错位的现象。6.2 后续可以扩展的方向环路输出打通后可以顺着几个方向深入第一加帧缓冲。在核心逻辑层挂一片DDR3/DDR4把输入帧写入内存输出端再从内存读出来。这样你就拿到了一个真正的视频处理平台可以实现画面冻结、帧率转换、图像缩放、字符叠加。这是很多工业视觉项目的雏形。第二换输入源。把HDMI输入换成摄像头接口比如OV5640 MIPI数据链路就变成了摄像头-预处理-显示。黑金的教程里有很多摄像头实验原理上和HDMI输入高度相似都是先做物理层解析再做像素处理。第三上Zynq平台。用ARM核处理上层协议FPGA只做数据搬运和实时处理。HDMI输入部分可以挂到PL侧当作一个视频前端PS侧通过AXI总线配置或读取图像数据。做视频采集设备方向的人早晚要走到这一步。第四换高速接口。HDMI吃透了之后你会发现MIPI、LVDS、DisplayPort这类接口都是同一种思路差分传输、编码对时、并串转换。把HDMI接收物理层改成MIPI CSI-2的物理层核心逻辑几乎可以复用。6.3 个人实操建议最后分享几点根据自己做FPGA视频项目的经验总结第一不要跳步。我见过不少人直接上手做HDMI算法的复杂工程遇到问题后连是输入链路还是算法链路的问题都分不清。先把环路输出跑通确立一个已知为正确的基线后面所有改动都是在基线上做增量。第二调试时一定要有可观测性。ILA打出来看波形是好习惯但ILA能抓到的深度有限长时间的观测要靠计数串口打印这种土办法。我在调试像素时钟时就是靠一个计数器1秒后把数值从串口打出来很快就能判断频率是否正确。第三不要迷信别人的代码。黑金的例程能跑通但理解不等于能复现。建议你认真读一遍hdmi_rx_phy里的ISERDESE2和IDELAYE2配置参数弄明白每一行是什么意思。这个读代码的过程比跑通实验本身更有价值。第四做时序约束的时候对HDMI相关时钟单独建约束文件把接收恢复时钟和发送像素时钟的设置分开。时序约束不做综合结果可能时好时坏排查起来很费力气。做视频相关的FPGA项目和做逻辑控制类项目感觉很不一样。逻辑控制只要功能对就行视频项目永远要绷着时序余量这根弦。环路输出实验跑通的那天说实话画面并没有让人惊艳但那种把高速信号踩在脚下的实感和点亮LED完全是两码事。希望这篇内容对正在啃HDMI的同学有帮助看完之后动手跑一遍实验遇到黑屏花屏别慌顺着链路一级一级查你也能调出稳定的画面。
返回列表