最近在做8路HDMI输入的视频拼接墙项目,每路信号源是不同摄像头的1080P60输出,现在用异步FIFO做跨时钟域缓冲,但拼接边缘还是偶尔出现撕裂和错位。查了几天资料,有人说要用帧同步器统一时钟域,有人说要在DDR3里做帧缓存再加读侧仲裁。想请教下有实际项目经验的大佬,多路视频同步到底怎么设计才稳定?帧同步器的具体实现思路是什么?
2026年了,FPGA工程师做视频拼接墙,多路HDMI输入不同步导致画面撕裂,除了加FIFO还有哪些同步方案?
5 个回答

先说结论:异步FIFO只是解决了跨时钟域的数据搬运,它管不了帧边界对齐。你遇到的撕裂本质是各路VSYNC相位差在毫秒级漂移,FIFO再深也会被慢慢填满或掏空。工程上常见做法是两级同步:帧同步用主源VSYNC做基准,产生一个统一的帧脉冲,各路在DDR3里缓存整帧,等这个脉冲来了再一起读;像素同步则是把所有源都搬到同一个像素时钟域,比如用PLL把各路TMDS时钟倍频到同一频率,再在写侧做相位补偿。一个容易踩的坑是:别只看VSYNC,还要核对各路HSYNC和DE的有效像素数,有些摄像头输出带消隐区长度不一致,即使帧率一样,像素总数也可能差几十个。建议你先抓各路源的实际时序波形,确认帧率偏差在千分之一以内,再写帧同步状态机。如果偏差大,就得考虑丢帧或重复帧策略,否则画面会周期性卡顿。另外,如果预算允许,可以看看专用视频同步芯片,比纯逻辑省事很多。你现在的DDR3带宽余量大概有多少?读侧仲裁如果做得不好,带宽不够也会导致偶发撕裂。

我做过类似的项目,给你一条主线思路,按这个顺序排查基本能定位问题。第一步,先别急着改逻辑,把8路HDMI的VSYNC抓到示波器上看,连续抓几十秒,记录每路帧脉冲的相对位置。你会发现两件事:各路帧率不是精确的60Hz,可能59.94、60.00、60.02都有;各路VSYNC之间的相位差会缓慢漂移,这是摄像头晶振误差导致的。撕裂就是漂移累积到超过FIFO深度时发生的。所以核心不是加大FIFO,而是要让读侧节奏跟着各路写入的长期平均速率走。具体做法:每路写DDR3时打上帧序号,读侧仲裁器以主源帧脉冲为基准,但允许从源在前后各留一定裕量,比如主源帧到来后,等待最多2ms,如果某从源帧还没写完,就跳过这一帧(丢帧)或者重复上一帧(插帧)。这个策略比硬同步更实用,因为物理上没法让8个晶振完全一致。第二步,像素同步:把各路RGB数据先写入各自的异步FIFO,FIFO读侧统一用一个高精度PLL生成的像素时钟,这个时钟频率取各路像素率的最大公约数附近,然后读侧对每路做行缓冲对齐。注意1080P60的像素率是148.5MHz,但有些源是148.35MHz(59.94),差0.1%看起来不大,但在拼接墙上一分钟会累积好几行错位。所以像素同步必须配合行计数器校准,每检测到DE下降沿就对行号做一次修正。最后说帧同步器,其实就是一个状态机:IDLE等待主源VSYNC,然后依次触发各路读DDR3,读完后进入HOLD等待下一帧。难点在HOLD期间如果某路DDR3写入还没完成,要么等要么丢。我建议你先把各路帧率偏差测出来,如果偏差在±0.05%以内,用丢帧策略就够稳定;如果偏差更大,就得考虑用外部VCXO做时钟驯服。你现在的源是固定摄像头还是可能换设备?这个影响很大。

FIFO只是缓冲,不是同步。你要做的是帧同步器:主源VSYNC触发所有路一起读DDR3,读侧统一时钟。先测各路帧率偏差,大于0.1%就得丢帧或插帧,否则FIFO再深也会溢出。别迷信专用芯片,自己写状态机没那么难。你DDR3带宽够吗?8路1080P60读写加起来要3.5GB/s以上。

先假设你已经确认过各路源的时序参数了,如果没有,建议第一步先做这个,不然后面全是猜。8 路 HDMI 来自不同摄像头,晶振都是独立 27MHz 或 74.25MHz,频率偏差和相位漂移是物理必然,不是逻辑 bug。所以你要解决的不是「让它们同步」,而是「让读侧容忍不同步」。加 FIFO 只是把问题从时钟域搬到帧域,真正要做的是在 DDR3 里缓存整帧,然后以主源 VSYNC 为基准生成统一读脉冲。具体做法:每路写 DDR3 时带上帧序号和时间戳,读侧仲裁器等到主源帧脉冲后,再等一个可配置的窗口,比如 2ms,窗口内如果某路该帧还没写完就跳过(丢帧),如果写完就正常读。这个窗口就是你的容差范围,窗口越大越不容易撕裂,但延迟越大。像素同步是另一层,把所有源搬到同一个像素时钟域,比如统一用 148.5MHz,写侧做相位补偿,读侧只认这个时钟,这样像素不会错位。一个常见误区是只盯 VSYNC 不看 DE,有些摄像头消隐区长度不一样,帧率相同但有效像素数差几十个,拼接边缘就会斜切。你现在的撕裂如果是周期性出现的,大概率是帧率偏差累积导致 FIFO 溢出或下溢,而不是像素时钟不对。建议先抓各路 VSYNC 和 DE 的波形,用计数器统计 1000 帧的周期,算出每路实际帧率,偏差大于 0.1% 就必须上丢帧/插帧策略。另外 DDR3 带宽要算清楚,8 路 1080P60 读写加起来大概 3.5GB/s 以上,如果带宽不够,读侧仲裁再合理也会卡顿。你说的加 FIFO 方案不是不能用,但 FIFO 深度按最大相位漂移量来设计,8 路 60Hz 下大概要缓存 2 到 3 帧,成本不低,而且治标不治本。想问下你现在 DDR3 用的什么型号,带宽余量有多少?

我做过类似的8路拼接项目,第一版也是FIFO加得特别深,结果撕裂照样出。后来把各路VSYNC抓到示波器上连续看了几分钟,才明白问题根本不在FIFO深度,而在各路帧率不是精确的60Hz,59.94、60.01、60.03都有,相位差会慢慢漂移,FIFO再深也会被慢慢填满或掏空。你现在的撕裂大概率就是漂移累积到FIFO边界后的表现。我的做法是分两级处理:帧同步用主源VSYNC做基准,各路先把整帧写进DDR3,每帧打个帧序号和时间戳,读侧仲裁器等主源帧脉冲来了之后,再等一个可配置窗口,比如2ms,窗口内某路该帧写完了就读,没写完就丢这一帧,避免撕裂。像素同步则是把各路TMDS时钟通过PLL统一到同一个像素时钟域,比如148.5MHz,写侧做相位补偿。有个容易忽略的坑:别只看VSYNC,还要核对各路HSYNC和DE的有效像素数,有些摄像头消隐区长度不一样,即使帧率相同,像素总数也可能差几十个,这会让拼接边缘出现亚像素级错位。建议你先抓各路源的实际时序波形,确认帧率偏差在千分之一以内,再写帧同步状态机。如果偏差大,就得考虑丢帧或重复帧策略,否则画面会周期性卡顿。另外,DDR3带宽要算清楚,8路1080P60读写加起来大概3.5GB/s以上,带宽不够的话帧缓存方案也白搭。你现在的源端时序参数确认过了吗?各路帧率偏差实测是多少?
发表回答
登录后可在本页底部提交回答