ARTICLE DETAIL

资讯详情

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

嵌入式FPGA开发实战:从高速接口到异构SoC的工程指南

嵌入式FPGA开发实战:从高速接口到异构SoC的工程指南 1. FPGA在嵌入式系统里的角色早不是当年的“胶水芯片”1.1 高速接口把FPGA顶到了数据通路正中央十年前我刚接触FPGA的时候这东西在嵌入式系统里的地位挺尴尬的。说是万能逻辑芯片干的活却大多是接口转换、电平匹配、地址译码这类杂事正经的高速数据处理轮不到它。那时候的主流方案是“ARM主控 FPGA做胶合逻辑”FPGA挂在旁边当配角。这几年情况完全变了。你去翻任何一个中高端FPGA的芯片手册高速串行收发器是标配动不动就是十几Gbps的线速率JESD204B、SRIO、PCIe、万兆网这些接口全往里面塞。为什么因为传感器和链路的速度上来了——高速ADC采集出来的数据JESD204B接口一秒钟就是几个G字节雷达信号处理的板间互联SRIO轻轻松松跑到5Gbps以上数据中心推的智能网卡PCIe要直接穿透到FPGA的逻辑里做报文处理。这些数据量传统MCU根本接不住ARM主控算力再强IO也进不来。FPGA成了整个数据通路里唯一能站在“接口最前沿”的芯片角色从胶水变成了心脏。这个变化最直接的体现就是FPGA工程师的活越来越像做高速电路设计。我记得第一次调高速串行收发器的时候以为只要在Vivado里把IP配好、烧上去就能跑通结果发现链路起不来折腾了整整两天最后查出来是参考时钟PCB走线太长信号质量不行。从那以后我养成了一个习惯先看IBERT跑误码再看链路能不能建起来最后才谈业务逻辑。1.2 异构SoC成了嵌入式FPGA的新常态如果只是接口速率提升FPGA还是那个FPGA。真正改变游戏规则的是异构SoC的出现。Xilinx的Zynq系列把ARM核和FPGA逻辑放在同一颗芯片里Zynq UltraScale EV进一步塞进了视频编解码核VCU。复旦微这些国产厂家的FPGA也在朝SoC化走配置工具都跟着变了。这东西对嵌入式系统的意义不是简单的“两颗变一颗”而是改变了整个软硬件分工的方式。以前FPGA和CPU之间通过总线通信一来一回延迟很大协同效率低。现在ARM和FPGA之间是AXI高速片上总线吞吐量高了几个数量级FPGA可以把CPU要的数据预先处理好放进DDRCPU直接读结果。拿我做过的一个Zynq上的数据采集项目举例FPGA逻辑部分负责把ADC数据流接入、滤波、降采样ARM核跑Linux负责网络协议栈和上层控制。这个架构的好处是算法迭代只需要改PL侧的Verilog协议、驱动、界面全在PS侧两边可以并行开发联调的时候接口早就定好了。你要是还在用独立FPGA加外部CPU的方案光是板间并行总线那一堆时序约束就够你喝一壶。嵌入式FPGA的未来很大程度上就是在这种“软硬协同”的架构上演进的。纯逻辑工程师的岗位会慢慢变少“懂RTL、能写驱动、会调Linux”的人才是市场真正缺的。2. 高速接口调试是嵌入式FPGA绕不过去的硬骨头2.1 IBERT核怎么用才能定位物理层问题做嵌入式FPGA的人迟早会碰到这么一个问题高速收发器链路起了但跑一会儿就出误码或者根本起不来。这时候别急着怀疑IP配置先把手头的IBERT用起来。IBERTIntegrated Bit Error Ratio Tester是FPGA内部自带的硬核测试逻辑它的意义在于在不写任何业务逻辑的情况下把收发器物理层通道打成一个回环或者对打链路看误码率和眼图。它能帮你把问题圈定在“物理层”还是“逻辑层”。用IBERT有几个值得注意的点。第一参考时钟的管脚别选错不同bank的参考时钟来源不同选错了信号根本起不来。第二线速率和协议层设置要和最终设计一致别用低速率测完就以为高速率没问题高速率的信号完整性要求苛刻得多。第三看眼图别只看能不能睁眼还要看眼高、眼宽、抖动这几个指标的余量。我一般会让眼高余量留到20%以上否则温度一上来就容易挂。有一次我在调试一块板子IBERT显示10Gbps链路误码率在10的负12次方左右眼图看着还行但就是每隔几分钟跳几个错。后来用示波器探电源纹波发现收发器供电的DC-DC纹波偏大导致锁相环跟着抖。换了片低纹波的LDO之后误码率直接降到10的负15次方以下。这个教训让我明白了高速串行链路的疑难杂症一半以上是电源和时钟的问题而不是代码问题。2.2 JESD204B链路建立失败先从这三个方向排查热词里有一条是“JESD204B调试笔记从链路建立失败到频谱干净的完整复盘”一看就是被折腾过的人。JESD204B这种接口在无线通信、高速数据采集里用得极多它是ADC/DAC和FPGA之间的高速串行协议替代了传统的并行LVDS接口。JESD204B的调试核心是“链路建立”说白了就是ADC和FPGA之间要握手成功双方在速率、通道数、采样点数这些参数上保持一致。链路建立失败最常见的三个原因是SYSREF没有对齐、时钟频率不对、参数配置不一致。Subclass 1是JESD204B最常见的模式它要求SYSREF信号必须和设备时钟同步保证确定性延迟。我调试的时候习惯用示波器同时抓SYSREF和设备时钟看上升沿对齐关系。SYSREF不能只是“有”它的建立时间和保持时间都得满足芯片手册要求。曾经有一块板子链路时好时坏最后发现是SYSREF走线没有等长导致不同温度下时序裕量不同链路就跟着抽风。链路建起来之后还要看频谱干不干净。JESD204B的采样数据在频域上如果有杂散往往是时钟抖动或者电源耦合造成的而不是协议本身的问题。这个时候去调FPGA逻辑没用回头检查时钟芯片的配置和电源滤波才是正路。JESD204B的调试我总结了一个排查顺序先确认参考时钟和SYSREF的时域质量再确认寄存器配置中的L、M、F、S参数和链路速率一致最后才去抓数据比对。顺序反了事倍功半。2.3 各类总线接口的取舍SRIO、PCIe、万兆网怎么选很多嵌入式系统里FPGA不只是处理数据还要和外面的板卡或者主机通信。这时候就涉及总线选型。SRIO、PCIe、万兆网是目前最常用的三种。SRIOSerial RapidIO是嵌入式板间互联的老牌方案特别适合雷达信号处理、图像处理这种板卡之间需要高带宽、低延迟、确定性的场景。它的优势在于协议栈相对简单原生支持DMA和消息传递实时性可控。缺点是不太适合跨机柜、长距离传输。PCIe的优势是生态成熟主机侧不用专门写驱动用现成的DMA驱动就行带宽也高。缺点是拓扑相对固定不太适合多板卡之间的对等通信。做AI加速卡、数据采集卡和服务器通信PCIe是首选。万兆网的优势是通用、能跨设备、能组网但协议栈开销大延迟相对高做实时性要求高的信号链传输会吃力。选型说白了就是看场景板卡之间做数据分发SRIO最稳和主机做批量传输PCIe最舒服跨设备组网万兆网没得选。也有些项目会用PCIe加万兆网同时存在FPGA内部做协议转换这种架构在通信设备里很常见。3. 信号链路的处理能力决定嵌入式FPGA的天花板3.1 前端数据接入LVDS和CIC滤波器怎么配合FPGA在嵌入式信号处理链路里最常见的活是从ADC接收数据、做滤波、降采样再喂给后级。ADC和FPGA之间低速时代用并行LVDS高速时代被JESD204B取代但LVDS并没有消失很多中低速高精度采集系统还在用。关于LVDS接口有个细节特别容易踩坑差分引脚的正负端DXn/DXP之类千万别接反接反了眼图直接全灭。我见过有人把LVDS正负端接反第一反应是怀疑FPGA的IO配置查了半天才发现是PCB封装画反了。还有LVDS的终端电阻要靠近接收端能内置就用内置非要外接的话电阻值一定要按差分阻抗特性来选别随手贴个100欧姆就完事。CIC滤波器级联积分梳状滤波器是FPGA里做降采样的经典结构它不需要乘法器全是加法器和延迟单元特别适合在FPGA里跑高频。CIC本身有个特点通带会有衰减所以一般后面要级联一个补偿滤波器把通带拉平。做CIC的时候最容易忽略的是位宽增长问题每一级积分器都会增加比特数不提前算好数据溢出以后出来的波形整个是花的。以我自己的经验做CIC抽取器的时候先把抽取倍数D、级联数N、差分延迟M这三个参数定好然后用公式算每级需要的位宽再把增益补偿一并算进去最后在ModelSim里用正弦波做仿真看输出波形幅值对不对。这一步省不了直接上板子调波形不对你都分不清是CIC位宽溢出还是后面接口的问题。3.2 在FPGA里做TDC比你想的更依赖底层硬件TDC时间数字转换器是FPGA里另一个颇有代表性的应用。激光雷达测距、超声成像、粒子物理探测都需要把极短的时间间隔量化成数字值。FPGA做TDC通常用进位链实现延迟线借由硬件本身的传播延迟特性把时间差转成温度计码。做TDC最重要的技巧是bin的校准。FPGA的进位链延迟不是均匀的温度、电压一变延迟也跟着变。所以工程上要定期做码密度校准输入一个随机时间分布的信号统计每个bin出现的概率反过来校准每个bin的宽度。不做校准的话TDC的分辨率高但线性度差测出来的时间值不可信。TDC设计的另一个痛点是延迟链的布局布线会影响一致性。你在综合的时候很难控制软件把进位链放在哪个物理位置所以实际调试中经常出现同一份代码换个芯片批次或者换个温度范围分辨率就变了。我现在的做法是尽量用厂商原语去例化进位链而不是写普通加法器让综合器自己去推断这样可控性会好很多。3.3 任意波形发生器DDS加DAC的工程化细节用FPGA做任意波形发生器比如热词里提到的 ego1 板卡是很多人入门时的经典项目但真正把它做好有几个关键点值得注意。DDS的核心是相位累加器加查找表相位累加器位宽决定了频率分辨率查找表深度决定了波形点数。工程上一般不用一个完整周期的正弦表而是用四分之一周期表加象限映射来节省存储资源。频率控制字的计算方法很简单Fout M * Fclk / 2^N其中M是频率控制字N是相位累加器位宽。这个公式一定要吃透否则你配的频率和示波器测出来的总是不对。DAC的接口时序是另一个坑。高速DAC对数据和时钟的对齐关系要求很严格差一点就会出现毛刺。很多DAC支持数据返回时钟FPGA侧要做bitslip或者延迟调整。调试的时候先用单点数据模式测DAC输出是否准确再切到DDS连续波形这样能快速定位是数据通路的问题还是DDS算法的问题。还有一点别忽略DAC输出端的重建滤波。DDS出来的阶梯波频谱上带很多镜像分量不加低通滤波器就直接看波形是“阶梯”的频谱是“脏”的。一个简单的RC低通或者运放构成的二阶低通就能让波形干净很多。4. AI和加密让嵌入式FPGA的定位更“上层”4.1 AI FPGA的价值不在算力在接口和时间确定性这两年“AI FPGA”这个概念挺热的但很多人对它有误解以为FPGA要去跟GPU拼TOPS。真要在嵌入式系统里用FPGA跑AI它的优势从来不是峰值算力而是接口全、延迟低、时间确定性强。一个典型的嵌入式AI场景是这样的摄像头或者雷达传感器把数据送进来FPGA在数据入口做预处理然后直接在内部跑一个轻量化的神经网络推断结果毫秒级输出用来控制电机或者触发告警。整个过程不经过CPU没有操作系统调度抖动延迟是可预测的。这在工业控制、自动驾驶感知这类安全至上的场景里非常关键。Zynq UltraScale EV这样的芯片已经把AI加速所需的基础设施都准备好了高速收发器接传感器DSP切片做卷积运算片上存储做数据复用ARM核做调度。做这块开发的时候我最大的感触是纯粹的神经网络算法反而最简单难的是把前端的传感器接口、中间的数据流控制、后面的执行机构协同起来。FPGA工程师的AI技能重点应该放在“怎么把模型部署到硬件上并跑通时序”而不是啃一遍深度学习理论。4.2 SM4等加解密算法在FPGA里的工程实现热词里有“FPGA实现SM4”这也是嵌入式FPGA一个重要应用方向。国密算法SM4在电力、金融、通信设备里用得越来越多FPGA做加解密比CPU快得多而且密钥存储更安全。SM4的FPGA实现核心是轮函数加密钥扩展。轮函数里最关键的是S盒替换直接用查找表实现会占用大量LUT工程上常用流水线或者组合逻辑优化。吞吐率要求高的场景可以对四轮加密做流水线展开让多个数据块并行处理吞吐率能翻几倍。我做过一个SM4的加解密模块最开始直接照论文写综合出来资源占用很大时序也收不上。后来改成把S盒拆分成多个小查找表再用寄存器打拍流水时序马上就收敛了。FPGA做加解密就是这样算法本身不难难的是在资源、时序、吞吐率之间找平衡。5. 开发工具链的演进正在改变FPGA工程师的日常5.1 Vivado生态里的Auto Connect、XVC、System PlannerVivado这两年迭代得很快Auto Connect这个功能在搭建块设计Block Design时非常省事。以前在IP Integrator里手动连AXI接口线又多又容易错。Auto Connect会根据接口类型自动生成相应的互联逻辑只需要把各个IP摆好点一下就让工具自动连几分钟就能把一个小系统搭起来。但如果你是做复杂系统级设计我还是建议手动把关一下跨时钟域的处理别让工具自动插的时钟和复位逻辑影响性能。XVCXilinx Virtual Cable是个很实用的远程调试功能。它把JTAG调试链路通过网络虚拟化在实验室以外的地方也能通过Vivado连上板子做在线调试。对那种已经装进机箱、不方便拆出来接JTAG的设备XVC能省不少事。实现XVC的方式有很多种可以用Zynq上的ARM跑一个TCP服务器做桥接也可以直接在FPGA逻辑里面用MicroBlaze实现。5.2 国产FPGA工具链的现状以Procise为例很多工程师开始接触国产FPGA复旦微的FPGA就是其中之一用的工具链叫Procise。刚开始用的时候会不太习惯因为操作习惯和Vivado有差异。比如下载程序的方式、IP核的配置界面、约束文件的写法都和Xilinx不完全一样。用Procise下载/固化程序的流程我踩过几次坑之后总结出一个稳定的套路先编译生成比特流然后加载到板卡上在线跑通确认逻辑没问题最后再生成固化用的烧写文件写入配置Flash。需要注意的细节是不同容量型号的Flash对应的烧写地址和格式不一样选错了烧进去起不来。另外国产FPGA工具链的文档相对少遇到问题很多时候要靠自己试。我的建议是做国产FPGA项目之前先在熟悉的平台上把RTL代码和测试bench调通、仿真通过再移植过去不要直接拿工具链当调试器用那样效率太低了。5.3 别忘了看时序报告内部时钟的约束和跨时钟域FPGA开发里时序约束是最容易被忽视、也是最容易导致返工的环节。热词里“FPGA如何约束内部时钟信号”“快时钟到慢时钟1.2倍怎么设置时序约束”都是非常实际的问题。内部时钟信号比如MMCM/PLL输出的时钟不需要你手动创建约束Vivado会自动从IP配置里得到时钟信息但要手动设置时钟间的关系。如果两个频率不成整数倍比如快时钟是慢时钟的1.2倍它们属于异步时钟域直接做数据交互会有亚稳态风险。这时候要在XDC里设置异步时钟组让时序分析工具不再对这两个时钟域做严格时序分析同时在代码里用两级同步器或者异步FIFO做同步。set_clock_groups -asynchronous -group [get_clocks -include_generated_clocks clk_fast] -group [get_clocks -include_generated_clocks clk_slow]当然设置成异步组不代表物理上真的安全你还需要确保跨时钟域的每个信号都经过同步处理。做这种处理时我习惯在RTL里给跨时钟域信号加后缀比如_sync这样看代码和约束的时候一目了然也方便代码评审的时候检查有没有漏同步的信号。6. 嵌入式FPGA工程师未来的能力模型要升级6.1 只会写Verilog已经不够用了这几年招人面试FPGA工程师我明显感觉到要求变高了。以前会写状态机、能调时序再会一点接口协议基本就能干活。现在不一样嵌入式FPGA的岗位要求你得懂ARM、得会Linux设备树、得能看懂示波器和频谱仪抓出来的波形有时候还得自己画原理图检查信号完整性。“FPGA十年老鸟”这个词最近在社区里挺火其实就是指那批从纯逻辑工程师一路干到系统级的人。他们的共同点是不完全依赖工具知道IP配好了但物理层没调好会有什么后果也不迷信理论知道仿真通过和上板跑通之间隔着电源噪声、串扰、时序收敛这好几道坎。6.2 新人和转行的朋友先抓住这三条主线如果你刚入门FPGA或者想从传统嵌入式转FPGA我的建议是别贪多先把三条主线抓牢。第一条主线是时序和状态机。这是FPGA的基本功状态机写不好后续所有逻辑都会埋雷。第二条主线是接口协议串口、I2C、SPI这些基础协议要能熟练用Verilog或VHDL实现并仿真调试然后再扩展DDR3、PCIe、JESD204B这些高速接口。第三条主线是调试方法会抓波形、会看时序报告、会用逻辑分析仪和示波器定位问题。学习路径上的具体建议是先在小板子上把LED流水灯、串口收发、按键消抖这类基础实验做扎实然后啃一个完整的信号处理链路比如AD采集加FIR滤波加DA输出最后再挑战高速接口。与其报一堆课不如自己动手做三五个完整的小项目踩过的坑才是真正长在身上的经验。写在最后嵌入式FPGA这几年最让我触动的一点是它不再是一个被固定角色框住的芯片类型。今天你可以用它做无线电的JESD204B数据采集链明天可以拿它跑轻量AI推理后天又变成一块PCIe加速卡的核心。这种可塑性是MCU和ASIC都很难给的。反过来这也给FPGA工程师提了个醒指望一套技能吃十年不现实。我自己的体会是保持对新接口、新工具链的敏感度比什么都重要。第一次调JESD204B的时候我也是一头雾水但把SYSREF、时钟芯片、眼图这三个概念串起来之后后面的路就顺了。最后再分享一个写代码之外的小技巧做嵌入式FPGA项目一定要在项目初期就建立信号完整性和电源质量的检查习惯。别等到系统联调时才发现收发器误码率高、ADC数据跳变那时候定位问题的成本是早期的十倍以上。先把物理层验证扎实再往上堆积木这条路我走了十年基本没走偏。
返回列表