ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Xilinx VTC实战:视频时序检测与生成的FPGA要点解析

Xilinx VTC实战:视频时序检测与生成的FPGA要点解析 做视频接口的工程师十个里有八个被“画面不出来”折腾过。我印象最深的一次是HDMI输入源非要接一个很冷门的隔行分辨率自己写的行场计数器读回来一直对不上折腾了一个下午没结果后来索性换思路直接用Xilinx的Video Timing ControllerVTC来抓时序。结果发现这个IP比我原先以为的要有用得多而且坑也比文档里写得多得多。这篇是Xilinx Video IP系列里关于Video Timing Controller的实战解析重点放在“时序检测”和“时序生成”这两个核心能力上。VTC这东西只要做视频输入、输出、处理链路的人迟早都会碰到很多项目里它藏在VDMA、Video In/Out这些IP后面看起来不起眼但实际上承担着“视频心跳”的角色。我会结合自己在HDMI采集、MIPI接口和PCIe视频传递场景里的实际调试经历把VTC的原理、寄存器配置、在线调试方法和常见坑一次说透适合正在做视频相关FPGA工程、想在项目里把VTC用得明明白白的人。1. VTC不只是一堆计数器它在视频链路中的真实角色1.1 从一次HDMI输入失步说起当时我们做的板卡接收一个第三方HDMI源的输出分辨率是一个非标准的1280x102460Hz变体源端给出来的信号经常在切换输入时出现短暂的失步。我一开始写了一个简单的行场计数器模块思路很直接检测VSYNC和HSYNC的极性然后用像素时钟数有效区的像素数和行数。刚开始在仿真里跑得挺好的可一上板遇到真实信号问题接踵而至有些源端的HSYNC宽度不规范有的VSYNC脉冲位置和标准时序差了几个像素还有的输入信号在切换分辨率时会先发几帧“怪帧”再稳定下来。我自己写的计数器模块对这些异常完全没有处理能力一旦时序不标准读回来的数值就乱套。后来我把VTC接进去让它工作在检测模式然后通过AXI4-Lite接口实时读回检测到的H Active、H Blank、V Active这些状态字段问题一下子清楚了——VTC把实际输入时序的每个参数都量化得清清楚楚我能看到源端切换时具体是哪一段时序参数突变再针对性地去让上游做重同步而不是毫无头绪地猜。这个经历让我意识到VTC的核心价值不只是“计数”而是“把模拟世界里的行场信号变成软件可读、可判断的数据”。它像一个视频时序的质检员自己写的计数器看起来也能数但真要应对各种不规范的工业级信号VTC的检测能力比自研模块可靠得多。1.2 检测、生成两个角色以及和Video IP家族的分工VTC有两种工作模式一个是检测另一个是生成。实际上一个带AXI4-Lite接口的VTC实例通常可以同时支持这两种能力通过寄存器切换或者同时使用。检测模式下视频源的行场信号接入VTC的视频接口VTC内部会对VSYNC/HSYNC/DE和像素时钟进行测量把有效宽度、消隐宽度、同步脉冲宽度、后沿宽度以及各类极性的配置状态全部量化成寄存器值。软件通过AXI总线读这些值就能知道输入源是1080p60还是720p50甚至是某个非标准格式。更实用的是VTC可以产生检测中断比如在检测到帧起始信号时向处理器发一个事件这个机制在实现帧同步、软同步、或者让处理器知道“新的视频帧已经来了”时非常有用。生成模式则完全反过来它按照你配置的时序参数对外产生一套标准的视频时序信号。这个信号可以是给下游显示接口用的行场同步和DE也可以是给Sensor/Encoder用的驱动时序。有时候VTC生成的是一组纯时序信号像素数据由另外的逻辑填充两者配合起来就是一条完整的视频输出链路。VTC在Video IP家族里的分工要搞清楚。Video In to AXI4-Stream这个IP管的是把带同步信号的总线视频数据转成AXI4-Stream流VDMA管的是像素数据的搬运和缓存Video Out则把AXI4-Stream流恢复成带时序的信号。这些IP都不直接去计算“现在这一帧该从哪个像素开始显示”也不去测量“输入信号到底是多少行多少列”。VTC干的就是这个活——它不搬运像素只管理时序的度量与生成。可以粗略理解成乐队里的节拍器乐手们负责演奏出声音节拍器负责让所有人知道现在到哪一小节的哪一拍。2. 拆开VTC的“心跳”检测与生成背后的状态机逻辑2.1 计数器式状态机怎么做到精确输出VTC生成模式的内部逻辑本质上是一条基于像素时钟的计数器链。我习惯把它理解成电子表有一个“行计数器”以像素时钟为节拍从0一直数到H_Total-1每个像素时钟加1当行计数器走完一整行后帧计数器加1行计数器清零重新开始。帧计数器从0走到V_Total-1之后一帧结束归零重新开始。用一段简化的Verilog伪代码来表达就是这个感觉always (posedge vtc_clk) begin if (!v_rst) begin h_cnt 0; v_cnt 0; end else if (h_cnt h_total - 1) begin h_cnt 0; v_cnt (v_cnt v_total - 1) ? 0 : v_cnt 1; end else begin h_cnt h_cnt 1; end end你以为VTC内部就是这样一个计数器吗不只是它在计数器的基础上还叠加了几个关键逻辑一是把H Active、H Blank、H Sync、H Back Porch这些参数映射到计数器的不同区间在对应的区间内输出高或低电平二是极性控制逻辑不管内部统一采用什么极性最后对外输出时可以根据配置反转三是边界处理逻辑检查计数器值是否等于某个配置值提前一个周期产生标志避免组合逻辑直接参与输出导致毛刺。检测模式的工作方式则恰好相反。检测模式不是自己产生计数器状态而是“观察”外部输入信号通过判断输入信号的电平跳变锁存像素时钟的计数值从而计算出每个时序宽度。比如输入DE信号为高时内部逻辑启动统计DE拉低后统计到的时钟个数就代表H Active的宽度。这个测量过程同样要考虑极性归一——外部输入VSYNC是低有效还是高有效VTC都需要先通过配置把极性统一然后才能准确测量。我自己在实际调试时发现极性配置一旦搞错检测出来的H Active会变成H Blank甚至数值完全无意义。2.2 参数怎么换算以1080p60为例的时序计算不管是配置VTC生成视频时序还是用VTC去检测输入时序前提是你得先建立一条从分辨率到行场参数的换算链。很多刚开始做视频的工程师容易忽略这一步直接凭印象填几个数字结果配置完输出完全不是那么回事。以最常见的1080p60为例它的标准时序参数如下参数名称数值H Active1920 像素H Front Porch88 像素H Sync44 像素H Back Porch148 像素H Total2200 像素V Active1080 行V Front Porch4 行V Sync5 行V Back Porch36 行V Total1125 行Pixel Clock148.5 MHzH Total是H Active、H Front Porch、H Sync、H Back Porch四段之和即192088441482200。V Total是108045361125。像素时钟的计算则是Pixel Clock H Total × V Total × Frame Rate 2200 × 1125 × 60 148.5 MHz反过来如果外部给了你一个像素时钟你想反查帧率那就是 Frame Rate Pixel Clock / (H Total × V Total)。这在用逻辑内部算时序参数时很常见如果要在FPGA内部对像素计数做除法使用Xilinx的除法器IP会比较方便。再比如720p60的参数H Active 1280、H Front Porch 110、H Sync 40、H Back Porch 220H Total是1650V Active 720、V Front Porch 20、V Sync 5、V Back Porch 20V Total是750Pixel Clock是74.25 MHz。这几个数字在配置VTC时经常用到可以直接当作常用值记住。VTC寄存器里填的不是H Total而是Active部分、Blank部分、Sync部分和Back Porch部分各自占多少所以你必须清楚每段宽度的含义别填反。2.3 为什么VTC能比自写逻辑更可靠可能有人会想VTC内部不也就是计数器吗我自己写几十行Verilog也能实现。但在实际系统里时序模块的可靠性并不只取决于计数器本身更取决于它对外部各种异常行为的容错能力。VTC的检测模式会做极性归一化和边界处理对于不完整行、异常帧起始、缺少SYNC脉冲等非标准情况VTC会把状态标记出来而不是让乱值直接污染下游逻辑。再说输出侧VTC生成的VSYNC/HSYNC/DE与像素时钟之间的相位关系是经过IP内部设计保证的对外部显示芯片或者编解码芯片来说这些信号要满足建立时间和保持时间的要求。自己写的计数器模块如果组合逻辑稍微复杂一点很容易出现DE翻转瞬间数据总线也在翻转导致显示端采样错位。这就是为什么在很多项目里哪怕逻辑资源紧张团队也倾向保留VTC因为它的时序裕量是经过验证的。3. 从寄存器把时序“配”出来AXI4-Lite配置实战3.1 寄存器空间的主要字段与配置流程VTC的配置接口在现行Vivado版本里一般是AXI4-Lite。不同IP版本、不同芯片家族的寄存器偏移可能略有差异但字段模型大同小异。实际操作时务必以你在IP Catalog里生成的实例对应的地址映射文档为准我下面讲的是通用配置思路。VTC寄存器主要分为几类控制寄存器、时序配置寄存器、检测结果状态寄存器、中断控制寄存器。控制寄存器最核心的是一个Enable/Disable位时序配置寄存器则包括H方向的HTIM0、HTIM1以及V方向的VTIM0到VTIM3。配置生成模式时你需要把2.2节算好的参数分别写入这些寄存器例如HTIM0的高16位写H Active值低16位写H Blank值HTIM1的高16位写H Sync值低16位写H Back Porch值VTIM寄存器组同理同时还有几个位专门控制极性包括VSYNC Polarity、HSYNC Polarity、V Blank Polarity、H Blank Polarity等。配置流程简单来说是先通过控制寄存器把Generator使能关闭让内部逻辑回到复位状态。按字段写入H方向和V方向的时序配置寄存器包括宽度和极性。重新打开Generator使能。观察输出的VSYNC/HSYNC/DE是否出现再用示波器或ILA测量确认时序正确。检测模式通常不需要你配置那么多时序参数你只需要把VTC的视频接口和待测信号连好然后通过检测状态寄存器读取测量结果再和预期值对应即可。3.2 动态切换格式的正确操作顺序VTC很实用的一个优势是它支持在运行中动态修改视频时序参数也就是软件随时可以把输出从1080p60切换成720p50。但这个操作有讲究我不能直接往寄存器里改写否则输出时序可能出现半帧“新老混搭”的畸变。我总结的正确顺序是先关闭Generator使能等待几拍让内部状态机回落到空闲然后把需要修改的HTIM和VTIM寄存器全部写一遍最后再打开使能。这里强调“等待几拍”是有意义的因为VTC内部寄存器跨时钟域同步需要时间如果你关使能后立即写寄存器新的值可能在同步过程中被内部逻辑采样到一半长度的毛刺状态。实际工程中我一般会在两步之间插入一个微秒级的延时或者至少等待软件读写总线已经完成刷新再执行下一步。反过来如果你的系统在做输入检测输入的分辨率随时可能切换VTC检测寄存器也会逐渐更新为新的测量值。这里最需要关注的是切换瞬间的中间值。比如某个源端从1080p切到720p中间的几帧时序可能是乱的VTC检测出的H Active可能会在1920附近慢慢过渡到1280附近也可能直接跳到某个不稳定的随机值。软件上要做的是对检测值做持续多帧确认连续读到同一个合理值之后才认为输入已经稳定再去切换下游的处理参数。我自己用的一个简单策略是连续读5次检测寄存器5次值都一致才认为格式稳定。3.3 一个最小配置Demo下面我用C代码风格写一个最简单的伪代码说明VTC配置1080p60输出时的寄存器操作顺序和字段放置方式。由于不同IP版本的偏移地址不一样这里用宏定义代替请以你的工程生成的地址表为准。#define VTC_ENABLE 0x00 #define VTC_HTIM0 0x08 #define VTC_HTIM1 0x0C #define VTC_VTIM0 0x10 #define VTC_VTIM1 0x14 #define VTC_VTIM2 0x18 #define VTC_VTIM3 0x1C #define BASE_ADDR 0x40010000UL static void vtc_write(uint32_t offset, uint32_t value) { *(volatile uint32_t *)(BASE_ADDR offset) value; } void vtc_set_1080p60_out(void) { // 1. 先关闭生成器避免写寄存器过程中输出毛刺 vtc_write(VTC_ENABLE, 0x00); // 2. H方向参数 // HTIM0: H Active 1920, H Blank H Total - H Active 280 vtc_write(VTC_HTIM0, (1920U 16) | 280U); // HTIM1: H Sync 44, H Back Porch 148 vtc_write(VTC_HTIM1, (44U 16) | 148U); // 3. V方向参数 // VTIM0: V Active 1080, V Blank V Total - V Active 45 vtc_write(VTC_VTIM0, (1080U 16) | 45U); // VTIM1: V Sync 5, V Back Porch 36 vtc_write(VTC_VTIM1, (5U 16) | 36U); // 4. 极性配置这里全部按高有效配置具体位段依据文档填写 vtc_write(VTC_VTIM2, 0x00); vtc_write(VTC_VTIM3, 0x00); // 5. 重新使能生成器 vtc_write(VTC_ENABLE, 0x01); }这段代码的字段排列逻辑足够说明问题了VTC配置不是直接填“行总数”“列总数”而是把每段时间拆开填这是它灵活性的来源也是容易出错的地方。实际使用中要根据VTC的Product Guide核对每个寄存器高16位/低16位对应的具体字段名特别是一些版本中H Blank代表的是“消隐总长”还是“Front PorchSyncBack Porch的总和”不同文档表述会有一点点差异但基本思路都是这样。4. ILA探针下的攻防时序检测的正确性与排查链路4.1 先用ILA确认输入信号再看寄存器结果配置VTC过程中遇到问题我最常用的调试武器就是Vivado里的ILA配合VIO做寄存器读写检查。调试检测模式最容易犯的错是直接看寄存器值来判断问题但其实软件读到的寄存器值只是结果你需要先通过ILA确认外部物理信号本身是否符合预期。具体做法是把VTC的输入时钟VTC_CLK设为ILA的采样时钟把外部输入的VSYNC、HSYNC、DE、以及VTC内部的几个关键状态信号加进探针列表触发条件设置在VSYNC的上升沿抓一整帧的波形。抓完之后先看行频和帧结构是否合理比如VSYNC周期是否正好是1125行、HSYNC周期是否正好是2200个像素时钟、DE高电平宽度是否为1920个时钟。把这些ILA测出来的值和VTC检测寄存器读回来的值对照一遍基本就能把问题定位在“输入物理信号异常”还是“VTC配置/读取异常”这两大类里。ILA发现信号根本没进来那就是硬件连接或FPGA引脚约束的问题ILA波形正常但VTC读回来是乱值那才是VTC侧配置或同步问题。我见过不少同事一上来就怀疑VTC有问题结果最后发现是外部芯片没有输出正确的行场信号白折腾半天。4.2 极性反了、检测漂移的完整排查链路有一个现象很有代表性VTC检测模式下读回来的H_ACTIVE不是1920而是240或者什么乱七八糟的值而且V_ACTIVE也不是1080。很多人第一反应是寄存器读写地址错了其实遇到这类问题完整排查链路应该是下面这个顺序。第一步确认输入信号的物理极性。很多Sensor和HDMI接收芯片的HSYNC/VSYNC默认是低有效而VTC内部的检测逻辑默认假设一个极性如果你没有在配置寄存器里把极性设对VTC会把高脉冲部分当作有效区测出来的H_ACTIVE就是错的。用ILA先看输入波形然后对照寄存器里的极性配置位确认双方对“有效”的定义一致。第二步确认采样时钟域。VTC检测时是用VTC_CLK去采外部输入的如果VTC_CLK和输入信号的像素时钟不是同一个频率甚至不是同源检测出来的数值一定等于真实宽度乘一个比例系数。比如输入是148.5MHz的像素时钟但VTC_CLK接入的是100MHz的参考时钟测出来的H_ACTIVE会变成1920×100/148.5≈1293而不会等于1920。这一步特别容易被忽略尤其在那些把VTC_CLK随便接到系统时钟上的设计中。第三步检查检测寄存器更新的时序。VTC检测寄存器并不是实时连续变化的它通常在一个检测窗口结束后锁存一组测量值。如果你刚上电就去读可能读到的是复位值或中间值。正确做法是等至少几帧输入信号稳定之后再去读取同时看状态寄存器里是否有检测完成标志。最后一步如果以上都没有问题做一个回环验证。让VTC先生成一组已知时序列然后把生成器的输出引脚直接通过内部逻辑反馈到自己的检测输入端检查读回来的值和配置值是否一致。这个回环验证法在排查“到底是生成方向错还是检测方向错”的场景里特别有效能一次性把两个方向的问题分开。4.3 检测结果与下游处理之间打拍和跨时钟域VTC检测到的是视频时钟域的时序状态而软件读取这些状态使用的是AXI时钟域内部IP会处理好异步接口。真正需要你自己注意的是把VTC的检测结果或生成信号用到下游用户逻辑时是否涉及跨时钟域。“always对reg打几拍管用”这句话在FPGA工程师圈子里经常被当成万金油但在视频时序场景里要谨慎对待。如果VTC的VSYNC输出和你的用户逻辑时钟确实是异步关系打两拍做同步是合理的但打拍只能解决亚稳态传播不能解决“信号本身在另一个时钟域持续一拍导致漏采”的问题。如果你想可靠地知道“VTC检测到帧起始了”更好的做法是用一个跨时钟域脉冲信号或者FIFO事件而不是简单打几拍去采。我在一个项目中就踩过这个坑VTC检测到输入源失步后想通过一个脉冲通知处理器启动重新同步结果只用两级寄存器同步遇到高像素时钟时偶尔会漏事件后来改成握手方式才稳定。5. 文档不会写但工程一定会踩的坑5.1 极性、边沿和Blank边界顺序错一个就是黑屏视频时序里最容易藏雷的就是极性配置。VTC配置寄存器里有一堆极性位包括VSYNC Polarity、HSYNC Polarity、V Blank Polarity、H Blank Polarity、V Active Polarity等。工程里常见的HDMI输入源VSYNC/HSYNC经常是低有效而很多FPGA内部的Video In IP默认又是按高有效来处理DE。如果极性配置不统一会出现信号链路上第一级模块能把DE识别出来但到了下一级模块就完全不认识的情况表现就是黑屏或花屏。我的习惯是用一张表把所有信号的极性在项目一开始就固定下来硬件设计、IP配置、FPGA约束三处保持一致信号HDMI典型极性常见Sensor极性内部处理建议极性VSYNC低有效高有效低有效HSYNC低有效高有效低有效DE高有效高有效高有效Pixel Clock上升沿采样上升沿采样上升沿采样Blank边界问题也值得一提。VTC配置里Active和Blank的分界很多文档用“H Total H Active H Blank”的方式描述所以在填字段时H Blank通常等于Front Porch、Sync、Back Porch三者之和而不是单纯指前肩或后肩。有的工程师误把H Blank填成H Front Porch当然配置完输出时序会乱。软件做寄存器表格时建议把“H_TOTAL”、“H_ACTIVE”、“H_BLANK”、“H_SYNC”、“H_BACK_PORCH”这些中间值全部计算并打印出来方便一眼看出填错没有。5.2 非标准输入与动态切换带来的隐患VTC的检测模式虽然能测量非标准时序但它的输出寄存器不会自动告诉你“这个格式是不是标准格式”它只负责报数值。所以当输入源出现非标准时序、或者切换格式时软件要做的是持续监控检测寄存器而不是只读一次就下手配置下游。我在一个多格式切换的项目里遇到过这样的情况输入源从1080p切到720p时中间会先发几帧只有行同步没有场同步的异常信号VTC检测寄存器在这期间的V_ACTIVE值忽大忽小。如果我们软件不判断就直接用这个值去重置VDMA就会导致图像撕裂甚至死锁。更隐蔽的是有些源端在切换格式时会改变VSYNC的极性。你按1080p的极性去等一个低脉冲结果源端先来了一串高脉冲VTC就不会触发帧边界检测。所以检测模式下软件最好同时读取“当前测量的时序值”和“检测到的极性/状态字段”两者都匹配才认为格式稳定。不要只关注数值大小极性状态的变化同样能反映链路是否进入新的工作状态。5.3 复位与使能拓扑为什么“看起来配了但没波形”配置了所有寄存器、使能位也打开了但输出就是没有波形。这个问题在我帮同事排查时遇到过好多次最后几乎都和复位拓扑有关。VTC的复位必须在他所依赖的视频时钟稳定之后才能释放。如果你的视频时钟来自外接的HDMI RX芯片或者MIPI D-PHY的恢复时钟那么上电后必须先让RX芯片锁定、时钟稳定再拉高VTC的复位释放信号否则VTC内部逻辑会在一个不稳定时钟上采样配置再正确也不会有输出。这在视频源来自PCIe、Aurora这类高速串行链路时尤其明显。GT的恢复时钟、复位、power_down时序如果处理不好VTC感知到的时钟可能是间歇性的配置就完全失效。一个工程项目中如果在逻辑里看到“复位已经释放了但VTC输出还是没有”先别急着改寄存器回去检查一下时钟锁定指示灯比如CPLL Locked、GT Tx/Rx Reset Done这类信号有没有拉高这一步能省去很多无意义的调试时间。和复位相关还有一个容易忽略的点当VTC和VDMA或者其他视频处理IP在同一套复位拓扑下时VTC的生成器使能和VDMA的帧同步启动顺序要仔细设计。先让VTC输出稳定时序再让VDMA开始搬运不然下游模块会在VTC产生第一个不完整的同步周期时就开始采样第一帧就会错位。我会在逻辑里用一个“视频时序稳定计数器”VTC使能后连续数到一帧完整长度再释放下游模块的软复位。6. 如果不想用VTC自研时序模块的对比与取舍6.1 自研方案的优点与代价很多团队在有经验的工程师主导下会倾向于自己写一个视频时序生成和检测模块而不是直接调用VTC。原因很实在VTC作为一个通用IP为了覆盖各种场景内部逻辑和寄存器比实际需求多得多对于固定分辨率的项目自研计数器模块可能只用到几百个LUT和FF而调用VTC后还要额外占用AXI总线资源、中断资源有时还会让软件驱动复杂化。资源在这类设计里通常不是问题但“可控感”对很多团队来说是实实在在的吸引力。自研方案的代价体现在两个地方。一是异常处理能力。VTC对非标准输入、极性漂移、缺失同步信号等场景有较完善的容错设计而这些逻辑如果自研你可能需要花好几个迭代版本才能慢慢补全。二是和软件系统的交互。VTC把所有测量结果和状态暴露成标准寄存器软件工程师不需要懂FPGA内部状态机直接读寄存器就行自研模块如果要提供类似能力你得自己设计寄存器地址映射、中断控制逻辑还要写文档工程量并不小。6.2 结合项目背景的选型建议我做了下面这个对比表方便你在项目立项时快速判断对比维度Xilinx VTC自研时序模块配置寄存器现成AXI4-Lite接口软件操作规范需要自己设计和定义寄存器异常输入处理对非标准时序、极性变化有较强容错完全取决于个人经验和代码质量运行时切换格式支持通过寄存器动态切换需要额外设计状态切换逻辑资源占用相对较多但通常可忽略可以做到非常精简验证工作量使用厂商经过验证的逻辑需要自己做完整的仿真和板级验证调试手段寄存器标准、文档齐全方便定位只能看波形状态需要自己判断授权和版本依赖受IP版本、芯片型号限制可移植性强我的个人建议是如果你的项目需要支持多种输入格式、需要处理器频繁参与参数配置和动态切换那就直接用VTC把精力省下来放在上层业务上如果你的设计固定处理某一种分辨率的视频流而且团队对FPGA内部逻辑完全掌控那自研计数器完全可行只要记得把异常保护逻辑写进去。还有一点值得提及在板卡健康管理上VTC检测到的行场错误状态可以和XADC采集到的温度、电压数据一起上报形成一个整板的状态监控。我在一个视频采集卡上就是这么做的VTC检测到输入信号异常时软件不仅记录视频状态还会同时读取XADC的温度和电压值判断是否因为电源不稳导致接收芯片性能下降。有了这些数据很多莫名其妙的问题都能从整板维度找到关联。对于PCIe、MIPI这些衍生项目VTC的存在也会让链路调试方便很多。比如MIPI CSI-2接口接收到的视频数据经过字节解包后行场信号通常是在逻辑内部恢复出来的虚拟时序你无法用示波器直接看这个时候VTC的检测模式反而成了唯一的“信号观测手段”通过读回检测寄存器就能确认链路是否恢复了正确的时序。再比如用PCIe传输视频流时VTC生成的帧起始脉冲可以作为用户逻辑打时间戳的基准让数据包带上精确的帧序号。这些都是VTC在“不算像素搬运”之外的衍生价值。最后分享一个我保留到现在的调试习惯调任何视频链路先别急着配置VTC生成输出而是先让VTC进入检测模式去看一个你确定已知的输入时序。哪怕是一个用VIO随便拉出来的低速时钟只要你能把检测读回来的值和预期值对得上说明总线读写、极性配置、时钟连接都是通的然后再切到生成模式去配置真正想要的输出格式。这个“先回环检测再开放生成”的顺序帮我排掉过好几个“看起来是VTC问题其实是我Source端格式没配对”的雷。如果你也在集成VTC希望这篇总结能帮你少走一段弯路。
返回列表