LVDS 在 FPGA 里算不上什么新鲜技术,但每次真到板子跑起来的时候,总有人卡在“时钟怎么给”“差分对怎么分配”“为什么数据全是错的”这几个老问题上。易灵思(Efinix)的 Trion 和 Titanium 系列这两年在国产替代和低功耗场景里用得越来越多,尤其是 Trion T20、T120 以及 Titanium Ti60 这些型号,很多项目拿它做图像采集、屏驱动、高速数据转发。但易灵思的 LVDS 配置逻辑跟 Xilinx、Altera 那套不太一样,Interface Designer 这个工具虽然把很多底层约束自动化了,可一旦你搞不清楚它的工作边界,照样会掉进坑里。这篇内容就是把我自己在易灵思 FPGA 上折腾 LVDS 接口的完整过程拆开来讲,从硬件设计到 Interface Designer 配置,再到 Efinity 里的时序约束和实测调试,适合正在用易灵思做 LVDS 相关项目、或者准备从其他平台迁移过来的朋友参考。
1. 易灵思 LVDS 的硬件层逻辑与常见认知偏差
1.1 LVDS 在易灵思 FPGA 里的物理资源分布
易灵思 FPGA 的 LVDS 资源不是随便哪个 IO 都能用的。以 Trion T20 为例,它的 LVDS 收发器主要集中在特定的 Bank 里,而且每个 Bank 的参考时钟输入也有固定引脚。这一点跟 Xilinx 7 系列类似,但易灵思的文档里对这部分描述比较分散,很多人第一次看引脚分配表的时候容易忽略。
具体来说,易灵思的 LVDS 分为两类:真 LVDS(True LVDS)和仿真 LVDS(Emulated LVDS)。真 LVDS 用的是芯片内部专门的差分驱动器,支持更高的速率和更低的抖动;仿真 LVDS 则是用普通单端 IO 配合外部电阻网络来模拟差分信号,速率和信号质量都要打折扣。在 Interface Designer 里选接口类型的时候,如果你没注意这个区别,工具可能会默认给你分配仿真 LVDS,结果跑高速的时候眼图一塌糊涂。
我一般会先翻芯片的 Pinout 文档,把支持真 LVDS 的引脚对标记出来。Trion T20 的 LVDS 对通常分布在 Bank 0 和 Bank 2,每个 Bank 有独立的供电电压要求。这里有个细节:LVDS 的共模电压是 1.2V,但易灵思的 LVDS IO 供电可以配成 1.8V、2.5V 或 3.3V,具体取决于你选的 IO 标准。如果你外部接的是标准 LVDS 接收器,那 IO 电压要匹配好,否则共模电平对不上,接收端可能直接识别不到。
1.2 差分对的引脚分配规则与布线约束
差分对的引脚分配不是你想怎么连就怎么连的。易灵思的每个 LVDS 对都有固定的 P 端和 N 端,P 端通常是奇数引脚,N 端是偶数引脚,而且它们必须属于同一个 IO Bank。在 Efinity 的引脚约束文件(.pin)里,你只需要指定 P 端的位置,N 端会自动关联,但前提是你选的 P 端确实支持 LVDS 输出或输入。
这里有个我踩过的坑:有一次做 LVDS 输入,我随手选了一个看起来是差分对的引脚,结果 Interface Designer 报错说该引脚不支持 LVDS 接收。后来查手册才发现,易灵思的 LVDS 输入和输出支持的引脚集合不完全一样,有些引脚只能做输出,有些只能做输入,还有些双向都支持。这个信息在 Pinout 表格里有一列叫“LVDS IO Type”,一定要仔细看。
另外,差分对的走线在 PCB 上必须等长、紧耦合,阻抗控制在 100 欧姆。如果你用的是排线或者杜邦线做测试,那基本上跑不过 100MHz,信号完整性会差到让你怀疑人生。我建议至少用带屏蔽的差分线,或者直接画一块测试板,把差分对走在内层,参考平面完整。
1.3 时钟资源与 LVDS 的配合方式
LVDS 接口通常需要一个随路时钟或者外部参考时钟。易灵思的 PLL 和时钟网络对 LVDS 的支持有几种模式:一种是外部晶振直接进全局时钟引脚,然后通过 PLL 倍频给 LVDS 发送逻辑;另一种是 LVDS 接收时,从数据流里恢复时钟(CDR),但这个功能在易灵思的某些型号上需要额外的 IP 核支持。
对于大多数中低速应用(比如 7 寸屏的 RGB 转 LVDS),我一般用外部晶振给 PLL,PLL 输出两个时钟:一个给 LVDS 发送模块,一个给内部逻辑。这里要注意PLL 的输出时钟到 LVDS 发送器的路径必须走全局时钟网络,否则 skew 会很大,导致数据眼图不对称。在 Efinity 的时序约束里,你需要对 PLL 输出到 LVDS 的时钟做 create_clock 和 set_output_delay,具体参数后面会讲。
2. Interface Designer 配置 LVDS 的完整流程与参数取舍
2.1 新建 LVDS 接口时的模式选择
打开 Efinity 的 Interface Designer,新建一个接口,第一步就是选接口类型。这里你会看到 LVDS、SubLVDS、Mini-LVDS 等选项。对于普通的 LVDS 屏或者数据转发,选LVDS就行。然后要选方向:Transmitter(发送)、Receiver(接收)或者 Bidirectional(双向)。大多数场景下,发送和接收是分开配置的,因为它们的时序约束和引脚分配逻辑不一样。
选完方向后,工具会让你指定数据宽度和串化因子。易灵思的 LVDS 发送器支持 4:1、7:1、8:1 等串化比,接收器也类似。举个例子,如果你要驱动一个 7 寸 TFT 屏,RGB888 一共 24 位数据加上 HSYNC、VSYNC、DE,总共 27 位,那你可以用 4 对 LVDS 数据线加 1 对时钟线,每对数据线串化 7 位,这样 4×7=28 位,刚好够用。这个串化比的选择直接影响到你的参考时钟频率和内部逻辑的并行时钟频率。
注意:串化比越高,内部逻辑的时钟频率越低,但 LVDS 的比特率越高。你需要根据你的 PCB 走线和接收端的能力来权衡。一般 7:1 在 7 寸屏应用里很常见,比特率大概在 400-500Mbps 左右。
2.2 数据映射与位序调整
Interface Designer 里有一个很关键但容易被忽略的步骤:数据映射(Data Mapping)。工具会给你一个默认的位序,但默认的往往跟你的实际连接不对应。比如你从 FPGA 内部送出来的 28 位数据,哪几位对应第一对 LVDS 的 7 位,哪几位对应第二对,这个必须跟你的硬件连接和接收端定义一致。
我通常会在 Interface Designer 里手动调整位序,把 HSYNC、VSYNC、DE 这些控制信号放在固定的位置上,方便调试。如果你用的是现成的屏,屏的规格书里会有一个 LVDS 数据映射表,你照着那个表在工具里拖拽调整就行。调整完之后,工具会生成一个 Verilog 或 VHDL 的 wrapper,你在顶层例化这个 wrapper,把内部并行数据接进去。
这里有个小技巧:在 wrapper 外面加一级寄存器,把并行数据打一拍再送进 LVDS 发送器。这样做的好处是改善时序,尤其是当你的内部逻辑时钟和 LVDS 并行时钟不是同一个时钟域的时候,打一拍可以降低亚稳态风险。
2.3 参考时钟与 PLL 的联动配置
Interface Designer 配置 LVDS 的时候,会要求你指定参考时钟。这个参考时钟可以是外部晶振直接给的,也可以是 PLL 输出的。如果你选 PLL 输出,工具会自动帮你例化一个 PLL,但参数需要你自己填。这里的关键参数是VCO 频率和输出分频比。
以 Trion T20 为例,假设你的 LVDS 比特率是 490Mbps,串化比是 7:1,那么并行时钟频率就是 490/7=70MHz。PLL 的 VCO 需要在这个频率的整数倍上工作,比如 700MHz 或 1400MHz,然后通过分频得到 70MHz 和 LVDS 发送器需要的比特时钟。Efinity 的 PLL 配置界面里有一个“Calculate”按钮,你输入目标频率,它会自动算出一组参数,但有时候算出来的 VCO 频率不是最优的,抖动会偏大。我一般会手动选一个 VCO 在 800MHz-1200MHz 之间的方案,这个范围内 PLL 的相噪表现比较好。
提示:如果你用的是 Titanium 系列,PLL 的性能更强,VCO 范围更宽,可以支持更高的 LVDS 比特率。但 Ti60 的 LVDS 资源分布跟 Trion 不太一样,配置的时候要重新查手册。
3. Efinity 工程中的时序约束与引脚约束实战
3.1 引脚约束文件的编写要点
Efinity 的引脚约束文件格式比较简单,每行一个引脚,格式是set_pin_assignment {信号名} {LOCATION=引脚号; IOSTANDARD=LVDS;}。对于 LVDS 差分对,你只需要写 P 端的引脚号,N 端会自动分配。但这里有个细节:IOSTANDARD 要写 LVDS 还是 LVDS25,取决于你的 IO 供电电压。如果 Bank 电压是 2.5V,就写 LVDS25;如果是 1.8V,就写 LVDS18。写错了工具会报错,或者虽然不报错但实际电平不对。
另外,对于 LVDS 输入,你还需要在约束文件里加上set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to {信号名},因为 LVDS 输入在没有信号的时候是浮空的,加一个弱上拉可以防止输入引脚振荡。这个细节在易灵思的官方文档里没有特别强调,但我在实际调试中发现,不加这个约束的话,接收端在空闲时会有随机跳变,导致内部逻辑误触发。
3.2 时序约束的创建与验证
时序约束是 LVDS 调试里最容易出问题的环节。Efinity 的时序约束文件(.sdc)支持标准的 SDC 语法,但对于 LVDS 接口,你需要额外注意几点:
第一,输入时钟的约束。如果你的 LVDS 参考时钟是从外部晶振进来的,你要用create_clock定义它的周期和占空比。如果是 PLL 输出的,PLL 会自动生成时钟约束,你不需要重复定义。
第二,输出延迟约束。对于 LVDS 发送器,你需要用set_output_delay来告诉工具,数据从 FPGA 输出到接收端的延迟是多少。这个值取决于你的 PCB 走线长度和接收端的建立保持时间。一般我会先设一个保守值,比如 1ns,然后根据实测的眼图来调整。
第三,输入延迟约束。对于 LVDS 接收器,用set_input_delay来约束数据到达 FPGA 引脚的时间。这个值跟发送端的输出延迟和走线延迟有关。如果你不知道具体值,可以先设 0,然后通过时序报告来反推。
Efinity 的时序分析器会给出 setup 和 hold 的 slack。如果 slack 是负的,说明时序不满足,你需要调整 PLL 相位、增加流水线寄存器或者降低比特率。我一般会先把比特率降下来,确保功能正确,然后再逐步提高,观察时序余量的变化。
3.3 布局布线后的时序报告解读
跑完布局布线(Place & Route)之后,Efinity 会生成一个时序报告。这个报告里最关键的是LVDS 发送器/接收器相关的路径。你要重点看几个东西:
- 从内部逻辑到 LVDS 发送器的建立时间是否满足
- LVDS 接收器到内部逻辑的保持时间是否满足
- PLL 输出时钟到 LVDS 的 skew 是否在允许范围内
如果发现某条路径的 slack 特别差,你可以用set_max_delay或者set_min_delay来手动约束,但更好的办法是优化逻辑结构,比如把组合逻辑打散,插入寄存器。
注意:易灵思的时序报告里,LVDS 相关的路径有时候会被归类到“IO”或者“Clock”类别里,你需要仔细找。我一般会直接搜索信号名,定位到具体的路径。
4. 实测调试中遇到的典型问题与排查链路
4.1 数据全错但时钟正常的排查思路
这是最常见的问题:LVDS 时钟有输出,接收端也能锁定时钟,但数据全是乱的。遇到这种情况,我一般按以下顺序排查:
第一步,检查数据映射。回到 Interface Designer,确认位序跟接收端定义一致。我遇到过好几次,都是因为 HSYNC 和 VSYNC 的位置搞反了,导致图像完全错位。
第二步,检查串化比和时钟频率。用示波器或者逻辑分析仪测一下 LVDS 时钟的频率,看看是不是你预期的值。如果时钟频率对,但数据不对,那可能是串化比设错了。比如你设了 7:1,但实际数据是 8 位的,那就会多出一位或者少一位。
第三步,检查差分对的极性。LVDS 的 P 和 N 如果接反了,数据会取反。有些接收端可以自动纠正极性,但有些不行。你可以试着在约束文件里交换 P 和 N 的引脚号,看看数据是否恢复正常。
第四步,检查参考时钟的抖动。如果参考时钟抖动太大,LVDS 发送器的眼图会闭合,接收端采样错误。你可以用频谱仪测一下参考时钟的相噪,或者换一个质量更好的晶振试试。
4.2 眼图测试与信号完整性优化
眼图是判断 LVDS 信号质量最直观的工具。如果你有条件用高速示波器,可以直接在接收端测眼图。一个健康的 LVDS 眼图应该是张开得很大,交叉点清晰,抖动很小。如果眼图闭合,说明信号完整性有问题。
常见的信号完整性问题包括:
- 差分对不等长:导致 skew 过大,眼图交叉点偏移。一般要求等长误差在 5mil 以内。
- 阻抗不匹配:导致反射,眼图出现振铃。差分阻抗要控制在 100 欧姆±10%。
- 参考平面不完整:导致回流路径断裂,信号质量下降。差分对下方要有完整的 GND 平面。
- 终端电阻缺失:LVDS 接收端通常需要 100 欧姆的终端电阻。如果接收端内部没有,你需要在 PCB 上靠近接收端的地方加一个。
我在一次调试中遇到眼图完全闭合的情况,后来发现是差分对走线跨过了电源分割区,回流路径断了。把走线移到完整的 GND 平面上方之后,眼图立刻恢复正常。
4.3 多路 LVDS 同步与相位对齐
有些应用需要多路 LVDS 同步输出,比如双屏显示或者多通道数据采集。这时候相位对齐就很重要了。易灵思的 PLL 支持多路输出,每路可以独立调整相位。你可以用 PLL 的 phase shift 功能,把多路 LVDS 的时钟对齐到同一个相位上。
但这里有个坑:PLL 的相位调整精度有限,一般是 1/8 或 1/16 个 VCO 周期。如果你的比特率很高,这个精度可能不够。这时候你可以考虑用 IDELAY 或者 ODELAY 原语来微调延迟。易灵思的 Titanium 系列支持 IDELAY,Trion 系列好像没有,具体要查手册。
另外,多路 LVDS 的走线也要等长,否则即使时钟对齐了,数据到达接收端的时间也不一样。我一般会在 PCB 设计阶段就把多路 LVDS 的走线做等长处理,误差控制在 10mil 以内。
5. 从其他平台迁移到易灵思的注意事项
5.1 Xilinx 与易灵思 LVDS 配置的差异对比
如果你之前用的是 Xilinx 的 FPGA,迁移到易灵思的时候,有几个地方需要特别注意:
| 对比项 | Xilinx 7 系列 | 易灵思 Trion/Titanium |
|---|---|---|
| LVDS 配置工具 | Vivado 的 SelectIO IP | Efinity 的 Interface Designer |
| 差分对引脚分配 | 任意差分对,灵活度高 | 固定引脚对,需查手册 |
| 串化比 | 支持 4:1 到 10:1 | 支持 4:1、7:1、8:1 等 |
| 时序约束 | 标准 SDC,工具自动推导 | 需要手动写更多约束 |
| IDELAY 支持 | 全系列支持 | Titanium 支持,Trion 部分支持 |
从表里可以看出,易灵思的灵活性不如 Xilinx,但它的工具链更轻量,上手更快。如果你做的是中低速应用,易灵思完全够用;但如果你需要极高的灵活性和高速性能,可能还是要考虑 Xilinx 或者 Altera。
5.2 从 Altera 迁移时的引脚约束转换
Altera 的引脚约束用的是 QSF 文件,格式跟 Efinity 的 .pin 文件不一样。迁移的时候,你需要把 QSF 里的引脚分配逐条转换成 Efinity 的格式。这里有个技巧:先用脚本把 QSF 里的引脚号和信号名提取出来,然后批量生成 .pin 文件。这样可以避免手动输入出错。
另外,Altera 的 LVDS 配置里有一个“Deserialization Factor”的概念,跟易灵思的串化比是对应的,但取值范围可能不同。迁移的时候要重新计算时钟频率和 PLL 参数,不能直接照搬。
5.3 代码层面的可移植性设计
如果你希望你的 LVDS 代码能在多个平台之间移植,我建议把 LVDS 相关的逻辑封装成一个独立的模块,接口尽量标准化。比如定义一个lvds_tx模块,输入是并行数据和时钟,输出是差分信号。然后在不同平台下,用不同的 wrapper 来例化具体的原语。
这样做的好处是,当你从易灵思换到 Xilinx 的时候,只需要替换 wrapper,核心逻辑不用动。我在几个项目里都用了这种结构,迁移成本很低。
6. 几个容易被忽略的实操细节
6.1 复位信号的亚稳态处理
LVDS 接口的复位信号如果来自异步时钟域,很容易产生亚稳态。我一般会在复位路径上加两级同步器,确保复位信号在 LVDS 时钟域里稳定后再释放。这个细节在高速 LVDS 应用里尤其重要,因为亚稳态可能导致 LVDS 发送器输出错误的码流。
具体做法是:用一个双触发器同步器,把外部复位信号同步到 LVDS 并行时钟域,然后再送给 LVDS 发送模块。同步器的时钟用 LVDS 的并行时钟,而不是系统时钟。
6.2 温控与长期运行的稳定性
LVDS 发送器在高速工作时会发热,尤其是多路 LVDS 同时工作的时候。如果你的板子没有良好的散热设计,芯片温度升高会导致时序余量下降,甚至出现间歇性数据错误。我一般会在 PCB 上给 FPGA 加一个小散热片,或者在机箱里加一个风扇。
另外,长期运行的时候,建议定期监测 FPGA 的温度和 LVDS 的误码率。如果误码率突然升高,可能是温度过高导致的。易灵思的 FPGA 内部有温度传感器,你可以通过 JTAG 或者内部逻辑读取。
6.3 调试用的测试图案生成
在调试 LVDS 的时候,我习惯在 FPGA 内部生成一个测试图案,比如彩条或者棋盘格,然后通过 LVDS 发送出去。这样在接收端可以直观地看到图像是否正确。如果彩条的颜色不对,说明数据映射有问题;如果图像有噪点,说明信号完整性有问题。
生成测试图案的逻辑很简单:用一个计数器生成行号和列号,然后根据行号和列号查表输出 RGB 值。这个逻辑可以放在 LVDS 发送模块的前面,通过一个多路选择器切换正常数据和测试图案。
6.4 电源噪声对 LVDS 的影响
LVDS 的共模电压是 1.2V,差模电压是 350mV,这个电压摆幅很小,所以对电源噪声很敏感。如果 FPGA 的 IO 电源纹波太大,LVDS 的差分信号上会叠加噪声,导致眼图闭合。我一般会在 IO 电源引脚旁边放多个去耦电容,包括 100nF 和 10uF,并且尽量靠近引脚。
另外,LVDS 的参考时钟电源也要干净。如果 PLL 的电源噪声大,输出时钟的抖动会增加,直接影响 LVDS 的比特率。我通常会给 PLL 的电源单独加一个 LDO,跟数字电源分开。
6.5 关于 Ti60 的 LVDS 特殊配置
Ti60 是易灵思 Titanium 系列里比较热门的一款,它的 LVDS 资源比 Trion 更丰富,但配置方式也有一些不同。Ti60 支持更高的比特率,最高可以到 1.5Gbps 左右,而且支持自适应均衡和 CDR。如果你用 Ti60 做 LVDS 接收,可以在 Interface Designer 里开启均衡功能,补偿 PCB 走线的损耗。
但要注意,Ti60 的 LVDS 引脚分布跟 Trion 不一样,有些引脚是复用的,配置成 LVDS 之后就不能再做普通 IO 用了。所以在引脚规划阶段就要确定好哪些引脚给 LVDS,哪些给其他功能。
7. 个人经验总结与后续扩展方向
LVDS 这个东西,说难不难,说简单也不简单。硬件设计占一半,FPGA 配置占一半。我在易灵思平台上做 LVDS 项目的时候,最大的体会就是:一定要先查手册确认引脚支持情况,再用 Interface Designer 配置,最后用示波器验证信号质量。这三步缺一不可。
另外,Efinity 的版本更新比较快,不同版本之间 Interface Designer 的界面和参数可能略有差异。我建议锁定一个稳定的版本,不要频繁升级。如果遇到工具报错,先去易灵思的官方论坛搜一下,很多时候是已知问题,有 workaround。
后续如果要做更高速的 LVDS 应用,比如 MIPI 转 LVDS 或者多通道数据采集,可以考虑用 Titanium 系列,它的 SerDes 性能更强,支持更复杂的协议。但相应的,调试难度也会增加,需要更专业的测试设备,比如高速示波器和误码仪。
最后再分享一个小技巧:在 Efinity 里跑完布局布线之后,可以用 Timing Analyzer 的“Report Path”功能,把 LVDS 相关的路径单独导出来分析。这样比看整个时序报告要高效得多,尤其是当你的工程很大、路径很多的时候。