Vivado 中实现 LVDS 串行通信的实战指南:从原理到调试
为什么 LVDS 成了高速接口的首选?
在机器视觉、雷达信号处理、工业相机这些领域,动辄上百 Mbps 甚至 Gbps 的数据量,传统单端信号早就不堪重负。而 LVDS(Low-Voltage Differential Signaling)之所以能成为主流选择,靠的是它与生俱来的三项硬实力:
- 抗干扰能力强:差分结构天然抑制共模噪声,哪怕在电机旁边也能稳定工作。
- 功耗低:恒流源驱动,3.5mA 电流就能跑出 655 Mbps 以上的速率。
- 传输距离远:双绞线上传输几米不成问题,EMI 还小得惊人。
举个例子,一台 1080p@60fps 的 CMOS 相机,原始数据率轻松突破 1 Gbps。如果用并行 TTL 传输,不仅布线复杂、易受干扰,PCB 根本没法做。但换成 8 通道 LVDS,每路跑 125–150 Mbps,系统瞬间变得简洁可靠。
Xilinx 7 系列及以后的 FPGA,原生支持 LVDS 电平标准,无需外挂 PHY 芯片,直接通过 SelectIO 资源就能搞定。这也是为什么越来越多工程师把 LVDS 作为高速接口入门的第一课。
FPGA 里是怎么'看懂'LVDS 信号的?
很多人以为 LVDS 只是换个 IO 标准那么简单,其实不然。FPGA 内部有一套完整的差分信号处理链路,理解这套机制,是避免后续踩坑的前提。
差分输入:IBUFDS 是第一道门
外部 LVDS 信号进入 FPGA 的第一站,就是 IBUFDS —— 差分输入缓冲器。
IBUFDS u_ibuf (
.I(clk_p), // 正端
.IB(clk_n), // 负端
.O(clk_250m) // 单端输出
);
这个模块干了三件事:
- 接收一对差分电压(典型摆幅 350mV)
- 判定逻辑高低(>100mV 为 1,<-100mV 为 0)
- 输出标准 CMOS 电平供内部逻辑使用
关键点来了:你必须确保这对引脚位于支持 LVDS 的 Bank 内。比如 Artix-7 的 HR Bank 可以支持 LVDS_25 或 LVDS_33,但某些低电压 Bank 就不行。翻错手册,硬件就废了。
而且,要不要启用片内终端?可以通过参数控制:
IBUFDS #( .DIFF_TERM("TRUE") // 开启 100Ω片内端接 ) u_ibufds (...);
开启后,PCB 上就可以省掉外接的 100Ω电阻,适合短距离板内连接;但如果走线很长或需要驱动多个负载,建议还是外置终端更稳妥。
差分输出:OBUFDS 把数据送出去
反过来,你想把 FPGA 里的数据以 LVDS 格式发出去,就得用 OBUFDS。
OBUFDS #( .IOSTANDARD("LVDS_25") ) u_obuf (
.I(data_from_fpga),
.O(data_p),
.OB(data_n)
);
注意 .I 是单端输入,.O/.OB 自动生成差分对。这里 .IOSTANDARD 必须和 Bank 电压匹配——2.5V Bank 写 LVDS_25,3.3V Bank 写 LVDS_33,否则可能烧毁 IO。
Vivado 工程怎么搭才不翻车?
别小看工程结构,一个清晰的目录组织,能让你后期维护省下大把时间。
推荐这样布局:
lvds_camera_project/
├── src/
│ ├── top.v
│ ├── lvds_rx
│ └── frame_buffer_ctrl
├── constraint/
│ └── pin
├── ip/
│ └── clk_wiz_0
└── sim/
└── tb_lvds_rx

