ARTICLE DETAIL

资讯详情

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

FPGA实现MIPI DPHY接收:从硬件设计到协议解析的完整指南

FPGA实现MIPI DPHY接收:从硬件设计到协议解析的完整指南 MIPI DPHY这个接口做图像和显示方向的人迟早都得碰。我最早接触它是在一个多摄像头采集项目上当时用Xilinx的Artix-7接一颗MIPI摄像头本以为照着UG文档配一下SelectIO就完事结果从硬件差分走线到IDELAY校准再到协议解析前前后后折腾了快三周才把第一帧图像稳定地抓出来。这篇文章就把这套流程完整拆开讲一遍——从硬件设计里那些容易翻车的地方到FPGA内部怎么用原语把高速差分信号收进来再到软件侧怎么把包解析成像素。适合已经会写Verilog、用过Vivado但还没碰过MIPI DPHY的工程师参考。1. 先搞清楚MIPI DPHY到底在FPGA里扮演什么角色1.1 DPHY只是物理层别把它和CSI/DSI混为一谈很多人一上来就说我要用FPGA实现MIPI其实这句话本身是模糊的。MIPI是一个很大的规范族DPHYD-PHY只是其中最底层的物理层协议它规定了差分信号的电气特性、时钟通道和数据通道的时序关系、以及高速HS和低功耗LP两种传输模式。而CSI-2和DSI是建立在DPHY之上的上层协议分别管摄像头和显示屏的数据包格式。所以当你说FPGA实现MIPI DPHY接口准确的含义是FPGA要能正确接收或发送DPHY规定的差分电平信号恢复出时钟并把串行的比特流对齐成字节交给上层做CSI-2或DSI的包解析。这三层是分开的硬件设计主要管物理层FPGA逻辑管比特对齐和字节恢复软件管包解析。理解这个分层非常关键因为它决定了你排查问题时该往哪一层看。图像出不来可能是差分线阻抗不对物理层可能是IDELAY没校准好导致比特错位链路层也可能是CSI-2的包长字段解析错了协议层。分层清楚了排查才有方向。1.2 为什么Xilinx FPGA适合干这件事Xilinx 7系列及以后的FPGASelectIO资源里自带ISERDESE2和IDELAYE2这些原语天生就是为高速源同步接口准备的。ISERDESE2可以把高速串行数据做1:4、1:8的串并转换IDELAYE2可以对每个比特做精细的延迟调整这两样东西加起来就构成了一个软件可调的DPHY接收前端。相比专用桥接芯片比如一些MIPI转并口的芯片用FPGA直接收的好处是灵活——通道数可以自己定数据可以直接进逻辑做处理不用再经过一层外部芯片引入额外延迟和成本。代价就是你要自己处理校准和时序工作量不小。我个人的经验是如果只是单纯想把MIPI转成并口给后端用桥接芯片更省事但如果要在FPGA里直接做图像处理、多路合并、或者需要精确的时间戳那FPGA直收是唯一合理的选择。1.3 一个典型的应用场景拆解拿我做过的一个四路摄像头采集板举例。四颗MIPI摄像头每颗一路时钟通道加两路数据通道DPHY的lane总共12对差分线进FPGA。FPGA内部对每路数据通道做ISERDES解串恢复出字节流然后四路CSI-2解析模块并行工作把YUV数据写进DDR。整个链路里DPHY接收前端是最容易出问题的一环因为它直接面对的是几百Mbps到1Gbps以上的差分信号任何一点阻抗不连续或者延迟没校准好都会导致误码。这个场景里硬件设计决定了信号质量的上限FPGA逻辑决定了你能不能把这个上限发挥出来。两者缺一不可这也是为什么这篇文章要把硬件和软件放在一起讲。2. 硬件设计阶段差分走线和电平匹配的坑2.1 DPHY的电气特性决定了布线规则DPHY的HS模式是低压差分信号共模电压大约200mV差分摆幅100mV到300mV左右速率从80Mbps到每lane 2.5Gbps不同版本规范上限不同。LP模式则是单端信号电平在0到1.2V之间。这两种模式共用同一对差分线靠线上的电平状态来切换。这个特性直接决定了布线要求差分阻抗必须控制在100欧姆±10%差分对内两根线的长度差要控制在5mil以内否则共模抑制会变差HS模式下误码率会飙升。我见过一块板子因为对内长度差了15mil结果在800Mbps以上就开始间歇性丢帧降到400Mbps才勉强稳定。后来重新绕线把长度差压到3mil问题立刻消失。另外DPHY的走线要尽量短尤其是时钟通道。时钟通道的抖动会直接传递到数据采样上走线越长引入的抖动和损耗越大。一般建议时钟和数据通道的走线长度差控制在合理范围内具体数值要看你的速率速率越高要求越严。2.2 端接和共模电压的处理DPHY接收端通常需要外部提供共模电压偏置。有些FPGA的HP bank支持内部差分端接DIFF_TERM但DPHY的共模电压比较低直接用内部端接可能不匹配。我的做法是在靠近FPGA引脚的地方加一对电阻做端接同时用电阻分压网络把共模电压拉到合适的位置。这里有个容易忽略的点LP模式下的电平是0到1.2V而FPGA的HP bank VCCO通常是1.8V或1.5V。如果你的bank电压设成1.8VLP信号的高电平1.2V可能识别不稳。所以接收LP信号的引脚bank电压最好设成1.2V或者用支持1.2V标准的bank。这一点在选引脚的时候就要规划好不能等PCB画完了才发现bank电压不对。2.3 电源和参考时钟的干净程度DPHY对电源噪声很敏感尤其是HS模式下的共模电压只有200mV电源上稍微有点纹波就可能淹没有效信号。我的经验是给MIPI接收相关的bank单独做电源滤波用磁珠加电容的方式隔离电容要选低ESR的靠近引脚放置。参考时钟方面如果你的FPGA逻辑里要用到IDELAYCTRL它需要一个参考时钟通常200MHz或300MHz这个时钟的抖动要尽可能低。我一般用专用的时钟输入引脚接一个有源晶振而不是从普通IO分频出来因为分频出来的时钟抖动大会直接影响IDELAY的精度。2.4 硬件设计检查清单在投板之前我习惯按下面这张表逐项过一遍能省掉很多返工检查项要求常见错误差分阻抗100欧姆±10%叠层没算对实际90或110对内长度差小于5mil绕线时没对齐通道间长度差尽量小按速率定时钟和数据差太多共模电压按DPHY规范偏置忘记加偏置网络Bank电压匹配LP电平用了1.8V导致LP识别不稳电源滤波单独滤波隔离和数字电源混在一起参考时钟低抖动有源晶振用普通IO分频这张表看着简单但每一条我都踩过或者见别人踩过。尤其是bank电压那条很多人画完板子才发现LP信号识别不了只能飞线改电压非常麻烦。3. FPGA逻辑侧用ISERDES和IDELAY搭接收前端3.1 ISERDESE2的工作模式和位宽选择ISERDESE2是Xilinx 7系列里做高速解串的核心原语。它支持SDR和DDR两种模式位宽可以配成2、3、4、5、6、7、8。对于DPHY接收我们通常用DDR模式因为DPHY在HS模式下是双沿采样时钟的上升沿和下降沿都传数据。位宽的选择要看你的速率和FPGA能跑的逻辑时钟频率。假设你的lane速率是800Mbps用DDR模式那么采样时钟是400MHz。如果你选8位宽逻辑侧的输出时钟就是400/4100MHz因为DDR下8位需要4个时钟周期来串出这个频率对FPGA逻辑来说很轻松。如果选4位宽逻辑时钟就是200MHz稍微高一点但也能接受。我的建议是优先选8位宽把逻辑时钟压下来给后面的处理留更多时序余量。代价是占用更多的ISERDES资源但对于大多数项目来说这不是瓶颈。3.2 IDELAYE2的校准逻辑IDELAYE2用来对输入信号做精细延迟调整步进精度和参考时钟有关。用200MHz参考时钟时每个tap大约是78ps。DPHY的一个比特周期在800Mbps下是1250ps所以理论上你需要找到那个采样点最稳的tap值。校准的思路是这样的先让IDELAY从0开始逐步增加同时用一个已知的测试图案比如固定的0xAA或0x55去比对接收到的数据。当接收数据开始正确时记下这个tap值继续增加直到数据开始出错再记下这个tap值。这两个值的中间就是最佳采样点。实际操作中我会写一个状态机自动跑这个过程把每个lane的最佳tap值存到寄存器里。这样每次上电都能自动校准不用手动调。这个自动校准逻辑是整个接收前端里最值得花时间打磨的部分因为它是稳定性的基础。3.3 时钟通道和数据通道的对齐DPHY的时钟通道和数据通道是分开的时钟通道提供采样时钟数据通道传数据。但时钟和数据之间会有相位差这个相位差在PCB上由走线长度决定在FPGA内部还会受到时钟树延迟的影响。处理方法是时钟通道也经过一个IDELAY或者用MMCM做相位调整然后去采样数据通道。对齐的目标是让采样时钟的边沿落在数据眼图的中心。这个过程和IDELAY校准是耦合的通常先粗调时钟相位再细调每个数据lane的IDELAY。我一般会先用MMCM把时钟相位调到大致居中然后用IDELAY做精细调整。如果时钟和数据走线长度控制得好这个调整范围不会很大如果走线差得多可能需要MMCM做较大范围的相位移动。3.4 一段可参考的接收逻辑框架下面这段代码是接收前端的骨架展示了ISERDES和IDELAY的例化方式。实际项目中还需要加上校准状态机和错误统计但框架是这样的// 单个lane的接收前端 IDELAYE2 #( .IDELAY_TYPE(VAR_LOAD), .IDELAY_VALUE(0), .REFCLK_FREQUENCY(200.0), .DELAY_SRC(IDATAIN) ) u_idelay ( .IDATAIN(data_in_p), // 来自IBUFDS的差分输入 .DATAOUT(data_delayed), .CNTVALUEIN(tap_value), // 校准得到的tap值 .LD(load_tap), .C(ref_clk), .CE(1b0), .INC(1b0), .RST(reset) ); ISERDESE2 #( .DATA_RATE(DDR), .DATA_WIDTH(8), .INTERFACE_TYPE(NETWORKING), .IOBDELAY(IFD) ) u_iserdese ( .D(data_delayed), .DDLY(data_delayed), .CLK(div_clk), // 逻辑侧时钟 .CLKB(~div_clk), .CLKDIV(div_clk), .RST(reset), .Q1(q1), .Q2(q2), .Q3(q3), .Q4(q4), .Q5(q5), .Q6(q6), .Q7(q7), .Q8(q8) );这段代码里tap_value就是校准状态机算出来的最佳延迟值。div_clk是MMCM分频出来的逻辑时钟。实际使用时要根据你的具体速率和器件型号调整参数。4. 从比特流到字节DPHY的协议解析细节4.1 HS和LP模式的切换检测DPHY在传输数据前会先进入HS模式传输结束后回到LP模式。FPGA需要能检测这个切换否则会把LP状态的信号误当成数据。检测的方法是看差分线上的共模电平LP模式下共模电平高HS模式下共模电平低。实际实现时可以用一个比较器或者FPGA内部的LVDS输入缓冲来检测。当检测到HS模式后启动ISERDES开始采样检测到回到LP模式后停止采样并复位解串逻辑。这个切换检测的响应速度要快否则会丢掉HS模式开始时的同步序列。4.2 同步序列和字节对齐DPHY在HS模式开始时会先发送一段同步序列Sync Sequence通常是0x0000B8或者类似的图案。FPGA收到这段序列后用它来做字节对齐——因为ISERDES输出的是8位数据但哪一位是字节的起始位是不确定的需要用同步序列来定位。对齐的方法是把ISERDES输出的8位数据做循环移位直到匹配上同步序列。匹配上之后记录下移位量后续所有数据都按这个移位量对齐。这个过程每个lane都要做一次因为每个lane的延迟可能不同。4.3 CSI-2包结构的解析字节对齐之后数据流就是CSI-2的包了。CSI-2的包结构是包头4字节包含数据类型和长度、数据载荷、包尾2字节的CRC。解析的时候先读包头根据数据类型判断这是图像数据还是控制信息然后按长度读取载荷最后校验CRC。这里有个细节CSI-2的短包和长包格式不同。短包只有包头和包尾没有载荷用来传帧同步、行同步这些信息。长包才有载荷用来传实际的图像数据。解析逻辑要能区分这两种包否则会把短包当成空的长包处理。4.4 一个常见的解析错误我踩过的一个坑是CSI-2的长度字段是16位但字节序是低字节在前。我一开始按高字节在前解析结果长度算出来完全不对图像数据全乱了。后来对着规范仔细看才发现字节序的问题。这种细节在规范里写得很清楚但如果不仔细看很容易忽略。另一个坑是CRC校验。CSI-2的CRC用的是特定的多项式不是标准的CRC32。如果你用通用的CRC模块去校验永远校验不过。这个多项式在CSI-2规范里有明确定义实现的时候要照着写。5. 调试与验证怎么知道问题出在哪一层5.1 用ILA抓信号的基本方法Vivado的ILA是调试这类接口的利器。我的做法是在几个关键节点插ILAISERDES的原始输出、字节对齐后的数据、CSI-2解析后的包头。这样一旦出问题可以逐级往上看定位到是哪一层出的错。抓ILA的时候要注意采样深度和触发条件。DPHY的数据速率高ILA的采样时钟如果跟不上抓到的数据会失真。我一般用逻辑侧的时钟100MHz左右去采这个频率下ILA能稳定工作。触发条件设成收到包头或者CRC错误这样能精准抓到出问题的时刻。5.2 误码率的统计和判断判断链路是否稳定的一个量化指标是误码率。我的做法是在FPGA里加一个误码统计模块用已知的测试图案比如PRBS去比对接收数据统计错误比特数。如果误码率在1e-12以下基本可以认为链路是稳的如果高于1e-9说明还有问题需要调。误码率高的常见原因有三个IDELAY没校准好、差分信号质量差、参考时钟抖动大。排查的时候先看IDELAY的校准结果是否落在合理范围再看硬件信号质量最后查时钟。5.3 分层排查的完整链路下面这张表是我总结的分层排查思路从现象反推问题所在层现象可能的问题层排查方向完全收不到数据物理层差分线是否接对、bank电压、电源数据间歇性错误链路层IDELAY校准、时钟相位包头正确但载荷错协议层长度字段、字节序CRC校验失败协议层CRC多项式、对齐图像有条纹链路层或协议层逐lane检查、包解析这张表在实际调试中帮我省了很多时间。每次遇到问题先对照现象定位到层再往那个方向查比盲目试要高效得多。6. 几个让我印象深刻的实操教训6.1 别忽视LP模式的信号完整性很多人把注意力全放在HS模式上觉得LP模式速率低不用管。但实际上LP模式的信号如果质量差会导致模式切换检测出错进而影响HS模式的启动。我遇到过一块板子LP信号的上升沿太缓导致模式切换检测延迟HS模式的前几个字节被丢掉了。后来在LP信号线上加了个小电容加速边沿问题解决。6.2 校准逻辑要考虑温度漂移IDELAY的最佳tap值会随温度变化。如果你的设备工作环境温度变化大上电时校准一次可能不够。我的做法是在逻辑里加一个周期性的重新校准比如每隔几秒重新跑一次校准状态机把新的tap值更新进去。这样即使温度漂移链路也能保持稳定。6.3 多lane之间的偏斜要控制多lane的DPHYlane与lane之间会有偏斜skew。如果偏斜太大即使每个lane单独都对齐了合并成完整数据时还是会错位。处理方法是在每个lane的接收前端加一个小的FIFO用统一的时钟读出把偏斜吸收掉。FIFO的深度根据最大偏斜量来定一般几个字节就够了。6.4 参考时钟的选择影响很大前面提过参考时钟要低抖动这里再强调一次。我试过用普通IO分频出来的时钟做IDELAYCTRL的参考结果校准出来的tap值抖动很大链路时好时坏。换成专用时钟引脚接有源晶振后tap值非常稳定。这个改动成本很低但效果立竿见影。7. 从能收到能稳定收性能优化的几个方向7.1 提高采样余量的方法采样余量决定了链路对抖动的容忍度。提高余量的方法有几个一是优化IDELAY校准算法找到眼图真正的中心而不是边缘二是用MMCM做更精细的相位调整三是改善硬件信号质量减小抖动。我一般会先确保硬件信号质量达标然后在逻辑侧做精细校准。校准算法上我会多采几组数据做平均避免单次校准的偶然误差。7.2 资源占用的权衡ISERDES和IDELAY都是有限资源。如果你的lane数很多资源可能不够用。这时候可以考虑用更少的ISERDES位宽比如4位而不是8位代价是逻辑时钟频率要提高。或者用时间复用的方式多个lane共享一套解串逻辑但这样会增加控制复杂度。我的经验是对于四路以下的lane直接用8位宽最省心超过四路就要算一下资源必要时做权衡。7.3 功耗和散热的考虑高速接口的功耗不低尤其是多lane同时工作的时候。FPGA的功耗上去之后温度升高又会影响IDELAY的稳定性形成恶性循环。所以散热设计也要考虑进去该加散热片就加该留风道就留。我在一个密闭机箱的项目里就吃过这个亏夏天的时候链路开始不稳定查了半天发现是温度太高导致校准值漂移。后来加了风扇强制散热问题解决。8. 写在最后的一点个人体会这套MIPI DPHY接收方案我从最早的磕磕绊绊到后来能比较顺畅地跑通核心的转折点是想明白了分层这件事。硬件、链路、协议三层各管各的出了问题先定位到层再往那个方向查效率比盲目试高太多。另外就是校准逻辑值得多花时间。很多人觉得校准就是个简单的状态机随便写写就行但实际上校准的质量直接决定了链路的稳定性。我在校准上花的调试时间大概占了整个项目的三分之一但事后看是值得的因为后面再也没为链路稳定性操过心。如果你也在做类似的项目建议先把硬件设计检查清单过一遍把信号质量的基础打牢然后再在逻辑侧做精细校准。基础不牢的话逻辑侧再怎么调也是事倍功半。
返回列表