ARTICLE DETAIL

资讯详情

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

CameraLink转光纤方案:FPGA与Aurora 8B10B实现图像长距离传输

CameraLink转光纤方案:FPGA与Aurora 8B10B实现图像长距离传输 做图像传输的同行应该都遇到过这种场景相机输出的是CameraLink接口但项目现场却要求把图像送到几十米甚至更远的地方还特别警告不能用粗重的CameraLink线缆。把CameraLink信号转成SFP光口用一根光纤代替原来的差分线束是目前工业视觉项目里最常见的改造方向之一。我采用的方案是Xilinx的GT Transceivers Wizard配置FPGA内部高速收发器再叠一层Aurora 8B10B协议做编解码把CameraLink的图像数据流打包发送实测在CameraLink Base模式下能稳定跑满带宽。这套方案适合手里有Xilinx 7系列FPGA、板卡上带了SFP光模块座子、想省掉自研高速链路协议的工程师。如果你正打算做CameraLink转光纤但又在纠结是该自己从GT底层写起还是直接用Aurora IP这篇文章会把带宽计算、数据通路设计、工程结构、调试心得一次讲清楚。文里提到的四套工程源码就是按发送、接收、回环验证、帧缓存这四类典型场景来组织的直接拿来当改造起点非常方便。1. 项目概述为什么要把CameraLink信号改成光口发出去1.1 CameraLink接口在实际工程里的局限CameraLink本身是NI和相机厂商联合定义的一种高速图像接口物理层基于Channel Link技术。如果从传输距离和线缆成本两个角度看它在工程现场确实让人头疼。CameraLink差分线束通常只能跑几米Base配置下一般不超过7到10米一旦超过这个距离信号完整性和时序就很容易出问题。线缆本身也又粗又硬MDR接口焊接难度大工业相机在机械臂末端、运动平台上安装时拖链弯折几次就容易接触不良。医院影像设备、半导体检测机台、户外监控这些对线缆长度和抗干扰有硬性要求的场景基本都会优先考虑光纤。光纤的优势很直观单模光纤几十公里不是问题多模光纤几百米到几公里很常见而且光纤细、轻、抗电磁干扰工业环境里走线舒服得多。所以这里的核心思路是“接口变换”CameraLink是图像源侧的数据格式SFP光口只是物理层的搬运手段真正在FPGA内部完成协议包装和恢复的是GT收发器和Aurora 8B10B。这样设计的好处是前端不管接的是CameraLink工业相机还是别的什么并行图像源后端光纤传输链路完全统一接不同板卡只需改前端适配部分。1.2 为什么选Aurora 8B10B而不是自己写GT逻辑刚接触这个需求时不少人的第一反应是从GT收发器底层写起。但真正动手后会发现GT收发器牵扯一套非常完整的链路初始化逻辑8B10B编解码、comma字符对齐、通道绑定、时钟补偿、初始化状态机、错误检测与恢复。这些逻辑本身工作量不小更麻烦的是任何一环没处理好都会导致链路不稳定排查起问题来非常费劲。Aurora 8B10B是Xilinx官方提供的免费IP核专门解决点对点高速串行传输问题。它把GT状态机、初始化握手、通道绑定、时钟补偿这些都封装好了用户只需要面对一套标准的AXI4-Stream接口把有效数据往里灌就行。对于图像传输这类数据量大、但对延迟不极端敏感的应用Aurora是被反复验证过的成熟方案很多FPGA相机、采集卡的数据通路底层都是这一套。选择8B10B编码本身也有原因。8B10B把每个字节映射成10bit符号保证直流平衡接收端可以通过符号跳变恢复时钟同时提供comma字符做字节对齐。也就是说Aurora不仅解决了“怎么传”还顺手解决了“怎么对齐、怎么恢复时钟、怎么发现拼写错误”这类问题。做产品时用官方IP能大大降低维护成本和交付风险这也是我最终选择方案的重要理由。1.3 带宽怎么算从CameraLink像素时钟到3.125Gbps光口做这个方案前第一个要算清楚的事情是带宽。CameraLink Base配置下最大像素时钟85MHz数据位宽28bit所以总数据带宽85MHz×28bit2.38Gbps。这个数值是用户侧有效数据量并不包含8B10B编码的开销。Aurora 8B10B线速率3.125Gbps时8B10B编码本身大约占掉20%的传输能力用户有效带宽约等于线速率×0.8也就是2.5Gbps。2.5Gbps相比2.38Gbps留了百分之五左右的余量刚好能让CameraLink Base配置跑满但余量并不算多。如果相机把像素时钟超到更高或者想传Medium/Full配置一根3.125G光口就不够了必须考虑多光口或者提升线速率。实际工程里我习惯把线速率选得稍保守一点避免光模块老化、环境温度变化后出现误码率上升的问题。如果板卡用的是Kintex-7这类GTX资源线速率上到5Gbps甚至6.6Gbps都没问题如果用的是Artix-7要看芯片是否带GTPGTP在3.125Gbps下完全能胜任但部分小容量的Artix-7型号不带高速收发器选型时一定得提前确认。2. 核心链路拆解CameraLink、GT与Aurora怎么协同2.1 CameraLink Base模式到底在传什么CameraLink Base配置包含一组Channel Link发送端把28bit并行数据转成4对LVDS数据差分对外加一对LVDS像素时钟总共5对差分信号。每对LVDS数据通道内部串行传输7bit数据4对加起来就是28bit。接收端拿到LVDS时钟后要以该像素时钟为基准去采样和恢复数据。像素时钟在20到85MHz之间每对LVDS数据的速率等于像素时钟乘以7。比如像素时钟85MHz时每对LVDS速率就是595Mbps4对合计2.38Gbps。同步信号包括FVAL帧有效、LVAL行有效、DVAL数据有效这些信号在CameraLink协议中通过XCTL控制线来传送。接收端有两种做法一种是用TI的DS90CR288A这类Channel Link接收芯片解串FPGA只需要读28bit并行数据和像素时钟实现简单另一种是FPGA直接接收LVDS用IBUFDS和ISERDESE2完成差分转单端和串并转换。工程源码里更推荐FPGA直接接收这样能省掉一颗接收芯片BOM成本低也方便后续调整电气参数。不过代价是需要自己做通道对齐这个内容等会儿放在数据通路设计部分细讲。2.2 GT Transceivers Wizard配置时容易搞错的三个点GT收发器配置是很多人第一次接触时最懵的地方。如果用Vivado里的GT Transceivers Wizard单独创建重点盯三件事线速率、参考时钟、GT类型。第一线速率必须和参考时钟在GT内部PLL的可分频范围内。以3.125Gbps线速率为例参考时钟常见选156.25MHz或125MHz。156.25MHz对应线速率除以20bit内部总线宽度是比较干净的整数关系推荐优先使用。实际板卡上晶振如果是125MHz只要PLL分频倍率支持也没问题但一定要去核对数据手册里的PLL范围不能只看“大概差不多的倍数”。第二GT类型要跟FPGA型号匹配。Artix-7用的是GTPKintex-7用GTXVirtex-7里还有GTH。不同GT类型支持的最高线速率差别很大工程配置时如果选错GT类型IP可能根本生成不了或生成后综合报错。3.125Gbps这个速率对GTP/GTX/GTH都轻松但换到10Gbps以上的场景就必须用GTH或GTY级别。第三参考时钟引脚必须是专用MRCC/SRCC引脚普通IO不能直接接到GT的refclk上。很多板卡布局阶段就把SFP座子和GT BANK关联好了但有的开发板会把参考时钟飞线到普通时钟引脚导致IP配置落不了位。拿到一块新板卡最先确认的就是refclk引脚位置和频率再决定IP参数怎么填。2.3 Aurora 8B10B的接口时序和流控模式怎么选Aurora 8B10B的用户侧接口是AXI4-Stream核心握手是tvalid和tready。发送端要等channel_up拉高tvalid才能拉高接收端则要保持m_axi_rx_tready拉高否则Aurora内核会暂停向上层交付数据。很多人第一次上板时程序卡在“数据发不出去”或“数据收不到”九成是没搞清楚valid和ready的配合关系。流控模式上Aurora 8B10B有Streaming和Framing两种。Framing模式带有tlast帧边界适合把每一行图像数据封装成一个frame接收端按帧解析逻辑上更清晰缺点是帧间隔、最大帧长需要按IP配置处理。Streaming模式则没有帧边界数据是连续流适合直接把整幅图像数据连续灌进去同步信号在自定义包头里自己定义。图像工程里两种模式都有人用。提到的CameraLink转SFP方案中我倾向于Streaming模式加自定义包头因为CameraLink的FVAL/LVAL/DVAL本来就是三根控制信号把它们打包到头部字段里接收端解析灵活也不受Framing模式最大负载限制。实际配置时Aurora IP向导里把Dataflow Mode选为DuplexFlow Control选StreamingUser K接口按需启用即可。3. 数据通路设计从CameraLink像素流到AXI-Stream3.1 接收端解串与同步信号恢复FPGA直接接收CameraLink时每个通道的LVDS数据和像素时钟都要进IBUFDS转成单端时钟通道接BUFG后作为像素时钟domain的全局时钟。数据通道通过ISERDESE2做串并转换4个通道会各自恢复出7bit数据拼起来就是28bit像素数据。难点在于通道对齐。CameraLink发送端的4个数据通道是并行发送的但经过PCB走线和连接器后各通道延迟不完全一致所以FPGA接收后需要把4个通道对齐到同一拍。常用做法是使用bit slip机制先让相机发送固定pattern比如0xAA/0x55交替数据然后在FPGA里逐通道调整bit slip直到4个通道读出来的pattern与期望值一致。这个校准状态机逻辑不多但必须保证在行消隐期或帧消隐期完成否则会打断正常图像数据。同步信号恢复也要重点处理。FVAL、LVAL、DVAL三个控制信号在CameraLink协议中通过XCTL0到XCTL3传送解串后要把它们单独拆出来。设计后续链路时这三个信号会和像素数据一起被并行打包进光纤帧接收端再根据包头恢复出一模一样的CameraLink时序。丢了同步信号接收端就算拿到像素也无从知道哪一行是行头、哪一帧是帧首。3.2 打包格式设计与32bit字结构打包格式是整个数据通路里最值得花心思的地方。我之前见过有人把28bit像素数据直接不经过处理就塞给Aurora的用户总线结果接收端完全无法区分行头帧头恢复时全靠猜。规范的做法是定义一套自定义帧格式发送端在数据流里周期插入包头接收端根据包头恢复同步信号。推荐的32bit字结构是这样的高28bit放像素数据低4bit放FVAL、LVAL、DVAL和备用控制位。这样每个用户时钟周期打一拍一个32bit字就是一组完整的CameraLink状态不需要额外像素缓冲区逻辑非常简洁。行同步、帧同步不再依赖单独信号线而是通过FVAL/LVAL/DVAL的状态组合来判断。具体行帧结构上可以按行打包每一行数据前面加一行头行头包含固定魔数比如0xA5A5A5A5、当前行号、这一行的数据和有效位计数。帧头可以复用行头加帧起始标志来实现。接收端一旦检测到行头就知道后续数据属于同一行直到LVAL变为无效且DVAL有效计数达到行长度再等待下一行头。这样即使个别bit发生错误也最多丢一行不会导致整帧花屏。3.3 FIFO深度计算与跨时钟处理CameraLink接收侧像素时钟和Aurora用户时钟是异步的必须经过异步FIFO过渡。写时钟是像素时钟读时钟是Aurora的用户时钟。以3.125Gbps线速率、32bit用户接口为例Aurora用户时钟是78.125MHz读带宽78.125MHz×32bit2.5Gbps写带宽是85MHz×28bit2.38Gbps所以理论平均读快于写FIFO不会持续增长。不过实际不能只看平均带宽还得看突发情况。相机在行有效期间连续输出像素行与行之间有消隐期像素时钟的突发长度可能比Aurora读侧瞬时处理能力更集中。如果FIFO太浅遇到Aurora的tready短暂拉低时仍然可能溢出。我实际工程里常用2048或4096深度的异步FIFO并增加almost_full信号当FIFO快满时暂停上游解串模块的写入。需要注意的是FIFO的写侧时钟是像素时钟域读侧时钟是Aurora用户时钟域复位也要分别异步复位、同步释放。FIFO位宽直接设为32bit读侧数据一路连到Aurora的s_axi_tx_tdata。Aurora的tvalid由发送状态机控制FIFO非空且channel_up拉高时允许传输。每传输一拍tvalid和tready同时拉高读指针前移如果tready拉低说明下游没准备好这一拍不能消耗FIFO数据。这一套握手逻辑不算复杂但一旦写错很容易出现图像花屏或者数据丢失调试时优先去抓这几个信号。4. 四套工程源码怎么用从回环测试到整链路移植4.1 四套工程源码的定位与差异提到四套工程源码很多人第一反应是“文件名里带个V1到V4”。实际上这四套源码是按功能角色划分的分别覆盖了发送、接收、验证、缓存四个关键场景。工程A是CameraLink Base转光口发送端核心模块包括LVDS接收、通道对齐、数据打包、异步FIFO、Aurora发送适合作为所有发送类项目的起点。工程B是光口转CameraLink接收端实现从Aurora接收数据、解析包头、恢复FVAL/LVAL/DVAL信号并用FPGA的LVDS发送能力还原CameraLink给后端设备用。工程C是光口自回环验证工程发送端产生递增测试数据经过Aurora发出去再收回来对收到的数据做逐拍比对专门用来验证光纤链路是否稳定。工程D是带DDR帧缓存的版本引入DDR3/DDR4缓存完整图像帧可以做格式转换、带宽整形、多路复用适合更高层的业务需求。实际调试时我建议第一次上手先把工程C跑通确认SFP光链路本身是好的再切换到工程A接收真实CameraLink相机图像。这样出了问题可以非常快速地把故障范围锁定在前端CameraLink还是后端光传输。4.2 工程目录结构与顶层模块划分一个规范的FPGA图传工程目录结构应该是清晰分层的。以这套源码为例顶层目录下会包含xdc约束目录、ip核目录、rtl源码目录、sim仿真目录和docs文档目录。rtl目录里核心模块包括lvds_rx做差分接收和ISERDESE2解串channel_align做bit slip通道对齐pack_fsm负责把像素数据和同步信号打包成帧fifo模块完成跨时钟域转换aurora_wrapper封装Aurora IP和用户接口握手。顶层top文件主要负责例化这些模块把引脚约束和IP信号连接起来。约束文件通常是两大部分。pin.xdc里放CameraLink差分对引脚、SFP引脚、参考时钟引脚的位置和电平标准timing.xdc里创建像素时钟的主时钟约束以及异步FIFO跨时钟域的相关约束。GT和Aurora IP的约束由Vivado在生成IP时自动带上不需要手动添加但位流生成前一定要检查是否有URCLK或IO相关警告。4.3 移植到新板卡的完整操作清单移植工程是使用这套源码最常用的场景。换一块新的FPGA板卡不一定需要从零改逻辑但必须按以下顺序检查。第一步确认FPGA具体型号和速度等级以及板卡上GTP/GTX/GTH资源分布。第二步打开Vivado里的Aurora IP核重新配置GT Reference Clock频率和线速率确保与板卡实际晶振和SFP光模块匹配。第三步检查refclk引脚是不是接在专用MRCC/SRCC上并修改xdc约束里的位置。第四步核对CameraLink的LVDS引脚所在的BANK电压是不是2.5VLVDS_25电平标准要求对应的BANK VCCIO必须匹配。第五步确认SFP座子的TX_DISABLE引脚是否已经拉低速率选择引脚是否固定到正确电平。第六步重新综合实现查看时序收敛情况尤其关注ISERDESE2和bit slip相关逻辑的时序余量。操作清单里最容易忽略的是光模块兼容性。普通SFP光模块在3.125Gbps下一般没问题但有些千兆模块只支持1.25Gbps插上去后Aurora初始化可能一直不成功。所以选型时要关注光模块速率等级明确是多模850nm还是单模1310nm收发两端的模块波长要配对。5. 调试实录光口不亮、误码高、花屏怎么排查5.1 上板前必须确认的硬件细节很多看起来是逻辑问题根因其实在硬件。光模块不发光是SFP图传项目里最典型的坑。SFP座子上的TX_DISABLE引脚如果悬空或者被拉高光模块的发射端会被强制关闭FPGA这边无论Aurora怎么初始化都只能看到RX侧无光信号。上电先拿万用表测一下SFP的TX_DISABLE引脚电平必须确认是低电平使能状态。参考时钟也必须在逻辑调试前验证。用示波器或者频率计实测晶振输出确认频率与Aurora IP配置一致。曾经有一个客户板卡原理图标注的是156.25MHz晶振实际贴完料后测出来是125MHz结果channel_up无论如何都起不来最后折腾了半天才发现是晶振贴错了。这种问题纯靠仿真和代码是查不出来的一定要从物理层排查。电源纹波同样值得关注。GT收发器对电源纹波很敏感MGTAVCC和MGTAVTT如果纹波过大误码率会明显上升。上板后可以先观察一下链路的硬错误计数若板卡风扇转动引起电源波动后误码飙升基本可以怀疑电源去耦不良需要检查供电模块的电容布局。5.2 光口不亮和误码高的排查方向光口不亮可以优先锁定在物理层。确认TX_DISABLE之后用光功率计打一下光纤发射端的出光功率看是否有光。多模模块正常出光功率通常在-6dBm到-3dBm之间如果完全没光说明光模块没工作如果有光但对端收不到可能是光纤RX/TX接反了SFP的RX和TX本身就是交叉连接的尤其使用跳线时方向弄反非常常见。channel_up无法拉起的另一个常见原因是GT参考时钟频率与线速率不匹配。Aurora IP里配置的refclk频率必须和实际硬件一致哪怕差一倍GT的PLL锁定不了channel_up永远拉不高。先检查频率计实测值再核对IP配置是这类问题最有效率的排查顺序。误码率高则要分两步看。第一步用IBERT眼图扫描判断物理层信号质量第二步看soft_err和hard_err计数器判断是偶发bit翻转还是链路失步。如果IBERT扫描结果显示眼宽眼高都很差多半是PCB走线、连接器焊接或电源纹波问题。如果眼图正常但Aurora报错则要把目光转向Aurora IP的复位顺序和时钟补偿配置。5.3 用IBERT和ILA快速定位链路问题IBERT是Xilinx自带的GT收发器测试功能用它可以直接扫RX眼图观察数据采样的眼高和眼宽。操作方法是在Vivado里加入IBERT IP核配置好线速率和参考时钟后在线工具里就能看到眼睛图。如果眼图张开度很好说明物理层没问题问题大概率在协议层或逻辑层。ILA主要用于逻辑层调试。建议在Aurora用户接口上添加ILA探针重点抓channel_up、lane_up、hard_err、soft_err、tvalid、tready和FIFO相关状态。第一次上板时直接看看channel_up上电后几毫秒内有没有拉高如果没有再回查GT状态信号和复位时序。还有一个细节是Aurora IP的复位信号必须在GT参考时钟稳定后释放如果复位释放太快初始化会反复失败表现为channel_up周期性拉高后又掉下来。最后分享一个调试习惯先跑回环工程再让CameraLink数据进来。先用递增测试数据验证链路无误码再切到真实图像数据看花屏问题。这样能把“光口本身通不通”和“图像数据对不对”两类问题彻底分开。很多朋友卡了好几天往往就是把这两类问题混在一起排查反而越查越乱。这个方案后续还可以继续扩展比如把CameraLink数据映射到AXI4-Stream后其实已经等于统一了传输格式后面再接PCIe、接USB、接以太网都只是换传输层而已。我在实际项目里的体会是高速图传最怕的不是协议复杂而是物理层和逻辑层定位混淆。把Aurora用熟把调试顺序固定成“物理层、协议层、业务层”三步走CameraLink转SFP这类项目做起来会顺手很多。
返回列表