跳到主要内容Vivado 中实现 LVDS 串行通信的设计流程 | 极客日志编程语言算法
Vivado 中实现 LVDS 串行通信的设计流程
在 Vivado 中实现 LVDS 串行通信的完整设计流程。内容涵盖 LVDS 技术优势、FPGA 内部差分信号处理机制(IBUFDS/OBUFDS)、工程搭建规范、引脚与时序约束编写方法。重点讲解了利用 MMCM 和 IDELAY2 进行时钟相位调整与微调,以及使用 ISERDESE2 实现高速串并转换的技术细节。此外,文章还提供了工业相机采集系统的实战案例,分析了电源去耦与跨时钟域处理的注意事项,并推荐使用 ILA 进行信号调试,总结了常见问题的解决方案及 PCB 布线最佳实践。
橘子海1 浏览 Vivado 中实现 LVDS 串行通信的设计流程
LVDS(Low-Voltage Differential Signaling)因其抗干扰能力强、功耗低、传输距离远等优势,成为机器视觉、雷达信号处理等领域的高速接口首选。Xilinx 7 系列及以后的 FPGA 原生支持 LVDS 电平标准,无需外挂 PHY 芯片。
为什么 LVDS 成了高速接口的首选?
在机器视觉、雷达信号处理、工业相机这些领域,动辄上百 Mbps 甚至 Gbps 的数据量,传统单端信号早就不堪重负。而 LVDS 之所以能成为主流选择,靠的是它与生俱来的三项硬实力:
抗干扰能力强:差分结构天然抑制共模噪声,哪怕在电机旁边也能稳定工作。功耗低:恒流源驱动,3.5mA 电流就能跑出 655 Mbps 以上的速率。传输距离远:双绞线上传输几米不成问题,EMI 还小得惊人。举个例子,一台 1080p@60fps 的 CMOS 相机,原始数据率轻松突破 1 Gbps。如果用并行 TTL 传输,不仅布线复杂、易受干扰,PCB 根本没法做。但换成 8 通道 LVDS,每路跑 125–150 Mbps,系统瞬间变得简洁可靠。
FPGA 里是怎么'看懂'LVDS 信号的?
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.v
│ └── frame_buffer_ctrl.v
├── constraint/
│ └── pin.xdc
├── ip/
│ └── clk_wiz_0.xci
└── sim/
└── tb_lvds_rx.v
新建工程时选"RTL Project",不要勾选"Do not specify sources",方便后续管理文件。
器件型号一定要准确填写,比如 xc7a200tfbg676-2,因为不同速度等级对应的时序特性不一样,综合工具会据此优化路径延迟。
引脚约束不是贴标签,而是定规则
很多初学者以为,只要把管脚连上就行。结果一进 Implementation 阶段,全是红色警告:"Unconstrained Pin"。
记住一句话:所有 LVDS 端口都必须有明确的电气标准和时序定义。
# === LVDS 输入时钟 ===
set_property PACKAGE_PIN AB12 [get_ports rx_clk_p]
set_property PACKAGE_PIN AB11 [get_ports rx_clk_n]
set_property IOSTANDARD LVDS_25 [get_ports rx_clk_p]
create_clock -name sensor_clk -period 8.000 [get_ports rx_clk_p]
# === LVDS 数据通道(8 位)===
set_property PACKAGE_PIN Y14 [get_ports rx_data_p[0]]
set_property PACKAGE_PIN Y13 [get_ports rx_data_n[0]]
set_property PACKAGE_PIN W14 [get_ports rx_data_p[1]]
set_property PACKAGE_PIN W13 [get_ports rx_data_n[1]]
# ... 其余通道类似
foreach p [get_ports rx_data_p[*]] {
set_property IOSTANDARD LVDS_25 $p
}
# === 输入延迟约束 ===
set_input_delay -clock sensor_clk -max 1.8 [get_ports rx_data_p[*]]
set_input_delay -clock sensor_clk -min 0.4 [get_ports rx_data_p[*]]
create_clock 告诉工具:这是我系统的主频来源。
set_input_delay 描述了数据相对于时钟的到达窗口。这个值不能乱填!得查传感器手册里的"Output Data Valid Window"参数。
如果你偷懒没加这些约束,Vivado 默认按最宽松的情况处理,最后生成的比特流很可能在实际硬件上跑飞。
高速采样靠什么?MMCM + IDELAY2 黄金组合
LVDS 常用于源同步传输,即随路携带时钟。这时候最大的挑战是:如何让 FPGA 内部时钟精准对齐外部数据的有效窗口?
用 MMCM 生成 90°相移时钟
假设输入数据速率是 125 Mbps,对应时钟周期 8 ns。如果我们用同相时钟去采样,刚好落在数据跳变沿附近,极易出错。
解决办法:用 MMCM 生成一个滞后 90°的时钟,在数据最稳定的中间点采样。
- 打开 IP Catalog → 搜索 Clocking Wizard
- 输入时钟:125 MHz(来自 IBUFDS)
- 输出两个时钟:
clk_out1: 125 MHz, 0° 相移(给主逻辑用)
clk_out2: 125 MHz, 90° 相移(专门用于 DDR 采样)
clk_wiz_0 u_clk_wiz (
.clk_in1(rx_clk_250m),
.reset(rst),
.clk_out1(sys_clk),
.clk_out2(sample_clk_90)
);
现在你有了一个'黄金采样时钟',大大提升建立保持余量。
还不够准?上 IDELAY2 微调!
即使有了 90°相移,由于 PCB 走线差异、器件温漂等因素,最佳采样点仍可能偏移几个百皮秒。
它能在 0~1.2ns 范围内以 78ps 步长调节输入信号的延迟,相当于给你一把显微镜级别的调焦旋钮。
IDELAY2 #(
.DELAY_SRC("IDATAIN"),
.SIGNAL_PATTERN("DATA"),
.CINVCTRL_SEL("FALSE"),
.HIGH_PERFORMANCE_MODE("TRUE")
) u_idelay (
.IDATAIN(data_raw),
.DATAOUT(data_delayed),
.CE(ce_inc),
.INC(inc),
.LD(ld),
.CLK(clk_200m),
.IOCLK0(ioclk)
);
- 上电复位后加载初始延时值
- 启动数据接收,观察误码情况
- 若错误多,则递增/递减延时,扫描整个窗口
- 找到误码最少的那个点,锁定为最优设置
你可以把这个过程想象成'自动对焦':不断微调,直到眼图完全睁开。
真正的杀手锏:ISERDES 实现高效串并转换
当你面对的是更高带宽需求,比如 Camera Link 或千兆视频流,单纯的 DDR 采样已经不够用了。这时就要祭出 Xilinx 的王牌模块——ISERDESE2。
它可以将高速串行数据(如 7:1 压缩)转换为本地时钟域下的并行信号,极大减轻逻辑负担。
ISERDESE2 #(
.DATA_RATE("DDR"),
.DATA_WIDTH(4),
.INTERFACE_TYPE("NETWORKING"),
.DYN_CLKDIV_INV_EN("FALSE"),
.DYN_CLK_INV_EN("FALSE"),
.NUM_CE(1),
.SERDES_MODE("MASTER")
) u_iser (
.D(rx_data_p), // 来自 IBUFDS 的信号
.CLK(clk_250m), // 高速采样时钟(250MHz)
.CLKB(~clk_250m), // 反向时钟
.CLKDIV(sample_clk_90),// 分频时钟(125MHz)
.RST(rst),
.SHIFTIN1(shiftin1),
.SHIFTIN2(shiftin2),
.Q4(Q) // 4 位并行输出
);
.CLK 是高速时钟(250MHz),负责每个边沿采样
.CLKDIV 是慢速时钟(125MHz),用来同步输出数据
- 当
DATA_WIDTH=4,意味着每 4 个高速周期输出一次 4 位数据
rx_data_p → IDELAY2 → IBUFDS → ISERDESE2 → 并行数据
这一整套流水线下来,哪怕面对复杂的嵌入式时钟协议,也能稳稳拿下。
实战案例:工业相机图像采集系统
- CMOS 传感器输出 8 位 LVDS 数据 + 1 位随路时钟
- FPGA 接收后缓存至 DDR3
- MicroBlaze 读取并通过 UDP 上传 PC 显示
[Sensor] ↓ (LVDS @ 125Mbps × 8bits)
[FPGA (Artix-7)] ↓ (AXI4 Stream)
[FIFO → DDR3 Controller] ↓ (DMA)
[MicroBlaze + LWIP] ↓ (Ethernet)
[Host PC]
我们曾在一个项目中遭遇严重误码,排查发现竟是因为忽略了 Bank 供电去耦。虽然功能正常,但在高频切换时产生地弹,导致采样失败。后来在每个 Bank 电源引脚旁补上 0.1μF 陶瓷电容,问题迎刃而解。
另一个常见问题是跨时钟域处理不当。LVDS 数据进来是源同步时钟域,而 DDR 写入是系统时钟域,两者频率略有偏差。如果不加异步 FIFO 缓冲,迟早溢出。
解决方案很简单:用 XPM_FIFO_ASYNC 打一层胶水逻辑,实现安全跨时钟传递。
调试秘籍:ILA 才是你的终极武器
强烈建议你在关键节点插入 ILA(Integrated Logic Analyzer)探针:
ila_0 u_ila (
.clk(clk_125m),
.probe0(rx_data_p),
.probe1(idelay_tap_value),
.probe2(iserdes_output),
.probe3(frame_valid)
);
然后跑起来,打开 Hardware Manager,实时查看:
- 原始 LVDS 信号质量
- IDELAY 调节过程
- ISERDES 输出是否连续
- 帧同步是否捕获成功
你会发现,很多你以为正确的设计,其实在信号层面早已扭曲变形。而 ILA 就像内窥镜,让你直视系统的'血液循环'。
最后划重点:那些年我们都踩过的坑
| 问题现象 | 根本原因 | 解决方案 |
|---|
| 数据乱码、误码率高 | 采样点未对齐 | 使用 MMCM+IDELAY2 联合调相 |
| Implementation 报 Timing Fail | 缺少 input delay 约束 | 补全 XDC 中的 set_input_delay |
| 引脚无反应 | IO 标准与 Bank 不匹配 | 查 UG475 确认电压兼容性 |
| 眼图闭合 | 差分走线不对等 | PCB 调整等长±10mil 以内 |
| 功耗异常 | 多个 LVDS Bank 同时切换 | 加强电源去耦,分散布局 |
- 差分走线坚持 3W 原则:线间距≥3 倍线宽,减少串扰
- 全程 100Ω阻抗控制:无论是走表层微带线还是内层带状线
- 避免跨分割平面布线:参考平面断裂会导致回流路径中断,引发振铃
掌握这些技能,你不只是会用 Vivado,而是真正掌握了高速接口的设计思维。而这,正是迈向高级 FPGA 工程师的关键一步。
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown 转 HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
- HTML 转 Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
- JSON 压缩
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online