ARTICLE DETAIL

资讯详情

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

CameraLink接口调试实战:OSERDES2/ISERDES2原语与时序约束详解

CameraLink接口调试实战:OSERDES2/ISERDES2原语与时序约束详解 如果你第一次调CameraLink接口大概率会遇到这样的场景功能仿真里数据对齐得整整齐齐可一上板图像要么整屏花掉要么出现固定规律的错位要么偶尔抖出几行噪点。代码逻辑看起来完全没问题问题出在哪多数情况下出在OSERDES2/ISERDES2原语的使用方式以及配套的时序约束与对齐策略上。这篇文章就围绕这两个原语展开把CameraLink调试过程中那些最容易踩坑的细节梳理一遍给正在跟Xilinx老器件Virtex-4/5、Spartan-3A等打交道的工程师还有所有被源同步接口对齐问题折磨过的人提供一条可以复用的排查路径。1. CameraLink接口到底快在哪里时序预算的底层逻辑1.1 物理层结构与7:1串行化CameraLink本质上是一种基于Channel Link技术的源同步串行接口。Base配置下它在一个连接器内使用4对LVDS数据线和1对LVDS时钟线发送端把24位图像数据加上FVAL、LVAL、DVAL、SPARE这4个控制信号总共28位按7:1的比例串行化到4条数据通道上。也就是说像素时钟PCLK每个周期会同时发送7个串行bit到每条通道上。串行数据速率等于像素时钟乘以7。举个例子PCLK为28MHz时串行速率是196Mbps单个bit的时间大约5.1nsPCLK到85MHz时串行速率就是595Mbpsbit窗口只有约1.68ns。对于FPGA板级设计来说500Mbps算不上特别高速但它带来的麻烦在于这是一对多的源同步接口数据和时钟是打包一起从外部进来的它们之间的相位关系在一个范围内变化而不是固定不变。1.2 为什么功能仿真会骗人功能仿真里data和pclk都是从理想模型出来的没有PCB走线延迟没有FPGA片内IO延迟也没有发送端芯片的Tco差异。仿真波形中数据边沿和时钟边沿永远满足建立保持时间ISERDES2采到的数据自然是对的。但真实世界里外部发送芯片输出的数据相对PCLK有一个Tco范围PCB上各条走线长度不可能完全一致FPGA内部从PAD到SERDES采样寄存器的路径也有延迟。如果这些误差叠加起来超过了一个bit窗口采样就会出错。更关键的是如果不给工具提供这些信息时序分析工具根本不会去分析这条路径它只会blindly按理想情况处理直到上板出问题才被发现。1.3 时序预算的核心公式计算CameraLink接收端时序核心是看数据位与时钟沿之间的关系。假设发送端芯片输出数据的时钟边沿对齐方式为center-aligned数据在时钟中间变化则接收端需要确保建立时间裕量 时钟到采样沿的时间 – 数据最晚到达时间保持时间裕量 数据最早到达时间 – 前一个时钟沿到采样沿的时间工程上简化表达Tsetup_margin Tbit - (Tco_max - Tco_min) - Tpcb_skew - Tskew_pcb_clk - Tsetup_fpga Thold_margin (Tco_min - Tco_max) Tpcb_skew_min - Thold_fpga Tcycle_adjustTbit是一个串行bit的周期Tco_max/Tco_min是发送芯片的时钟到输出延迟范围Tpcb_skew是数据线与时钟线之间的走线延迟差Tsetup_fpga/Thold_fpga是FPGA IO寄存器的建立保持时间要求。这些参数在CameraLink发送芯片的datasheet里都能查到。做时序约束时需要把上述参数换算成相对于PCLK的input delay这样工具才能自动检查setup/hold。这个换算方法后面章节会具体讲。2. OSERDES2/ISERDES2原语接口调试的第一现场2.1 为什么不能用普通IOB寄存器有人可能会问串行速率不到1Gbps直接在IOB上放寄存器按PCLK的上升沿采数据不就完了理论上讲如果数据率和时钟频率都很低确实可以这样做。但CameraLink是7:1串行如果直接采FPGA内部逻辑就必须工作在串行速率上而且每个通道要自己写移位寄存器来拼数据不仅浪费资源还会引入很大的时序不确定性。SERDES原语的价值在于它把高速串行数据和低速并行数据之间的转换直接在IO Tile内完成内部逻辑只需要工作在像素时钟或分频时钟上。以ISERDES2为例它接收外部高速串行数据在bit clock驱动下逐位移入然后并行输出一组数据供内部逻辑使用。OSERDES2则相反内部逻辑给出并行数据原语将其串行化后从单个引脚输出。2.2 ISERDES2的Bitslip机制ISERDES2最关键的功能之一就是Bitslip。它解决的问题很朴素外部数据流是一个连续的bit序列解串器需要知道从哪个bit开始作为一个并行字的边界。如果起点选错了并行输出里每个字节都是错位的看起来就是图像数据整体偏移。Bitslip的操作方式是给一个脉冲并行输出数据就循环移动一位。你可以把它理解成滑动窗口——每滑动一次尝试一种切分方式。对于CameraLink这类接口正确的字边界通常由发送端的同步信号LVAL或FVAL决定因此调试时可以发送一个固定pattern然后不断发Bitslip脉冲直到并行数据中能看到正确的同步信号位置。有个细节容易搞错DDR模式下Bitslip一次移动的是串行域的一个bit而不是并行域的一个bit。不同器件上Bitslip的生效时刻也有差异有些是异步立即生效有些要等下一个时钟沿。使用前必须翻对应的Series Architecture手册别凭经验想当然。2.3 原语例化的关键参数与时钟关系一个典型的ISERDES2例化需要注意以下参数ISERDES2 #( .DATA_WIDTH (7), // 并行数据宽度 .DATA_RATE (DDR), // 双沿采样 .BITSLIP_ENABLE (TRUE), // 启用Bitslip .SERDES_MODE (MASTER), // 主模式 .INTERFACE_TYPE (RETIMED) ) iserdes_inst ( .D (data_in_from_pad), .CE0 (1b1), .CLK (clk_bit), // 高速时钟 .CLKDIV (clk_div), // 分频时钟 .CLKDIVP (1b0), .OCE (1b1), .RST (rst), .BITSLIP (bitslip_ctrl), .Q (parallel_data) );这里最需要注意CLK和CLKDIV的关系。CLK是串行bit时钟CLKDIV是并行数据时钟一般要求CLKDIV频率等于CLK频率除以DATA_WIDTH。在CameraLink场景中CLK就是PCLK×7或PCLK×3.5取决于DDR还是SDRCLKDIV则是PCLK。这两路时钟不是随便接到BUFG上就完事的。高速bit时钟通常需要走BUFIO或BUFPLL这类专用时钟网络才能保证到各个SERDES的延迟一致性。如果图省事直接上BUFG高速时钟在片内走全局时钟树偏斜和抖动都会明显变大高速下很难稳定工作。OSERDES2的例化方向相反但时钟关系类似OSERDES2 #( .DATA_WIDTH (7), .DATA_RATE (DDR), .SERDES_MODE (MASTER), .OUTPUT_MODE (SINGLE_ENDED) ) oserdes_inst ( .D1 (tx_data[0]), .D2 (tx_data[1]), .D3 (tx_data[2]), .D4 (tx_data[3]), .D5 (tx_data[4]), .D6 (tx_data[5]), .D7 (tx_data[6]), .TQ (1b0), .CLK (clk_bit_tx), .CLKDIV (clk_div_tx), .OCE (1b1), .RST (rst), .Q (data_out_to_pad) );不同的DATA_WIDTH对应的输入引脚映射不同。比如DATA_WIDTH4时只使用D1~D4DATA_WIDTH6时使用D1~D6DATA_WIDTH8时使用D1~D8。具体哪个并行bit对应串行输出的第几位不同器件有细微差别建议每次都以官方数据手册的时序图为准。2.4 老器件原语与7系列的差异OSERDES2/ISERDES2是Virtex-4/5、Spartan-3A等器件的原语名称到了Virtex-6/Spartan-6变成OSERDESE1/ISERDESE17系列变成OSERDESE2/ISERDESE2。名称看起来差不多但参数和行为有差异项目ISERDES2ISERDESE1/2最大并行宽度88可拼接更宽Bitslip支持有有行为略有不同动态时钟分频选择无有DYNCLKDIVSEL接口类型部分支持网络更丰富如果你在维护老工程或从旧设计移植到新器件原语名称要改参数名称也要逐项核对不要简单粗暴地只改个名字。特别是7系列的ISERDESE2它引入了DYNCLKDIVSEL等新特性约束方式也有差异。3. 时序约束配置源同步接口的完整落地3.1 时钟约束从PCLK到内部时钟域时序约束的第一步是让工具认识所有时钟。CameraLink接收方向从PAD进来的PCLK是主时钟需要先约束NET pclk_p TNM_NET TNM_pclk; TIMESPEC TS_pclk PERIOD TNM_pclk 28.0 ns HIGH 50%;如果使用ISE中的UCF这样定义主时钟。PCLK经过IBUFDS后一般会走BUFPLL或BUFIO给SERDES提供bit时钟同时通过BUFPLL内部的CLKDIV输出作为并行数据时钟。这些由MMCM/PLL生成的时钟需要在约束中定义对应的生成时钟例如NET pll_inst/clkout1 TNM_NET TNM_clkdiv; TIMESPEC TS_clkdiv PERIOD TNM_clkdiv 28.0 ns HIGH 50%;关键是确保bit clock和div clock的频率关系被正确识别。如果使用的是VivadoSDC格式写法更直观create_clock -name pclk -period 28.0 [get_ports pclk_p] create_generated_clock -name clk_bit -source [get_pins mmcm_inst/CLKIN1] -divide_by 1 [get_pins mmcm_inst/CLKOUT0] create_generated_clock -name clk_div -source [get_pins mmcm_inst/CLKIN1] -divide_by 7 [get_pins mmcm_inst/CLKOUT1]3.2 输入延迟约束set_input_delay的换算方法对于源同步接口输入延迟描述的是数据相对于参考时钟沿的到达时间。以CameraLink接收为例假设发送芯片数据相对于PCLK是center-aligned即数据bit中心对准PCLK边沿。此时计算input delay的公式是max_input_delay Tco_max Tpcb_data_delay - Tpcb_clk_delay min_input_delay Tco_min Tpcb_data_delay - Tpcb_clk_delay如果时钟走线比数据走线长数据相对时钟会提前到达这个差值要体现在参数里。实际工程中PCB设计通常要求数据线和时钟线做等长处理误差控制在±50mil以内对应的时延差大约±8ps/mil。在SDC中set_input_delay -clock pclk -max [expr $Tco_max $Tpcb_skew] [get_ports data_in_*] set_input_delay -clock pclk -min [expr $Tco_min - $Tpcb_skew] [get_ports data_in_*]注意如果数据是DDR采样双沿input delay要分别对上升沿和下降沿定义。老式UCF也有OFFSET IN约束OFFSET IN 5.0 ns VALID 3.0 ns BEFORE pclk;意思是数据在pclk上升沿前3.0ns开始有效持续5.0ns。只要VALID窗口覆盖了时钟沿并且有足够余量就算满足要求。3.3 输出延迟约束与PLL相位补偿发送方向的OSERDES2同样需要约束。外部接收芯片对数据和时钟的相位关系有明确要求输出延迟描述的是FPGA输出数据相对输出时钟沿的延迟。set_output_delay -clock tx_pclk -max 2.0 [get_ports data_out_*] set_output_delay -clock tx_pclk -min -1.0 [get_ports data_out_*]这几个数值的物理含义是外部芯片从接收时钟沿到采样数据之间的时间预算。具体的max/min值要从CameraLink接收端芯片如DS90CR288A的datasheet中查。发送方向一个常见问题是FPGA内部逻辑输出的并行数据相对PLL生成的div clock是否满足建立保持时间。由于OSERDES2的输出路径从并行寄存器到串行输出中间存在固定延迟如果PLL相位没有做补偿可能出现内部逻辑时序收敛但外部输出采样失败的情况。此时可以在MMCM/PLL上做相位偏移调整或者设置set_output_delay时把PLL输出时钟的相位考虑进去。3.4 验证约束是否生效约束写完后必须确认时序分析工具真的分析了这些路径。ISE里可以查看Timing Report确认IO路径有对应的分析结果而不是出现unconstrained path这类字样。Vivado里同样查看report_timing_summary检查input/output delay约束是否被纳入。很多工程师在出现对齐问题时第一反应是怀疑逻辑写法实际上很可能是时序约束没有覆盖到工具根本没有检查接口路径。遇到奇奇怪怪的偶发误码先看timing report而不是反复改代码。4. 对齐实战从总线错位到单bit毛刺的排查链路4.1 字节对齐Bitslip到底该怎么滑上板后最常见的现象是图像整体错位比如每个像素都偏了几个bit颜色通道完全对不上。这种问题基本可以锁定为字边界不对。标准的调试方法发送端先输出一个已知pattern比如0x55、0xAA交替。上板后用ChipScope抓ISERDES2的并行输出。对比抓到的数据与预期pattern计算错位数。给Bitslip发脉冲每发一次抓一次数据直到并行输出与pattern一致。这个过程中有个效率技巧不要每次都人肉比对。如果发的是PRBS伪随机序列可以写一个小的逻辑判断模块自动比较并行数据与预期值找到第一个匹配点后停止滑动。CameraLink相机通常也有测试pattern输出功能可以配合使用。4.2 通道间偏移4路LVDS之间的skew怎么控制CameraLink Base配置有4条数据通道即使每路内部字节对齐了如果通道间出现过大的skew同样会导致并行数据合并时出现错位。channel-to-channel skew的来源主要有两个一是PCB走线长度差异二是FPGA内部不同IO Bank或不同SERDES的路径延迟差异。前者靠PCB等长设计控制后者需要在FPGA内部做补偿。典型现象单独的pattern测试每个通道都正确但把4路合并成28位数据时图像出现行错位——每行的开头偏移不同或者颜色分量错乱。这时要分别抓取每路的并行数据对比它们之间的相位关系。如果发现某一路总是比其他路慢一个串行bit可以在该路径上插入延迟单元如IDELAY或在逻辑中做循环移位修正。4.3 从错误现象反推原因我习惯先把错误现象归类再看对应原因现象可能原因排查优先级整幅图像固定偏移字边界错位、Bitslip没滑对先做字节对齐颜色通道错乱但轮廓清晰某个通道的并行bit顺序反了检查D映射关系偶发大量噪点建立保持时间不足、时序约束缺失查timing report图像行错位且抖动通道间skew超限分别抓各路数据对比整幅图像镜像或反色差分极性接反查原理图/万用表差分极性接反这个问题特别容易被忽略。LVDS每一条通道的P/N一旦接反采到的数据就不是简单错位而是完全乱码。如果刚上电就发现所有通道数据全部异常先别急着调代码拿示波器看下差分对的极性或者查一下原理图确认P/N有没有接错。4.4 用ChipScope/ILA观察哪些信号调试对齐问题时ChipScope上的观察点很关键。我一般会抓这几组每个通道的ISERDES2并行输出QBitslip控制信号脉冲内部的LVAL/FVAL/DVAL解析结果像素时钟域重组后的完整像素数据误码检测模块的error标志抓取时要注意ChipScope的采样时钟应该用CLKDIV像素时钟而不是bit clock。原因很简单bit clock频率太高ILA资源不够用且内部逻辑本来就在像素时钟域工作直接观测像素时钟域的信号更直观。如果你发现抓到的并行数据在ChipScope里看起来是乱的但实际逻辑里却是对的很可能是采样时钟选错了导致采样位置落在数据跳变沿附近。5. 容易翻车的几个细节位序、缓冲器与相位裕量5.1 并行输出位序D0到底对应哪个bitISERDES2的并行输出Q[7:0]与串行输入D的bit对应关系不同器件可能不同。有的器件D0对应并行输出的最低位有的是最高位甚至不同DATA_WIDTH下映射规律还会变化。如果代码里把Q直接当成像素数据使用位序反了图像会出现类似位反转的花屏。我在实际项目中就吃过这个亏同一个工程从Spartan-3A迁移到Virtex-5原语参数几乎一致但并行输出的位序变了图像花了整整一天才排查出来。后来每换一个器件型号我都会先在文档里确认位序映射图再决定是否需要在逻辑里做bit重排。5.2 时钟缓冲器的选择BUFIO/BUFPLL vs BUFGSERDES的高速时钟必须走专用时钟资源这一点我在前面提过值得再强调一次。BUFG是全局时钟缓冲它能覆盖整个芯片但延迟和抖动相对较大而且各处的偏斜可能在几百ps量级。对于1Gbps以下的串行信号几百ps听起来不多但对应到bit窗口可能已经占掉20%-30%了再加上其他误差很容易把建立保持裕量吃光。BUFIO是IO时钟缓冲直接从IO Bank的时钟引脚驱动该Bank的IO寄存器延迟极小是专门为高速IO设计的。BUFPLL则能把PLL输出同时接到BUFIO和内部逻辑适合需要同时提供bit clock和div clock的场景。CameraLink的接收方向标准做法就是PCLK进IBUFDS后接BUFPLL由其产生bit clock和div clock。5.3 手动调延迟的诱惑与风险上板调试时很多工程师会用IDELAY或PLL相位一点一点手动调整直到误码消失。这种方法短期内可能奏效尤其在实验室环境温度稳定的情况下。但隐患在于你只是在凑一个能工作的点而不是保证整个时序窗口内都能工作。一旦温度变化、电源波动或更换了一块PCB工作点偏移误码就可能卷土重来。正确的做法是用时序分析工具报告确认setup和hold都有正裕量最好再留出至少几十ps的margin。如果发现某个延迟参数调一点就完全翻转从全对变成全错说明已经工作在窗口边缘需要重新检查约束逻辑而不是继续加大延迟值。5.4 跨时钟域处理的隐性坑ISERDES2输出的并行数据虽然在CLKDIV时钟域但这个时钟是直接从PCLK分频下来的与FPGA内部其他逻辑的主时钟比如图像处理模块的100MHz或150MHz时钟是异步关系。直接把并行数据送进另一个时钟域的FIFO或寄存器存在亚稳态风险。很多调试难题表面上看是SERDES对齐问题实际是跨时钟域没有做好。比如图像偶尔出现单帧花屏抓了很久没找到规律最后发现是输入数据跨时钟域时没有加异步FIFO或双寄存器同步。这个问题在接口调试阶段容易被ChipScope抓到正确数据而忽略因为ChipScope采样本身也在CLKDIV域掩盖了后续跨时钟域的不确定性。等图像处理链路变长问题才暴露出来。我在实际项目里通常会在ISERDES2输出后立刻加一个异步FIFO把像素时钟域的数据转换到内部处理时钟域。FIFO空满标志作为同步状态机的一部分。这样既解决了跨时钟域问题也自然处理了像素时钟暂停或抖动带来的数据流间隙。CameraLink相机在采集开始时会有几行无效数据用FIFO 同步状态机过滤效果很稳定。5.5 复位信号的同步处理还要说说复位。ISERDES2和OSERDES2的RST端口在使用时必须注意它应该是异步复位、同步释放的脉冲信号并且至少要保持几个CLKDIV周期。不少工程师直接把系统复位信号接过来或者用简单打两拍的方式在高速源同步接口场景下容易出现复位释放时的亚稳态导致SERDES初始状态不对进而出现偶发性的第一帧数据错位。我建议为SERDES单独生成一个复位信号由像素时钟域产生宽度至少为4个CLKDIV周期并且用CLKDIV时钟做同步释放。这样每次上电或重新配置后SERDES的状态是确定可预期的不会因为复位时序问题引入额外变量。调试时也方便手动触发快速复现问题。写在最后的个人体会CameraLink加上OSERDES2/ISERDES2这套组合技术本身不算特别难但调试过程很考验对时序本质的理解。我见过太多项目卡在对齐问题上最后靠玄学调参蒙混过关然后等下一批板子回来又翻车。与其这样不如把时序约束、位序映射、时钟网络这些底层细节一次性弄清楚。调好一个接口后面再碰到类似的源同步接口都能举一反三。留个习惯每次上板验证前先花10分钟看一眼timing report里的IO路径确认它不是unconstrained再谈图像对不对。这个小习惯能帮你省下几个通宵。
返回列表