ARTICLE DETAIL

资讯详情

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

Lattice FPGA HSB相机方案实战:从架构到上板调试

Lattice FPGA HSB相机方案实战:从架构到上板调试 1. 为什么要在Lattice平台上折腾HSB相机方案如果你手头有一块Lattice的FPGA开发板又恰好需要接一个摄像头做图像采集那HSBHigh-Speed Bridge高速桥接相机方案大概率是你绕不开的一条路。我最初接触这个方案是因为一个工业检测的小项目客户要求用低成本FPGA实现CMOS传感器的实时采集和显示分辨率不用太高但帧率要稳延迟要低。选来选去Lattice的ECP5和CrossLink系列在功耗和价格上都有优势而HSB恰好是Lattice官方推的一套高速接口桥接参考设计专门用来对接MIPI CSI-2或者DVP并口的摄像头。说白了HSB相机方案解决的核心问题是FPGA的通用IO怎么稳定地接收高速并行或差分图像数据并把它转换成内部逻辑能处理的像素流。很多人第一反应是直接用DVP并口接几根数据线加行场同步就完事了。但实际跑起来你会发现当像素时钟超过100MHz或者走线稍微长一点数据眼图就惨不忍睹采样位置稍微偏一点就出花屏。HSB的思路是用Lattice器件里内置的硬核或者软核来实现高速串并转换和训练对齐把时序余量做大让系统在温度变化和电压波动下也能稳住。这套方案适合谁呢我觉得有三类人值得花时间研究一是做机器视觉前端采集的嵌入式工程师二是玩FPGA图像处理的学生和爱好者三是需要给自家传感器模组做快速原型的硬件产品经理。你不需要对Lattice的整套开发流程了如指掌但至少得会用Diamond或者Radiant建工程、跑综合、下板子验证。如果你连约束文件都没写过那建议先补一下时序约束的基础不然HSB里的那些训练逻辑会让你一头雾水。我见过不少人一上来就问“有没有现成的bit流直接烧”说实话HSB方案的价值不在于一个能跑的bit而在于它提供了一套可配置的参考架构让你根据自己摄像头的时序参数去调整。不同厂家的传感器HSB的配置差异很大直接抄别人的参数大概率跑不通。所以这篇文章我会从方案选型、时钟架构、训练逻辑、调试手段几个角度把我在实际项目里踩过的坑和总结的经验摊开来讲尽量让你少走弯路。2. HSB方案的核心架构与Lattice器件的匹配逻辑2.1 HSB到底桥接了什么先把这个概念理清楚。HSB在Lattice的语境里通常指的是一组参考设计用来把外部高速信号比如MIPI D-PHY的差分对或者高速并口通过FPGA的专用IO资源接收进来然后转换成内部并行像素总线。它不是一个单一的IP核而是一套包含物理层接收、时钟恢复、字对齐、通道绑定等功能的逻辑集合。你可以把它理解成一座桥桥的一头是摄像头输出的高速串行或源同步信号另一头是FPGA内部相对低速但稳定的像素时钟域。为什么需要这座桥因为摄像头输出的数据速率往往远高于FPGA内部逻辑能直接处理的频率。比如一个1080p60的传感器MIPI每条lane的速率可能到800Mbps以上你不可能让FPGA的逻辑阵列直接跑在这个频率上。HSB的做法是利用器件里的SERDES或者DDR输入寄存器先把高速数据降速成并行字再交给后续的像素处理流水线。这个降速过程就是串并转换而HSB负责保证转换后的数据边界对齐、通道之间不 skew。2.2 ECP5和CrossLink的IO资源差异Lattice的FPGA产品线里适合做相机桥接的主要是ECP5、CrossLink和CrossLink-NX。ECP5的通用IO支持DDR输入最高能跑到大概400MHz的时钟频率配合SERDES可以处理更高线速率。CrossLink系列则更偏向于MIPI硬核它内置了D-PHY的接收器可以直接对接MIPI CSI-2的差分信号不需要外部分立电阻网络。CrossLink-NX在此基础上增加了更多的逻辑资源和更灵活的IO配置。选型的时候你得先看摄像头输出的是什么接口。如果是DVP并口ECP5的通用IO加DDR输入就够了成本也低。如果是MIPI CSI-2那CrossLink或者CrossLink-NX的硬核D-PHY会省事很多因为硬核已经帮你处理了差分信号的接收和电平转换你只需要配置lane数和速率。我个人的经验是如果项目对功耗和尺寸敏感比如内窥镜或者小型无人机上的相机模块CrossLink-NX是首选如果是工业相机或者开发板验证ECP5的灵活性和生态更成熟。2.3 参考设计的目录结构里藏着什么Lattice官方提供的HSB参考设计解压之后你会看到几个关键目录一个是RTL源码里面包含了物理层接收模块、时钟域交叉模块和像素打包模块另一个是约束文件模板里面预置了输入延迟和输出延迟的约束示例还有一个是仿真测试平台用来验证训练逻辑的正确性。很多人拿到参考设计直接打开顶层文件就开始改结果改到一半发现时钟约束没跟上综合出来的时序报告一片红。我的建议是先把仿真跑通。参考设计里的测试平台会模拟摄像头输出的训练码流你可以观察字对齐状态机是怎么从搜索状态跳到锁定状态的。把这个过程看明白了再去改RTL或者约束心里就有底了。另外约束文件里的set_input_delay和set_output_delay不是随便填的它们需要根据你PCB上的走线长度和摄像头输出时序来计算。这个计算过程我后面会专门讲。2.4 为什么HSB方案对时钟质量如此敏感高速接口的命门就是时钟。HSB方案里通常有两种时钟架构一种是源同步摄像头随数据一起发一个时钟FPGA用这个时钟去采样数据另一种是系统同步FPGA自己产生一个参考时钟通过训练序列来恢复数据相位。无论哪种时钟的抖动和偏斜都会直接吃掉数据眼图的余量。我在一个项目里遇到过这样的情况摄像头模组输出的像素时钟是148.5MHzPCB走线大概8厘米没有做阻抗控制。结果HSB训练能锁定但跑几分钟后开始间歇性丢帧。用示波器一测发现时钟线上的过冲和振铃很严重导致采样点漂移。后来在时钟线上串了一个22欧姆的电阻问题就消失了。这个例子说明HSB的逻辑再健壮也扛不住物理层的信号完整性问题。所以在layout阶段差分对要等长单端时钟线要包地这些基本功不能省。3. 从Diamond工程到上板跑通我的实操步骤拆解3.1 工程创建与器件选型打开Lattice Diamond新建工程器件选型这一步别选错。ECP5系列里LFE5U-25F和LFE5U-45F是常用的两个型号后者逻辑资源更多适合做图像缓存或者简单的ISP处理。如果你用的是CrossLink-NX那就得用Radiant而不是Diamond这两个开发环境不通用。我刚开始的时候在Diamond里找了半天CrossLink-NX的器件后来才发现得换工具。工程建好之后把HSB参考设计的RTL文件导入。注意参考设计里可能包含多个顶层文件对应不同的接口模式。比如hsb_dvp_top.v和hsb_mipi_top.v你得根据实际摄像头接口选一个作为顶层。选错了综合能过但上板肯定没反应。我建议在工程里建两个配置一个用于仿真一个用于综合这样切换起来方便。3.2 时钟约束的写法与计算时钟约束是HSB工程里最容易出错的地方。以DVP并口为例摄像头输出一个像素时钟pclk假设频率是74.25MHz那么周期就是13.468纳秒。在约束文件里你需要这样写create_clock -name pclk -period 13.468 [get_ports pclk_in]但这只是第一步。因为数据是在pclk的边沿输出的FPGA内部用同一个时钟去采样所以还需要设置输入延迟。输入延迟的计算取决于摄像头输出数据的有效窗口和PCB走线延迟。一般来说摄像头手册会给出tSU和tH参数比如tSU2nstH1.5ns。那么输入延迟的最大值和最小值可以这样估算最大输入延迟 时钟周期 - tSU 13.468 - 2 11.468 ns最小输入延迟 tH 1.5 ns然后在约束里写set_input_delay -clock pclk -max 11.468 [get_ports data_in*] set_input_delay -clock pclk -min 1.5 [get_ports data_in*]这还没算PCB走线的影响。如果数据线和时钟线的走线长度不一致每厘米大约引入60到70皮秒的延迟。假设数据线比时钟线长2厘米那就要在最大和最小延迟上各加约0.13纳秒。这些细节看起来繁琐但正是它们决定了你的采样窗口是否居中。3.3 训练状态机的观察与调试HSB方案里通常包含一个训练状态机用来搜索数据字边界。以MIPI为例传感器会先发送一段连续的训练码型HSB的逻辑通过滑动窗口搜索特定的同步字找到之后就把字对齐位置固定下来。调试的时候你可以把状态机的状态输出到LED或者ILA如果器件支持上观察。我用ECP5的时候因为逻辑资源有限没法塞进一个完整的ILA就用了一个笨办法把状态机的几个关键状态位映射到开发板上的LED。比如LED0亮表示搜索中LED1亮表示已锁定LED2亮表示错误。上板之后一看LED1常亮说明训练成功了。如果LED0一直闪烁那就要检查训练码型是否匹配或者时钟频率是否在允许范围内。还有一个坑是训练码型的位宽。有些传感器的训练码是8位对齐的有些是10位或者12位。HSB参考设计里默认可能是8位如果你用的传感器输出10位像素那就得改状态机里的比较逻辑。我遇到过一次训练死活锁不上后来发现是参考设计里的同步字是0xAA而我的传感器发的是0x55改一下比较值就解决了。3.4 像素数据的打包与跨时钟域处理训练锁定之后HSB会把接收到的串行数据转换成并行像素。这里涉及一个跨时钟域的问题接收端用的是恢复出来的时钟或者随路时钟而后续的图像处理流水线通常跑在系统时钟下。如果直接跨时钟域传递多bit数据不加同步机制就会产生亚稳态表现为像素值随机跳变。参考设计里一般会用异步FIFO来做这个转换。你需要关注FIFO的深度和宽度。深度太浅遇到行消隐期间的数据突发就会溢出宽度不够像素位宽对不上。我的经验是FIFO深度至少能缓存两行像素宽度等于像素位宽加上几个控制位如行有效、帧有效。在ECP5里用分布式RAM或者块RAM实现都可以块RAM更省逻辑资源但要注意读写时钟的约束。另外FIFO的读写使能信号也要小心处理。读使能不能一直拉高否则会把空FIFO里的无效数据读出来。通常的做法是用empty信号取反后作为读使能或者用一个状态机来控制读取节奏。我在一个项目里因为读使能没处理好导致图像顶部出现几行随机噪声查了两天才定位到是FIFO读空的问题。4. 那些让我熬夜的坑信号完整性与时序收敛4.1 输入延迟约束过紧导致的偶发误码前面讲了输入延迟的计算方法但实际调试中你会发现即使按手册算出来的值也可能出现偶发误码。原因在于摄像头输出的时序会随温度和电压变化手册给的是典型值不是最坏值。我建议在计算出的最大和最小延迟基础上各留出10%到15%的余量。比如算出来最大是11.468纳秒那约束里可以写到12.5纳秒让工具去优化。但余量也不能留太大否则工具会认为时序很宽松布局布线时把相关逻辑放得很远反而引入更大的走线延迟。这是一个平衡。我的做法是先按计算值约束跑一遍时序报告看setup和hold的slack。如果slack是正的但很小比如小于0.5纳秒那就适当放宽约束再跑一次直到slack稳定在1纳秒以上。4.2 PCB走线等长与阻抗控制的实战教训HSB方案对PCB的要求比普通低速接口高得多。差分对如MIPI的时钟和数据lane必须严格等长误差控制在5mil以内。单端时钟线要尽量短并且两边包地。我见过一个设计MIPI的时钟差分对没有等长差了大概30mil结果训练能过但图像上每隔几行就有一条细横纹。后来重新layout把等长做到3mil以内横纹就消失了。阻抗控制也很关键。MIPI的差分阻抗通常是100欧姆DVP的单端阻抗是50欧姆。如果你用的是两层板很难做好阻抗控制建议至少四层板有完整的地平面。我在一个低成本项目里为了省层数用了两层板结果DVP接口的像素时钟跑到100MHz以上就开始丢数据后来在时钟线上加了端接电阻才勉强稳住但功耗上去了。所以如果项目对成本不是极度敏感四层板是底线。4.3 时序报告里的红色路径怎么读综合和布局布线之后Diamond会生成时序报告。如果看到红色的路径不要慌先看是setup违例还是hold违例。setup违例通常意味着组合逻辑太长或者时钟频率太高解决办法是插入流水线寄存器或者降低时钟频率。hold违例则可能是时钟偏斜太大或者数据路径太短可以通过增加缓冲或者调整布局来修复。在HSB工程里最常见的违例出现在训练状态机的比较逻辑和FIFO的跨时钟域路径上。训练状态机里有一个滑动窗口搜索如果窗口很大组合逻辑就会很深。我的做法是把搜索过程流水线化每个时钟周期只比较一个位置用状态机控制搜索步进。这样虽然锁定时间变长了但时序容易收敛。FIFO的跨时钟域路径则要确保读写指针的格雷码转换正确否则会出现指针跳变导致的空满判断错误。4.4 温度漂移引起的训练失锁这个问题在工业环境里特别常见。设备在常温下跑得好好的一到高温环境比如50摄氏度以上HSB就失锁了。原因是摄像头的输出时序和FPGA的IO延迟都随温度变化如果训练逻辑只在初始化时锁定一次之后不再跟踪那温度一变采样点就偏了。解决办法是让训练逻辑支持周期性重训练。具体做法是在帧消隐期间插入一段训练码HSB逻辑重新搜索字边界并更新采样位置。这样即使温度漂移也能在下一帧恢复。不过重训练会占用一些带宽而且如果训练码太短可能来不及锁定。我一般会在每帧的垂直消隐区留出至少几十个时钟周期的训练窗口实测下来在零下20度到70度的范围内都能稳定工作。5. 进阶玩法把HSB方案用出花来5.1 多摄像头同步采集的时钟方案有些应用需要两个甚至更多摄像头同时采集比如立体视觉或者全景拼接。这时候HSB方案要解决的不只是单路桥接还有多路之间的同步。最简单的做法是用一个共同的参考时钟让所有摄像头都工作在同一个时钟域下。但很多摄像头模组不支持外部时钟输入只能用自己的晶振。那就得用FPGA产生一个同步信号比如一个帧同步脉冲同时发给所有摄像头让它们在同一时刻开始曝光。HSB逻辑里可以增加一个同步状态机检测到同步脉冲后同时复位所有通道的训练状态和FIFO指针。这样虽然各摄像头的时钟独立但帧起始时刻是对齐的。我在一个双目项目里用这个方法同步误差控制在几个像素时钟以内后续的立体匹配算法完全能用。5.2 用HSB做简单的图像预处理HSB桥接出来的像素流是原始的Bayer格式或者RGB格式直接送到上位机处理会占用大量带宽。如果FPGA逻辑资源有富余可以在HSB后面接一个简单的预处理流水线比如Bayer转RGB、伽马校正或者边缘检测。ECP5-45F有足够的乘法器资源来做3x3的卷积跑在100MHz时钟下处理720p30的帧率绰绰有余。我试过在HSB后面加一个Sobel边缘检测只用了不到20%的逻辑资源。这样输出的就是边缘图数据量小了很多可以通过低速接口传给MCU。这种方案适合对实时性要求高但不需要高分辨率的场景比如智能小车的循迹或者工业上的缺陷初筛。5.3 调试接口的选择UART还是逻辑分析仪调试HSB的时候你需要观察内部信号。如果器件支持用Lattice的Reveal逻辑分析仪是最方便的可以抓取训练状态、FIFO指针、像素计数等信号。但Reveal会占用额外的逻辑资源和RAM对于资源紧张的设计可能塞不进去。这时候可以退而求其次用UART打印关键状态。比如每锁定一次训练就通过UART发一个字符每检测到一次FIFO溢出就发另一个字符。虽然信息量少但足以判断系统是否在正常工作。我通常会在设计里预留一个调试寄存器组通过UART或者SPI可以读写。这样上板之后我可以动态修改训练阈值或者FIFO深度不用重新综合。这个技巧在调试初期特别有用能省下大量编译时间。5.4 从HSB到完整相机系统的扩展路径HSB只是相机系统的一部分。一个完整的相机方案还需要自动曝光控制、白平衡、图像压缩、接口传输等模块。如果你打算基于HSB做产品我建议先把图像采集和显示跑通再加控制算法。自动曝光可以用简单的均值统计来实现统计一帧的平均亮度和目标亮度比较用PI控制器调整曝光时间。这个逻辑不复杂但需要和摄像头的寄存器配置接口配合通常是通过I2C去写传感器的曝光寄存器。白平衡稍微麻烦一点需要统计RGB通道的均值然后计算增益。如果对色彩要求不高可以跳过。图像压缩的话JPEG编码在FPGA上实现起来资源消耗较大可以考虑用低复杂度的预测编码或者直接传RAW数据。传输接口可以根据距离选择USB、以太网或者LVDS。如果传输距离在几米以内LVDS是最简单的HSB本身就有LVDS的参考设计可以复用。6. 关于Lattice Diamond工具链的一些碎碎念6.1 保留信号与综合优化Diamond的综合器有时候会把你认为重要的信号优化掉比如训练状态机的中间状态。如果你需要在Reveal里观察这些信号就得在综合选项里设置保留层次或者使用syn_keep属性。我一般会在关键模块的寄存器上加上/* synthesis syn_keep1 */这样综合器就不会把它们合并或者删除。但保留信号会占用额外的逻辑资源所以只对调试相关的信号用量产版本记得去掉。另外Diamond的3.13版本在时序收敛上比之前的版本好一些如果遇到奇怪的时序问题可以试试升级工具版本。不过升级之前记得备份工程因为不同版本的约束语法可能有细微差别。6.2 约束文件的组织方式约束文件不要全部写在一个.lpf里建议按功能拆分成多个文件比如clocks.lpf、io.lpf、timing.lpf。这样修改的时候容易定位也方便复用。Diamond支持在工程里添加多个约束文件综合的时候会按顺序读取。注意后面的约束会覆盖前面的同名约束所以顺序很重要。我习惯把时钟约束放在最前面然后是IO约束最后是时序例外。时序例外比如set_false_path或者set_multicycle_path要慎用用错了会导致时序报告失真。在HSB工程里跨时钟域的路径通常用异步FIFO处理不需要额外的时序例外因为FIFO的读写指针已经做了同步。如果你不确定某条路径是否需要例外宁可先不加等时序报告出来再分析。6.3 版本兼容性与IP更新Lattice的IP核和参考设计会不定期更新新版本可能修复了旧版本的bug也可能引入了新的接口。如果你从旧版本升级到新版本一定要看Release Note确认接口有没有变化。我遇到过一次HSB参考设计从1.2升级到1.3训练状态机的输出信号位宽从4位变成了5位我没注意直接替换文件结果综合报错。后来看了文档才发现多了个training_error信号。另外Diamond的工程文件格式在不同版本之间也可能不兼容。如果你需要和同事协作最好统一工具版本。我一般会在工程目录里放一个readme.txt写明使用的Diamond版本和IP版本避免别人打开时出现莫名其妙的错误。6.4 上板验证的检查清单最后分享一个我每次上板前都会过一遍的检查清单能帮你排除大部分低级错误电源电压是否正常FPGA核心电压和IO电压是否在允许范围内时钟输入是否有时钟信号用示波器或者频率计确认频率和幅值。复位信号是否已经释放有些开发板的复位按键是常闭的需要手动拨开。约束文件里的引脚分配是否和原理图一致特别是差分对的P/N极性接反了训练肯定失败。摄像头的I2C配置是否已经写入很多传感器上电后需要初始化寄存器才能输出图像。训练状态机的LED指示是否正常如果一直不锁定先检查训练码型和时钟频率。这个清单看起来简单但我在实际项目里至少有一半的调试时间花在排查这些基础问题上。HSB方案本身是成熟的大部分问题都出在外围配置和物理连接上。把基础打牢后面的事情就顺了。
返回列表