ARTICLE DETAIL

资讯详情

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

基于AU15P的SLVS-EC到PCIe图像采集桥接方案解析

基于AU15P的SLVS-EC到PCIe图像采集桥接方案解析 写这篇博文之前我先把这个项目的来龙去脉捋一遍。我们最近做了一套高端工业相机数据采集方案传感器输出的是索尼系CMOS常见的SLVS-EC接口信号上位机那边要的是PCIe中间怎么接最直接的办法就是找一颗合适的FPGA做桥接。反复比选之后定了AMD的Artix UltraScale系列AU15P把SLVS-EC收进来解析完图像数据通过PCIe DMA丢给上位机。整个项目从选型到调通前后花了两个多月中间踩了不少坑今天把设计思路、关键决策和调试过程完整梳理一遍给做类似采集方案的朋友一个参考。1. 为什么非要桥接SLVS-EC输入与PCIe输出之间缺的哪一环1.1 SLVS-EC是什么为什么传感器厂喜欢用它SLVS-EC全称Scalable Low Voltage Signaling with Embedded Clock是索尼主导定义的一种高速串行接口标准专门用在CMOS图像传感器和后续处理芯片之间。你可以把它理解成MIPI CSI-2的工业级变体同样是串行差分传输但SLVS-EC把时钟直接嵌进了数据流里接收端需要做CDR时钟数据恢复而不是靠一根独立的时钟线做源同步采样。它最吸引传感器厂商的一点是Scalable速率能从几百Mbps一路拉到几Gbps甚至更高而且lane数量可配置。像素越多、帧率越高就多加几条lane非常灵活。另外它用的是低压摆幅信号功耗控制比传统LVDS好很多。所以在高分辨率、高帧率的全局快门传感器上SLVS-EC几乎成了事实标准。对比一下MIPI CSI-2就能看出差异。CSI-2的物理层基于MIPI D-PHY或C-PHY协议上更偏消费电子bandwidth规划受到D-PHY速率档位的限制多lane的对齐机制也比较固定。SLVS-EC的包格式更简单直接适合裸数据搬运没有那么多CSI-2的帧格式和虚通道设置。对FPGA开发者来说SLVS-EC免license、文档公开、实现自由度更大这对做定制化采集板卡非常重要。1.2 AU15P在同系列里为什么适合干这个活拿到需求后我在AMD的中端FPGA系列里筛了一遍。Artix UltraScale是AMD面向成本敏感但需要高速收发器的场景主打的一系列器件AU15P是里面资源比较顶的一颗逻辑单元规模大概在50万级别DSP和URAM数量也够用同时集成了大量GTY高速收发器速率上限能覆盖SLVS-EC的实际需求。最关键的是它内置了PCIe硬核支持Gen3 x8这对做桥接方案来说是决定性的——硬核比逻辑拼出来的软核稳定太多带宽也高得多。对比同系列里更小的AU7PAU15P在逻辑资源、BRAM/URAM容量、收发器数量上和PCIe硬核规格上其实都有明显优势。AU7P做简单的桥、低带宽采集也够但我们这套方案还要做图像拼接、坏点校正、ROI裁剪这些预处理逻辑预留资源不足会很被动。AU15P多出来的URAM对图像行缓存特别友好一张1080p图像的行数据放进URAM完全没问题不用老往DDR4里搬。再说一个选型细节AU15P的GTY收发器支持从几百Mbps到12.5Gbps的速率SLVS-EC常见速率档位全都能覆盖。如果选纯逻辑资源大但收发器弱的器件就得在外部再挂SLVS-EC PHY芯片或者SerDes芯片成本和版图复杂度直线上升。一颗AU15P把这些活全包了板子上不需要额外的高速PHY这对项目周期是巨大的帮助。2. 整体数据通路从Sensor到DDR再到上位机的每条路都要算清2.1 数据流的四段链路整条数据通路我从Sensor侧到上位机侧拆成四段SLVS-EC接收段、预处理段、DDR缓存段、PCIe DMA段。第一段是FPGA的GTY接收器直接接收传感器的SLVS-EC差分信号在接收端恢复出并行数据然后做lane对齐和deskew把多lane的数据拼成完整的像素流。SLVS-EC协议包里会有Header和FooterHeader里包含帧号、行号、数据格式这些信息协议解析模块负责把这些抠出来把纯像素数据转成AXI4-Stream流。第二段是预处理。这一段的复杂度看项目需求简单场景下只是做像素重排和格式转换比如把10bit Bayer数据打包成16bit对齐。复杂场景就要加ISP、坏点校正、黑电平扣除、LUT、直方图统计这些在AU15P的DSP和BRAM资源下都能实现。第三段是DDR4缓存。SLVS-EC是传感器推数据速率恒定但PCIe DMA是突发性拉数据速率不恒定两者之间必须靠帧缓存来削峰填谷。正常情况下DMA带宽要大于Sensor输入带宽这样缓存只是个小缓冲如果Sensor瞬时带宽大于DMA突发带宽就必须靠DDR4做大缓存。第四段是PCIe DMA把缓存里的图像数据通过DMA引擎搬进上位机内存或者通过P2P直接给到GPU显存。这部分用AU15P自带的PCIe硬核加XDMA控制逻辑实现数据面跑AXI4控制面跑AXI4-Lite。2.2 带宽预算计算带宽预算这步千万别省我在项目启动第一天就按最坏情况算了一遍。以我们项目用的传感器为例5000万像素全局快门30fps10bit输出。原始像素带宽是50M x 30 x 10bit 15Gbps。SLVS-EC不是纯像素流包格式里还有Header、Footer、CRC这些开销和MIPI CSI-2类似协议开销大概在2%到5%按4%算就是15.6Gbps。如果用8条lane承载单lane速率约1.95GbpsGTY完全没压力。到了PCIe侧Gen3 x8单向带宽是7.877GB/s也就是63Gbps远超15.6Gbps的输入带宽看起来绰绰有富余。但要注意PCIe实际有效带宽到不了理论值通常Gen3 x8 DMA实测能到6.5GB/s到7GB/s就不错了即便如此也超过15.6Gbps约三倍所以瓶颈不在PCIE总线反而在DDR4读写调度和SLVS-EC接收逻辑上。DDR4这条链路要仔细算。我们用一颗DDR4颗粒数据位宽16bit速率2400MT/s理论带宽9.6GB/s。读写各占一半的话实际可用带宽要打折读写交替还有总线翻转开销实际能用大概5GB/s到6GB/s。Sensor输入只有2GB/sDMA输出峰值可能到6GB/s加上预处理读改写DDR带宽是够的但余量不大了。所以DDR4控制器端要做好QoS仲裁图像数据的高优先级通道不能被别的低优先级访问饿死。2.3 为什么中间要挂DDR4而不是直通有人会问PCIe峰值带宽这么高能不能不挂DDR4直接从SLVS-EC到PCIe FIFO一下就跑答案是可以但有严格的限制条件。如果Sensor帧率和DMA的实时性配合得足够好比如DMA是持续满带宽拉数据FIFO只做几十行的行缓冲直通方案能成立。但这样做有两个隐患一是万一上位机DMA请求有延迟FIFO深度不够就直接丢帧二是传感器一秒钟多少帧是不可变的DMA的带宽被其他PCIe设备挤占时你没办法让Sensor停下来等你。DDR4在这里起的作用不是存一整个帧的完整备份而是提供一个大容量的松耦合缓存。Sensor数据来的时候先写进DDR4的环形缓冲DMA空闲了再搬出去。即使DMA有几十毫秒的延迟DDR4的容量也能兜住不会丢帧。再加上我们还需要做图像预处理像多帧降噪、3A统计这些算法需要访问历史帧数据这就必须DDR4了。不过要提个醒加DDR4也引入了新的难点带宽竞争和时延不确定性。如果DDR控制器调度没做好Sensor写入请求可能被DMA读请求堵住导致FIFO溢出丢帧。我们在设计里给Sensor写通道设了最高的AXI QoS优先级同时DMA读通道设了中优先级确保输入数据永远是第一优先级的。3. 硬件设计上的几个关键决策电平匹配、参考时钟与电源3.1 SLVS-EC电气接口与FPGA收发器的对接SLVS-EC的物理层电气特性需要重点核对。SLVS-EC是电流驱动型差分信号共模电压和摆幅都有特定范围。接AU15P的GTY时第一件要确认的事是共模电压匹配——GTY的RX端设计上通常是给PCIe这类标准接口准备的内部的RX端接网络共模点不一定和SLVS-EC一致。我们的做法是在RX差分对上加交流耦合电容电容值选100nF到220nF这样DC共模被隔离掉AC信号正常通过。GTY内部RX端接可以配置成50欧姆到VTTVTT取决于供电电压。通过内部寄存器把RX终端电阻打开然后在PCB上把VTT拉到SLVS-EC要求的共模电压附近。如果SLVS-EC输出类型是电流模式外部可能还需要一个到地的偏置电阻网络这部分要严格按传感器厂家手册来不能想当然。差分对布线要特别注意等长和阻抗。SLVS-EC单lane速率到2Gbps以上时走线的反射损耗和串扰影响非常大。我们的原则是差分阻抗100欧姆或按传感器手册要求有些是100欧差分对内等长控制在5mil以内对间等长控制在50mil以内。另外一个容易忽略的点是AC耦合电容的封装选择小封装电容寄生参数小但耐压和可靠性要重新评估我们最后选了0402的NP0电容性能实测没问题。3.2 参考时钟与时钟树的处理时钟设计是FPGA高速接口这部分的命脉。SLVS-EC是嵌入式时钟GTY收到数据后靠RX CDR从数据流里恢复时钟所以不需要额外给GTY提供和SLVS-EC数据同步的参考时钟。但GTY的参考时钟决定了RX CDR的搜索范围和恢复出的并行时钟频率这个时钟的精度直接影响CDR锁定成功率。我们使用了板上独立的100MHz参考时钟给GTY的MGTREFCLK同时PCIe硬核也需要参考时钟这里也用的100MHz。两路参考时钟都用低抖动晶振通过时钟Buffer分成多路保持各GTY Bank之间的时钟同源。别图省事把参考时钟和系统时钟共用抖动和频率偏差会让CDR锁定的时间拉长严重时直接锁不住。上板调试时第一件事就是拿频谱仪测参考时钟的相位噪声。具体到AU15PGTY的参考时钟输入有专用的MGTREFCLK引脚PCB走线要严格控制阻抗和串扰不要和别的信号交叉。REFCLK的端接方式按UG576文档配置一般是用内部端接外部不需要再加电阻加了对差分信号反而会造成阻抗不连续。3.3 电源轨与上电时序的简单梳理AU15P的电源设计比传统中端FPGA复杂不少因为器件功耗上去了各种电源轨的电流需求不同而且有严格的上电时序要求。关键电源轨包括VCCINT核心逻辑0.85V左右、VCCINT_IO、VCCBRAM、VCCAUX、VCCO以及GTY的VMGTAVCC和VMGTAVTT。其中VMGTAVCC和VMGTAVTT的纹波噪声直接影响高速收发器眼图质量一般要求10mV以内波纹。电源设计上建议每路独立用一颗高精度DCDC或者LDO至少高速收发器相关电源轨要用低噪声LDO同时加足够的去耦电容。上电时序按照AMD文档要求做通常是VCCINT先上然后是VCCBRAM和VCCAUX最后是VCCO和GTY电源。用电源监控芯片加一个CPLD做时序控制最稳妥成本加不了多少但能保证上电不损坏器件。调试的时候特别要留心用示波器测VMGTAVCC的纹波时一定要在FPGA附近测量不是电源模块输出端。因为PCB走线电感会造成远端压降和噪声叠加远端测出来的纹波才是GTY实际看到的如果纹波超标SLVS-EC接收眼图会恶化表现为误码率升高但基层逻辑可能跑得正常。4. FPGA内部逻辑SLVS-EC接收、DMA与背压4.1 SLVS-EC协议解析模块的设计细节协议解析模块是整个FPGA逻辑里最核心的部分也是最容易被低估的一块。SLVS-EC的包格式和MIPI CSI-2的包格式差异很大SLVS-EC是流式的包头有固定的同步码带帧号、行号、数据格式类型数据段后面还有CRC校验。如果CRC校验失败通常的做法是丢弃这一行而不是整帧丢弃然后输出错误行信号给上位机。物理层恢复出来后GTY的RX端会给出一个并行数据接口以lane为单位。多个lane之间的数据要对齐核心机制是检测Header里的同步码然后以同步码所在位置为基准对每个lane做独立的移位调整。这个操作时序上比较繁琐建议用状态机分阶段执行检测同步码、计算偏移、拉齐所有lane、进入数据透传状态。对齐之后要在每个lane后面再接一个FIFO把跨时钟域的数据转成内部逻辑时钟域。SLVS-EC的多lane模式里有个关键概念是lane交织还是lane独立传输。如果是lane交织像素数据是交替分布在所有lane上的拼接时需要按规则重排如果是lane独立传输每条lane传固定的通道数据。这两者的数据重组逻辑完全不同必须仔细看传感器手册确认我们在项目初期就是因为没确认这一点走了两天弯路。4.2 PCIe DMAXDMA与自定义DMA的取舍PCIe DMA的实现方案我对比过XDMA软核和自己RTL写DMA。最终选了AMD官方的XDMA原因很直接稳定、省时间、驱动和文档生态成熟。XDMA的AXI4主接口带宽高AXI4-Lite从接口可以接收上位机命令中断机制也完整。硬核加软件驱动配合基本把PCIe驱动的内核维护工作降到了最低。自定义DMA的优点是可以按应用定制减少不必要的功能从而节省逻辑资源。但问题是PCIe的TLP构造、完成包处理、重试机制、流量控制这些细节处理起来非常费精力而且出了问题很难查。做产品的话时间就是成本我建议除非对PCIe协议有深入掌握否则优先用XDMA把精力集中在图像处理数据通路上。XDMA使用上有个要点描述符环Descriptor Ring的设计。XDMA支持Host和Local两种模式我们选了Host模式由上位机分配DMA缓冲区把物理地址告诉FPGA端描述符然后XDMA按照描述符搬运数据。缓冲区地址必须4KB对齐不然会产生性能问题甚至卡死。上位机驱动里分配内存时要用页对齐分配不能随便malloc。4.3 帧缓存与背压机制帧缓存设计是保证数据不丢的关键。我把DDR4划分成多个缓冲区用于缓存传感器输入数据。这里用环形缓冲结构Producer是SLVS-EC写通道Consumer是XDMA读通道。环形缓冲的剩余空间是固定的要实时监控。背压机制的核心是防止Producer覆盖Consumer还没读走的数据。AXI总线上用READY信号做逐拍反压但反压只能停一个周期如果DDR4写通道因为带宽满而长时间拉低READY上游FIFO就会溢出。所以在SLVS-EC写DDR之前加了一个深度可配置的FIFOFIFO水位到达高阈值后抛出一个中断给控制逻辑。接下来有两种策略一是允许丢行丢弃新来的行数据保证已有数据不丢二是停止接收Sensor数据让Sensor进入等待状态。SLVS-EC这种传感器在主动推数据时不太好让它停。所以我们在FIFO水位超过80%时就会主动丢弃后续的行数据并记录丢行计数同时上报上位机。实测来看只要DMA带宽规划合理这种情况几乎不会出现但一旦出现系统不至于死锁丢行重发一帧就恢复这是工程上很实用的兜底策略。4.4 控制通路与寄存器控制通路用AXI4-Lite通过XDMA的BAR0空间映射到上位机可见地址。我们在FPGA侧做了两个寄存器组一个是全局控制寄存器用于使能Sensor输出、软复位、中断状态回读另一个是状态寄存器用于上报当前帧计数、丢帧计数、CRC错误计数、FIFO水位。这套方案里上位机软件通过读写BAR0空间来控制FPGA。软件设好寄存器Sensor就开始出图FPGA驱动XDMA持续搬运数据同时周期性更新状态寄存器。上位机侧用了一个工作线程轮询状态寄存器如果发现丢帧计数器有增长就通过配置寄存器调整DMA缓冲区的数量或者请求重传。控制通路本身不用太复杂但寄存器地址映射表和文档一定要写好不然后期联调全是坑。5. 调试过程与踩坑记录5.1 调试链路从IBERT到全链路通流整个系统调试我按从底向上的顺序来没有一步到位全链路联调不然出问题根本没头绪。第一步是IBERT测GTY物理层眼图。AMD的IBERT工具可以图形化显示RX端眼图和误码率先验证SLVS-EC信号进FPGA的物理通道是否OK。用PRBS模式让GTY对发一段已知序列检查眼图和BER。如果眼图不好看要回查PCB布线、参考时钟质量和电源纹波这三个方面。第二步是绕过协议层做数据回环测试。把GTY RX收到的数据原路丢给TX发回去看传感器端如果有第三方Sensor模拟器能不能正常收到回环数据。这一步验证了物理层到收发器数字侧的路径通畅。第三步才是真正的SLVS-EC协议解析。传感器先出单行的测试pattern比如纯色图或渐变图FPGA解析后做简单的像素统计把每一行的平均值、最大值、最小值打出来和预期的渐变值对比。这里能快速验证Header、CRC、像素格式解析是否正确。最后一步是PCIe链路。先用XDMA自带的Loopback测试上位机向FPGA写一段数据再读回来比对确认BAR映射、DMA描述符、中断链路全部正常。然后接入真实图像流全链路通流看图像。5.2 踩坑1GTY的RX CDR锁定失败第一个遇到的大坑是CDR失锁。刚开始上电调试时无论怎么配置GTY RX都锁定不上眼图显示信号质量不错但CDR就是反复锁定又反复掉锁。排查了很久才发现是GTY配置里选错了CDR模式——AU15P的GTY支持LPM和PPF两种CDR模式。LPM模式锁定时间短但抖动容忍度低PPF模式则相反。我们的SLVS-EC数据流是连续传输中间不会长时间停顿理论上LPM没问题但实测发现某个特定速率档位上LPM模式的高频抖动容限不够导致锁定不稳定。解决办法是改用PPF模式。PPF锁定时间稍长一点但锁定稳定度好很多。SLVS-EC这种连续数据流对锁定时间不敏感多等几个微秒完全可接受。这个坑给我们的教训是速率越高CDR模式对眼图质量的敏感度越高。调试时不要只盯着眼图好不好看还要看CDR的lock状态用虚拟IO核把CDR状态寄存器读出来实时观察。5.3 踩坑2多lane数据之间的skew多lane对齐这步标准做法是检测同步码然后按lane分别调整到同一基准位置。但在实际调试中总有两三个lane的数据重排后是错位的表现为图像有明显的纵向条纹。最后发现是因为不同lane的PCB布线长度差异导致数据到达GTY的时间不同虽然语法时序约束做了但对间等长一致性不够。解决办法是先把每条lane的走线长度量了一遍把对间skew因子量化出来然后根据这个skew值在FPGA逻辑里额外补偿。SLVS-EC协议本身也提供了deskew机制具体是周期性发送一个特殊控制码FPGA收到控制码后调整FIFO读位置这样就把PCB布线引入的固定skew自动消除了。所以一定要仔细看SLVS-EC协议手册里deskew部分的内容把它实现出来。这里值得提醒的是deskew逻辑必须加在CDR之后、数据拼接之前。如果放在CDR之前会破坏CDR锁定放在拼接之后就只能处理整包级别的偏移处理不了lane内在的bit偏移。5.4 踩坑3DMA带宽峰值与丢帧全链路联调时发现一个隐蔽问题DMA连续读传10GB数据后会出现一次偶发丢帧但重跑或许就正常。查了半天最后定位到是XDMA描述符环的更新方式有问题。我们的上位机驱动在DMA描述符完成后没有及时把描述符的归还没收状态同步给FPGA端导致XDMA在连续大吞吐时偶尔找不到可用的描述符直接停在原地等。因为输入侧还在持续写DDRDDR里的环形缓冲就满了然后就丢了一帧。解决办法是对描述符管理做了优化上位机驱动里把描述符分成两组交替使用DMA引擎正在读A组时上位机已经可以准备B组了两组来回倒换彻底消除了描述符不足的等待。同时DMA缓冲区用HugePage分配减少TLB miss带来的延迟抖动。这个问题的本质是软件和硬件的流水线配合问题。FPGA硬核只管按描述符取数但描述符谁来准备好、什么时候准备好、准备好了怎么通知FPGA这些软硬配合细节是性能瓶颈的最大来源。设计和调试时要一起做别等FPGA做完再找驱动工程师。6. 实测效果与还可以扩展的方向6.1 实测数据与性能表现系统全部调通后我们做了24小时的压力测试数据如下SLVS-EC接收带宽15.6Gbps稳定运行无CRC错误PCIe DMA带宽Gen3 x8实测约6.3GB/s读传大块数据稳定无掉速DDR4带宽占用率系统满载约60%有充足余量端到端延迟从Sensor出图时刻到上位机内存可访问约2.3ms含一帧缓存时间长时间稳定性24小时连续运行丢帧计数为0这个结果基本符合预期。CPU占用率方面XDMA的中断合并机制做得不错再加上HugePage优化上位机应用层的CPU占用大约在5%左右剩下大量CPU资源可以留给AI推理或图像处理算法。6.2 后面能怎么扩展这套平台稳定后后续想继续扩展也不难一是把预处理逻辑加厚。AU15P里DSP资源够做一套简化版ISP管线包括去马赛克、坏点校正、白平衡、Gamma校正。如果做深度学习预分析还能用FPGA做ROI提取、预处理只传有效区域省PCIe带宽。二是改用PCIe P2P直接到GPU显存。这样图像数据不用先到CPU内存再搬到GPU省一次内存拷贝CPU占用更低特别适合实时推理场景。三是多加路输入把AU15P的收发器资源用完单板做到8路甚至16路SLVS-EC输入做一个多目相机采集系统。帧同步逻辑只要以一路对外输出时钟为基准其他路做延迟补偿就行。四是做AI前处理下放比如在FPGA里接AMD Vitis AI跑一个小模型只传推理结果这样带宽占用会大幅下降特别适合高帧率筛选场景。我自己在这个项目里最大的体会是做桥接方案最容易翻车的反而不是具体某个模块而是跨越多个领域的配合问题信号完整性、协议解析、DMA驱动、上位机应用每个环节单拎出来都有标准答案但合在一起就需要系统性的调试思路。整体方案能不能跑得稳很大程度上取决于前期带宽预算和时钟规划有多仔细。希望这篇分享能给做类似SLVS-EC采集或FPGA桥接方案的朋友一个参考。
返回列表