ARTICLE DETAIL

资讯详情

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

FPGA接Sony IMX421:基于Kintex-7 GTX的SLVS-EC接口设计与调试

FPGA接Sony IMX421:基于Kintex-7 GTX的SLVS-EC接口设计与调试 IMX421这颗Sensor的SLVS-EC接口第一次接触时很容易被它的协议名吓住。当时项目要求用Xilinx Kintex-7接IMX421我第一反应是找Sony官方有没有现成的RX IP第二反应是翻Vivado里有没有MIPI CSI-2硬核翻了半天发现两条路都走不通——最后只能老老实实用K7自带的GTX高速收发器去解SLVS-EC。说实话这个结论一开始有点反直觉。K7是前几年发布的FPGASLVS-EC是Sony主推的传感器接口怎么看都不像“标配组合”。但做下来才发现SLVS-EC本质上就是一种嵌入式时钟的高速串行差分链路和PCIe、Aurora这类SerDes在物理层是同一套玩法而Kintex-7恰好把GTX收发器做到了足够成熟的水平。真正麻烦的不是能不能收而是怎么把传感器输出电平、GTX输入灵敏度和协议对齐这三件事同时做对。下面这些内容是我从项目里整理出来的完整思路从电气匹配讲到GTX配置再讲到上板调试顺序适合手里有IMX421或者类似Sony全局快门传感器、打算用7系列FPGA接SLVS-EC的工程师直接“抄作业”。1. SLVS-EC到底是个什么信号先摸清接口底细再动手我第一次看IMX421的数据手册时先入为主地以为SLVS-EC和MIPI CSI-2差不多毕竟都是Sony在图像传感器上常用的串行接口。等把物理层部分读完才发现这个判断会带偏整个方案设计。1.1 嵌入式时钟的串行链路SLVS-EC的全称是Sony Low Voltage Serial Signaling with Embedded Clock最关键的就是“Embedded Clock”这两个词。它不像MIPI CSI-2那样单独拉一根差分时钟通道而是把时钟信息直接嵌入到高速数据流里接收端要通过CDRClock and Data Recovery把时钟恢复出来。这一点直接决定了FPGA侧不能用普通的LVDS/SubLVDS接收器去处理。随便一个LVDS接收器只能做差分转单端它没有时钟恢复能力更谈不上Gbps级别的串并转换。SLVS-EC的单通道速率随便就是2.34Gbps这个量级必须用带CDR的SerDes收发器来收。这也是为什么项目里最终落到Kintex-7的GTX上而不是用一堆LVDS bank去凑。GTX的CDR核心能力就是干这个的它从进来的比特流里提取时钟再用这个恢复时钟去采样数据、解串成并行总线。这跟SLVS-EC的需求天然对得上。1.2 IMX421的Lane配置和数据格式IMX421这类Sony传感器一般会支持多种Lane模式常见的有2 Lane和4 Lane具体用几条通道取决于你要跑的帧率和像素格式。Sony的传感器手册里通常会给一个建议配置表告诉你什么分辨率、什么帧率下用几条Lane、每条Lane跑多少速率。这里最容易踩的第一个坑是Lane数和线速率不是随便定的它和你选的PLL参考时钟、FPGA GTX的PLL分频组合是强耦合关系。我在项目里就是先定了“传感器配4 Lane、RAW12、60fps”然后才去反推GTX参考时钟频率结果发现常用的125MHz根本没法整数分频到传感器要求的线速率最后只能换参考时钟。数据格式方面IMX421通常支持RAW10、RAW12这类Bayer输出。FPGA侧不需要关心像素格式本身但要知道每条Lane传输的有效数据位宽和字序因为这些直接决定了解串之后的数据怎么拼接。我在调试后期遇到过图像颜色整体偏掉的情况最后查出来就是传感器配了RAW12输出FPGA却按RAW10的位宽去解析整整错开了一个位域。1.3 为什么SLVS-EC不能用普通LVDS接收器硬接很多做过工业相机的工程师看到“低电压差分信号”就会条件反射想到LVDS接收器这个直觉需要纠正。SLVS-EC的差分摆幅比传统LVDS更小再加上它没有单独的时钟通道本质上是一个“窄带高速串行链路”不是传统的并行传输接口。如果用普通LVDS接收器去接最多只能把差分信号变成单端数字信号后面还是要面对Gbps级别的串行数据怎么时钟恢复、怎么解串的问题。绕了一圈你会发现最终还是绕不开FPGA的SerDes硬核。所以方案设计初期直接按SerDes的思路来做能省下很多弯路。2. 为什么选Kintex-7 GTX速率、PLL与成本之间的平衡确定了要用带CDR的SerDes收发器之后接下来就是选FPGA。市面上能接SLVS-EC的方案其实不少Zynq UltraScale的GTH/GTY可以Intel的Transceiver也可以但我不建议一上来就上高端平台——成本和复杂度都溢出了。2.1 GTX收发器能力与型号选择Kintex-7系列里的GTX收发器在不同速度等级下的最高线速率不太一样。通常-2速度等级能跑到10.3125Gbps左右-3速度等级更高12.5Gbps也有。IMX421的SLVS-EC单通道速率一般在2.34Gbps附近这个速率对GTX来说压力很小余量非常大。具体型号上我这边用的是XC7K325T-2GTX数量足够覆盖传感器的4条Lane还能富余几条用于调试和后续扩展。如果逻辑量不大XC7K160T也能做只要GTX数量和逻辑资源够就行。对比Artix-7的GTP收发器虽然理论上也能跑到这个速率但GTP的参考时钟容忍度和文档完备程度不如GTX第三方参考设计也更少所以我最终没有考虑GTP方案。注意选型时不要只盯着GTX速率还要看FPGA的GTX BANK分布。4条Lane最好集中在同一个GTX BANK里方便统一时钟管理和复位时序。如果Lane分布在两个BANK跨BANK的时钟处理会麻烦不少。2.2 参考时钟的整数倍频思维GTX要正常工作必须有一个参考时钟输入。这个参考时钟经过GTX内部的PLL倍频之后再通过串行分频落到目标线速率上。关键约束是参考时钟频率要能整数倍分频到线速率或者至少让PLL的VCO频率落在合法范围内。拿2.34Gbps举例。如果参考时钟用125MHz2.34 / 0.125 18.72不是整数PLL组合起来非常别扭Vivado的GTX Wizard里经常直接报错或者即使生成了IP上板之后CDR锁定的裕量也很差。我最后是用117MHz参考时钟解决的2.34 / 0.117 20正好整数倍PLL工作得很舒服。这里有个工程技巧实在找不到合适的整数倍关系时可以通过调整PLL输出的VCO频率加串行分频器TXOUT_DIV/RXOUT_DIV来凑。GTX的PCS内部有好几级分频不是只能1倍频到线速率。但这是最后手段第一优先级还是选一个能让PLL整数倍工作的参考时钟。类似地有时候选78MHz、93.6MHz这类非标频率也是合理的关键是整数倍频关系要成立。2.3 被很多人忽略的GTX BANK供电要求K7 GTX对电源纹波的要求比普通逻辑BANK高不少。GTX的AVTT、AVCC等引脚如果供电纹波过大最典型的现象是CDR锁定不稳定、误码率偏高而且这种问题用示波器还不一定看得出来。我在原理图设计时就专门给GTX电源加了独立的LDO或者低纹波的DC-DC并且特别注意了磁珠滤波和去耦电容的摆放。上板之后用IBERT做误码率测试轻松跑到10^-15级别以下。如果图省事直接从数字3.3V电源域拉过来后面调试SLVS-EC链路时会非常痛苦。3. 电气特性匹配SLVS-EC信号进GTX之前的每一处细节电气特性匹配是整个项目里决定成败的一步。SLVS-EC信号幅度小、速率高任何一个环节处理不好都会直接表现为CDR锁不住或者数据误码。很多朋友问我的第一个问题就是“GTX的输入能不能扛住SLVS-EC的电平”这个答案是肯定的但前提是匹配方式要正确。3.1 交流耦合与端接别把传感器输出当普通LVDSSLVS-EC信号进入GTX之前必须经过交流耦合电容。GTX的RX输入本身也要求AC耦合这是Xilinx官方给的建议电容值一般在0.1uF左右要求介质是X7R或者C0G不能随便用电子料里常见的Z5U电容。如果传感器输出的信号中包含低频分量AC耦合电容的取值就不能太小否则时间常数不够会把低频信息吃掉。项目里我用的是0.1uF实测没有问题。如果传感器手册里明确要求某种耦合方式以手册为准。端接电阻同样关键。GTX内部有可配置的RX端接一般可以配置成100欧姆差分端接这正好匹配SLVS-EC的100欧姆差分阻抗。但为了保险起见原理图上我还是在靠近FPGA引脚的位置预留了外部100欧姆差分端接的位置等于双保险。实际焊接时先不上外部电阻直接启用GTX内部端接测试通过了就不再动。3.2 共模电压和灵敏度SLVS-EC的差分输出摆幅典型在几百毫伏级别比传统LVDS的350mV还要小一些更接近SubLVDS的水平。K7 GTX的RX输入灵敏度远高于这个值所以真正要担心的是共模电压范围。GTX的RX在交流耦合之后输入端的直流工作点由FPGA内部结构决定而不是由传感器侧决定。也就是说AC耦合电容解决了两个芯片共模电压不一致的问题。前提是传感器的差分信号幅度不要超过GTX的绝对最大额定值否则有损坏引脚的风险。提示在第一次上电调试之前务必用示波器量一下传感器输出的差分信号幅度。如果幅度明显偏低比如只有几十毫伏先别急着怀疑FPGA去IMX421的寄存器配置里查输出摆幅控制项把它调到合适档位再继续。3.3 PCB走线的几项硬指标SLVS-EC在2.34Gbps下已经属于高速信号设计范畴PCB走线不能抱着“响就行”的心态。差分阻抗按100欧姆控制对内等长尽量控制在5mil以内跨层要避免对地平面产生大的破坏过孔数量越少越好。我画的板子上SLVS-EC差分对一路走内层参考地平面完整传感器到FPGA的走线长度控制在1英寸左右实测眼图余量不错。如果走线长度拉得很长或者中间有换层过孔建议在接收端补一个小的共模滤波或者再减小端接电阻试一下。AC耦合电容的位置也有讲究。理想情况是靠近接收端放也就是靠近FPGA的GTX引脚这样整个走线的大部分保持直流耦合状态阻抗更连续。电容本身有寄生效应摆放时要注意焊盘处地的连续性。4. 用GTX收数据时的关键配置与复位时序Vivado里生成GTX IP不算难难的是知道该关掉哪些东西、该手动处理哪些东西。SLVS-EC不是标准协议GTX Wizard里内置的PCIe、Aurora模板都不能直接用我最后用的是“Start from Scratch”模式把所有协议层都剥掉只保留纯粹的收发通道。4.1 从零开始配置GTX Wizard在GTX Wizard里线速率填IMX421实际的工作速率比如2.34Gbps参考时钟填117MHz。数据位宽我选了2字节16bit接口这样可以降低内部逻辑的时钟频率布局布线压力小一些。关键点是关闭GTX的8B/10B编码。SLVS-EC有自己的一套通道编码和同步机制不需要GTX再叠一层8B/10B。如果开着8B/10BGTX会尝试用标准comma做字节对齐但SLVS-EC的比特流里不会出现它期望的comma图案结果就是对不上、数据错乱。“Start from Scratch”模式跑起来之后生成的IP只有GTX收发通道、DRP接口和复位逻辑没有多余的协议栈所有链路层的事都留给FPGA逻辑自己处理。4.2 字节对齐不能用GTX自带comma检测关闭8B/10B之后GTX自带的comma检测和对齐机制就失效了。也就是说并行数据输出时的字节边界是任意的可能错位一个bit或者一个字节。这时候要自己实现字节对齐用到的GTX原语是rxslide。实现思路是把GTX输出的并行数据送给一个对齐状态机状态机在数据流里扫描SLVS-EC的同步码。同步码是Sony协议里规定的固定特征图案一旦连续多个周期都检测到它就认为当前字节边界是对的如果检测不到就拉一次rxslide信号让接收窗口滑动一个位置再继续扫描直到对齐成功。这个做法和传统SerDes里的comma对齐逻辑本质一样只是特征图案从8B/10B的comma换成了SLVS-EC自己的同步码。4.3 复位顺序和CDR Lock的等待逻辑GTX的复位时序如果处理不好就算配置全对链路也起不来。通用做法是先拉低GTX TX复位等TX PLL锁定再释放RX复位等RX CDR锁定最后再开始做字节对齐和链路握手。项目里我在Verilog里写了一个简单的状态机把复位流程拆成四步等待GTX TXPLL锁定释放TX复位释放RX复位等待rx_cdrlocked信号拉高。每一步都加了超时计数万一哪一步卡住可以通过ILA观察状态机停在哪个状态快速定位问题。CDR锁定之后GTX的rxdata还不是有效数据要等字节对齐完成之后才对。很多人一看到rx_cdrlocked拉高就急着抓数据结果抓到一堆乱码还以为是物理链路有问题其实是对齐没做。5. 链路层解析同步码、跨通道对齐和帧打包打通了GTX物理层之后接下来就是把并行数据还原成图像帧。SLVS-EC的链路层有一套自己的打包规则包括同步码、包头、负载数据和CRC。这部分完全靠FPGA内部逻辑实现是项目里工作量最大的地方。5.1 同步码扫描与rxslide滑位同步码扫描状态机是链路层的起点。我在GTX的恢复时钟域里对rxdata做连续的移位寄存器匹配一旦匹配到SLVS-EC的同步码特征值就把当前的偏移位置记录下来后续所有数据都按这个偏移来解析。这里有个细节最好同时检测连续两组同步码而不是只检测一次。原因是单次匹配可能是随机比特序列碰巧撞上了。连续两次固定的同步码才能表明真正进入了正确的字节边界。实际调试中这个双确认机制帮我挡掉了好几次误触发。5.2 多Channel的De-Skew多条Lane并行传输时由于PCB走线长度、温度差异等因素每条Lane的数据到达时间会有微小偏差。SLVS-EC协议在每条Lane上都会周期性发送同步码FPGA侧要做的是以某一条Lane为基准把其他Lane对齐到同一时刻。具体做法是每检测到一次同步码就记录当前时间戳和Lane内偏移然后通过可配置的FIFO把每条Lane的数据调整到同一拍输出。这有点类似PCIe里的Lane Deskew只不过触发源是自己定义的同步码。实践建议先单独调通每条Lane的字节对齐再做Lane之间的De-Skew最后再拼接完整数据。三步分开调试每步都有明确验证点比一次性全部做完更容易定位问题。5.3 数据位宽组合与缓存设计4条Lane全部对齐之后每条Lane是16bit并行数据4条合并就是64bit总线。接下来把这些数据按SLVS-EC协议解出帧头、行信息和像素数据再转换成AXI-Stream或者简单的FIFO接口供后级图像处理或DDR3写入使用。跨时钟域处理一定要用异步FIFO。GTX恢复时钟域和图像处理时钟域不是同一个频率直接拿信号会出亚稳态。我这里用Xilinx的FIFO IP读侧挂在图像处理时钟域写侧挂在GTX的恢复时钟域数据位宽做一次拼接逻辑非常清晰。帧开头和行有效信号怎么判断要看Sony协议手册里对HVALID/SOF这些控制信号的定义。每个传感器的包结构略有差异这块必须对着IMX421的寄存器手册逐个字段核对不能想当然套用其他型号。6. 上板调试的完整排查链路上板调试是整个项目最考验耐心的一环。SLVS-EC链路的问题往往一会儿像物理层、一会儿像逻辑层没有一套固定的排查顺序很容易陷入泥潭。总结一下我调通这个项目时用的排查链路按这个顺序走能把大部分问题快速逼到墙角。6.1 先用IBERT确认物理层自环保拿到板子第一件事不是接IMX421而是用Vivado里的IBERT例子工程做GTX自环测试。把GTX配置成内部Loopback模式发伪随机序列统计误码率确认FPGA这颗料、这块板子的GTX通道本身是好的。这个步骤能过滤掉大量物理层变量。如果IBERT自环保都过不了别急着怀疑SLVS-EC信号先查FPGA供电、参考时钟、GTX配置。IBERT的误码率报告会直接告诉你每个通道的眼图裕量和误码数是物理层调试最趁手的工具。IBERT通过之后把Loopback断开接上真实的IMX421信号再做一次低级测试不解析任何协议只抓GTX的rxdata看是否有稳定的比特翻转。如果能观察到数据在变化说明SLVS-EC的串行信号已经成功进入FPGA内部CDR也锁住了。6.2 ILA抓同步码的实操技巧ChipScope ILA在链路层调试里是主力工具。抓同步码的时候触发条件设置为“匹配同步码特征值”采样深度设深一点至少要能看到对齐前后的完整波形。我遇到过的一种典型情况是ILA触发到了同步码但同步码的位置每隔一段就跳动一个bit。这说明字节对齐状态机不稳定或者rxslide滑动逻辑有问题。重新检查偏移锁定逻辑确定在检测到同步码之后停止滑动而不是持续尝试新偏移。另一个容易被忽略的点ILA的采样时钟必须用GTX的rxusrclk不能用其他逻辑时钟。如果采样时钟和GTX恢复时钟不是同一个抓到的波形会有相位误差分析起来非常容易误导。6.3 图像错误时的对照排查表调通链路层之后最后一步是确认图像数据本身是否正确。这里我整理了一个问题对照表遇到现象直接查表定位节省了很多时间。现象可能原因排查方向画面整片花屏Lane顺序错误或数据位宽配置错误检查Lane映射、rxdata位宽是否与传感器输出匹配图像偏色严重像素格式解析错误确认RAW10/RAW12配置检查位域拆分逻辑图像上下错位或行错乱行同步信号解析错误检查HVALID解析逻辑、同步码后跳过的字段是否正确画面有一道道斜纹Lane间De-Skew偏差重新检查各Lane同步码时间戳调整FIFO深度偶发丢帧或绿屏跨时钟域FIFO溢出或复位异常检查FIFO深度、背压逻辑、复位时序图像整体平移了一个像素字节对齐偏移错误重新检查rxslide锁定位置对比像素边缘其中“画面有一道道斜纹”是最容易误判的我一开始以为是传感器配置问题反复改IMX421寄存器没有任何改善后来用ILA对比各Lane的同步码时间戳才发现两条Lane的延迟差异超过了时钟周期。调整De-Skew FIFO的深度之后斜纹立刻消失。最后再分享一个小经验调试过程中把IMX421的输出摆幅、Lane数、像素格式、GTX参考时钟这些关键配置都记成一张表每次改动只动一个变量并记录现象不要同时改两个参数。SLVS-EC链路涉及的配置项太多变量一旦叠加问题就永远定位不清楚。这个方法听起来笨却是调通这类高速传感器接口最靠谱的方式。
返回列表