ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

ZYNQ选型与迁移实战:7020到7045资源对比及避坑指南

ZYNQ选型与迁移实战:7020到7045资源对比及避坑指南 说实话ZYNQ选型这事我一开始也栽过跟头。之前做某图像采集项目起初选了7020逻辑用到了八成多BRAM直接爆了DSP也快见底算法团队还想往里塞算子最后只能硬着头皮往7045迁移。结果发现换芯片根本不是改一下型号那么简单PCB要动电源要动DDR引脚要重排Vivado工程里的IP要重新生成连FSBL和设备树都得推倒重来。这个过程中踩了不少坑也把选型和迁移的整套逻辑理清楚了。这篇就把7020和7045的资源对比、选型计算和项目迁移避坑经验一次讲透适合正在纠结这两颗料的硬件工程师、FPGA开发者以及做ZYNQ裸机、DMA、烧写固化相关工作的人参考。1. 为什么7020和7045的对比不是换个器件那么简单很多人第一眼看到的是“7020便宜、7045资源多”但在工程上这两颗芯片几乎是两套设计方案。7020属于Zynq-7000家族里的入门到中端档位PS端和7045一样都是双核Cortex-A9但PL端资源差了四倍多封装和引脚也完全不是一个级别。选型的时候如果只盯着逻辑单元数量后面迁移基本会处处碰壁。1.1 一张表看懂两颗芯片的硬资源差异先看官方数据这里以常见的XC7Z020和XC7Z045为例数据主要参考Xilinx的DS190和DS187手册速度等级通常选-1或-2PS端主频可以跑到766MHz到1GHz具体看等级。资源项XC7Z0207020XC7Z0457045差异说明可编程逻辑单元Logic Cells85K350K约4.1倍CLB LUT53,200218,600约4.1倍CLB Flip-Flop106,400437,200约4.1倍Block RAM140块共4.9Mb545块共19.2Mb约3.9倍DSP Slice220个900个约4.1倍硬核PCIe无有7020只能PL做软核GTX高速收发器无有具体lane数看封装影响高速接口方案PS处理器双核ARM Cortex-A9双核ARM Cortex-A9基本相同PS最高频率766MHz~1GHz766MHz~1GHz选-3等级可上1GHz常见封装CLG400 / CLG484FFG676 / FFG900引脚、尺寸完全不同这张表十几秒就能看懂但真要用来做决策还得再往深想一层。Logic Cells是宣传值工程上实际看LUT、FF、BRAM、DSP四项是否够用。我见过有人只看逻辑单元数量觉得够了结果BRAM先爆了算法没法落地最后只能改架构非常被动。另一个经常被忽略的点是GTX和PCIe。7020没有GTX也没有PCIe硬核而7045有。如果项目里将来可能接PCIe采集卡、CameraLink转接板、高速AD/DA那7020基本就不适合。反过来说如果项目就是普通工业控制、电机驱动、千兆网透传7045的GTX和PCIe反而是多余成本的来源功耗也压不住。1.2 资源参数背后的真实需求映射选型不能只数资源要往回映射到具体算法模块。举个例子做720p灰度图像处理一帧原始数据是1280乘以720约等于0.92MB。7020的BRAM总量是4.9Mb换算过来只有0.61MB左右连一帧都缓存不下必须靠PS端的DDR7045的BRAM有19.2Mb约2.4MB可以缓存两帧以上这时候设计流水线就有很多灵活空间。很多图像算法之所以在7020上跑不动不是逻辑不够而是BRAM这头堵死了。再比如卷积运算。一个5x5的卷积核一个输出像素需要25次乘加。如果做FPGA全并行一个像素周期内就要完成数十次乘加DSP消耗是几十到几百不等。7020只有220个DSP做三路并行大卷积核很容易吃紧7045有900个DSP余量明显宽裕。算资源时建议这样估算先把每个模块需要的LUT、FF、BRAM、DSP列一张表累加后除以器件资源看看占用率是多少。经验上综合占用率最好控制在70%到80%以内超过80%布局布线就开始吃紧时序收敛难度指数上升工具跑多久都难收敛。这里多说一句资源余量不是玄学是给接口逻辑、跨时钟域、调试逻辑留的。很多项目在联调阶段会临时加在线抓信号、触发逻辑、计数器这些都要占资源。如果一开始就压到95%后期每加一个ILA模块都要拆东墙补西墙痛苦得很。2. 从7020迁移到7045前先算清硬件这笔账如果资源评估之后确认必须从7020迁到7045先别急着开Vivado硬件层面的账要先算清楚。这个阶段最容易出问题而且一出问题就是改板、换物料、返工的大问题。2.1 封装、引脚与PCB改动成本7020常用CLG400或CLG484封装7045常用FFG676或FFG900封装。两者球距、封装尺寸、扇出规则完全不一样基本意味着PCB要重新设计。不要指望用飞线或者转接板把7020的板子改成7045电源网络、去耦电容、DDR拓扑都撑不住。引脚上最大的坑是bank分配和电压域不一样。Zynq的IO分HR和HP bank不同封装下bank的位置、可用的HR/HP数量都不同。原来在7020上用的某个bank可能到7045封装里变成了另一个bankVCCO电压、HSIO电平都要重新核对。我见过有人迁移后直接把旧XDC里的引脚编号平移过去结果DDR控制器复位失败、千兆网初始化失败查了两周最后发现是引脚分配错位。PCB改版时重点检查三块DDR走线拓扑、VCCINT电源平面、GTX差分走线。DDR部分如果7045封装的引脚位置变化很大原来的数据线、地址线分组会乱掉MIG配置也要同步改。电源平面方面7045的PL逻辑规模大动态功耗比7020高得多如果沿用7020的电源铜箔宽度和过孔数量跑大逻辑时VCCINT很容易跌落。2.2 电源、时钟与DDR设计差异电源设计是迁移中最容易低估的一环。7020在中等资源利用率下内核电流大致在1安培到2安培级别7045如果跑到70%以上利用率动态电流可以到4安培甚至更多。DC-DC选型时不要只看平均电流要看瞬态响应。FPGA在高频翻转时电流是脉冲式的电源模块动态响应不够快电压跌落几十毫伏就可能导致时序崩溃或者偶发死机。我遇到过一台7045设备跑图像算法时不定时重启最后用示波器抓VCCINT波形发现负载突增时电压跌了将近0.1V最低点已经接近芯片工作下限。后面把DC-DC的开关频率调高、加了大容量陶瓷电容、重新优化了反馈采样位置才解决。这个坑在7020上不明显因为电流小IR压降不容易体现但到了7045就暴露了。DDR设计上7020和7045的PS端DDR控制器本质上是一样的支持DDR3、DDR3L、LPDDR2但不支持DDR4。迁移到7045后因为封装引脚变了原有的DDR走线、引脚分组、字节通道都要重新分配。操作上不能直接把旧MIG工程拿来用必须在新器件下重新生成MIG逐项核对DDR型号、位宽、Bank地址、时序参数。特别要注意DQS、DM引脚的约束组这类错误通常不会有明显报错但跑内存压力测试时随机出错。时钟方面PS端的时钟输入仍然是PS_CLK频率范围一般在30MHz到50MHz这个不影响。但7045如果要启用GTX就需要额外设计GTX参考时钟常见的是125MHz或100MHz差分时钟802.3协议通常还要多个频率相位对齐。7020完全没有GTX很多旧板子根本没有对应的时钟buffer和匹配电路迁移时往往要重新加。2.3 PCIe和高速接口带来的连锁反应7045的GTX和PCIe硬核是它比7020强出许多的地方但这也是迁移时新增工作量最大的部分。PCIe硬核不是简单配个IP就能用涉及到参考时钟、复位逻辑、LTSSM状态机、DMA地址映射还要配合PL端逻辑做报文中断处理。这些工作在7020上完全不存在等于软件和逻辑团队都要补课。如果项目原本没有高速接口纯粹为了资源数从7020升到7045那GTX相关电路可以先不画但要注意7045的封装里GTX引脚所在的bank即便不用也必须接正确的参考地或端接不能悬空。很多原理图设计人员习惯性把不用的高速引脚空着结果板子画完上电PL温度异常查半天是GTX电源域没处理干净。反过来如果项目未来三年都看不到PCIe或万兆光口需求我反而建议慎重选7045成本高、功耗大、设计复杂度高。中间档位还有个XC7Z030资源在两者之间有GTX但没有PCIe硬核也能做三路以下的高速串行通道预算敏感时可以考虑。3. Vitis/Vivado工程迁移实操流程硬件设计确认没问题后才轮到软件工程迁移。这里我按从Vivado工程到Vitis的完整链路写一下步骤重点是换器件后哪些东西必须重建、哪些东西容易忽略。3.1 Vivado器件替换与IP更新先把原工程备份一份这个老生常谈但我真见过有人迁移到一半原工程被自动更新坏掉追悔莫及。然后在Vivado里做器件替换操作路径是Tools - Project Settings - General - Project Device把器件从xc7z020换成对应的7045比如xc7z045ffg676-2。也可以直接用Tcl命令行set_property -name {part} -value {xc7z045ffg676-2} [current_project]改完器件后IP状态会变成需要升级或重新生成。重点检查这几个IPMIG DDR控制器、AXI Interconnect、Clocking Wizard、AXI DMA。MIG必须重新配置因为引脚分组和封装变了AXI Interconnect可能会根据新器件的位宽规则自动调整但建议手动确认数据宽度Clocking Wizard要重新生成时钟检查是否和白皮书约束冲突AXI DMA如果原来跑在较低频率换到7045后可以试着往上拉频率但要重新跑时序验证。XDC约束文件是迁移中最大的坑。不同封装的物理引脚几乎不兼容单纯把约束文件里的引脚名称做正则替换是危险的。我习惯的做法是先把原工程综合后的资源报告和I/O报告导出存档然后新建一个空约束文件按照新原理图逐条填写引脚约束而不是从旧XDC复制。这个过程耗时但能排查出原理图里bank电压错误、引脚冲突等问题。完成更换后跑一遍综合和实现。7045的资源多通常时序更容易收敛但如果原设计在7020上已经压着时序线过的换到7045后不一定直接通过尤其是时钟树结构变化之后部分路径的约束需要重配比如创建生成时钟的从节点位置变了需要同步修改。3.2 FSBL、设备树与BSP重建换完器件后Vivado侧导出新的硬件文件然后进入Vitis旧版本叫SDK。这里强烈建议新建一个platform工程不要用旧platform硬改。很多人图省事直接在新Vitis里挂旧BSP结果外设配置、中断号、DDR地址这些参数还是按7020生成的启动后各种诡异现象。新platform生成后FSBL会自动换成新器件对应的版本。要注意FSBL里的DDR初始化参数如果新板子的DDR容量变了或者DDR型号变了必须更新DDR参数否则FSBL启动阶段就卡住。DDR参数的来源是Vivado里的MIG配置或者PS DDR配置界面两者要一致。裸机应用的BSP也要重新生成尤其是外设配置。比如原来用SDIO、SPI、UART、USBBSP里对应的驱动版本、时钟频率、中断ID都要重新确认。Zynq的PS外设中断ID在器件迁移后一般不变但PL侧自定义IP的中断号取决于Vivado工程里对Interrupt Controller的连接如果地址映射变了裸机代码里的XScuGic配置要同步修改。设备树方面Linux场景下要重点核对memory节点例如DDR实际容量为1GB时memory0 { device_type memory; reg 0x0 0x40000000; /* 1GB DDR3 */ };如果设备树里DDR大小和新硬件不一致Linux能启动但跑大任务就随机崩溃。还要检查PL侧设备树节点中的中断属性确保和Vivado工程导出的中断号一致。Zynq设备树的很多节点是固定外设这部分迁移后变化不大但FPGA节点、DMA节点、自定义IP节点建议逐个过一遍。3.3 启动镜像生成与QSPI固化烧写工程重建完后生成BOOT.BIN是Zynq启动的关键一步。在Vitis里创建Boot Image时顺序是FSBL、Bitstream、应用App如果是裸机或者FSBL、PMU、ATF、U-Boot、kernel imageLinux方案。普通裸机方案最简单三件套按顺序加进去就行。烧写到QSPI Flash有两种常用方式。一种是在Vitis菜单里选Xilinx - Program Flash界面里选择BOOT.BIN路径偏移地址填0Flash Type选择对应的qspi型号点击烧写。另一种是命令行方式习惯自动化流程的人喜欢用program_flashprogram_flash -f BOOT.BIN -offset 0 -flash_type qspi-x4-single -fsbl fsbl.elf -cable type xilinx_tcf url TCP:127.0.0.1:3121这里有个经典问题为什么烧Flash时要带fsbl因为program_flash工具需要FSBL来初始化DDR然后把BOOT.BIN整体搬到DDR里再从DDR写入Flash。这就自然引出了众说纷纭的“JTAG固化Flash必须用DDR吗”这个问题下面专门展开讲。4. 迁移后的常见问题排查与避坑记录这一章算是我踩坑集锦也是很多搜索热词背后的真实痛点。项目迁移过程中烧写固化、DMA、裸机USB、上位机串口通信这些环节最容易出问题我按场景逐个梳理。4.1 固化烧写类JTAG烧Flash到底要不要DDR先给明确结论不是绝对必须但标准工具链使用方法下一定会用到DDR。Zynq的上电启动过程是BootROM先把FSBL加载到片内OCM里执行FSBL的第一个大动作通常是初始化DDR。之后DDR就可以作为数据中转区。program_flash这类工具要烧写的镜像一般有几百KB到几十MBOCM只有256KB放不下所以必须先把镜像放在DDR里再写进Flash。网上经常能搜到“7020使用JTAG固化Flash时必须使用DDR吗”实际场景答案是如果只是想把一个很小的FSBL烧进Flash理论上可以改FSBL跳过DDR初始化直接从OCM搬到Flash控制器但这样做没有任何收益反而绕。更常见的坑是有人烧写BOOT.BIN后拔电重启发现QSPI启动失败第一反应是DDR没初始化其实大概率是Flash型号配置错误或者偏移地址不对。排查思路大概是先确认上电后MIO启动模式引脚拨到了QSPI档位再从Vivado Hardware Manager里读Flash ID确认软件识别的型号和板子上的一致最后确认BOOT.BIN偏移QSPI通常从0地址启动如果偏移到了某个地址BootROM就找不到镜像头。烧完后不要直接关电先读回Flash内容对比前几百字节是否和BOOT.BIN一致这条经验能节省大量重复烧写时间。4.2 AXI DMA与缓存一致性问题Zynq平台做DMA传输最常见的问题是PS和PL之间数据不一致尤其是跑Linux或带Cache的裸机工程时。现象经常是DMA能搬数据但数据偶尔旧、偶尔新或者中断丢了。核心原因是CPU有CacheDMA直接访问DDR两边看到的数据不同步。解决办法就是正确的Cache操作。发送数据前将buffer cache flush接收数据后将buffer cache invalidate。在Xilinx的驱动里常见写法是Xil_DCacheFlush(); // 或者 Xil_DCacheInvalidate();如果工程用了AXI DMA还要注意描述符地址和数据buffer地址的对齐。描述符建议放在DDR的低地址区域数据buffer按32字节对齐避免跨4KB边界。还有一个隐藏点DMA的Buffer大小如果设置得比实际传输大很多Cache操作的区间也要对应不能只刷前一半否则后半段数据可能被Cache残留污染。迁移到7045后PL侧AXI时钟可以跑更高DMA吞吐量理论上更大但跨时钟域稳定性反而更敏感。建议做长时间压力测试不只测传输速度还要盯着系统跑24小时以上看有没有偶发中断丢失。另外如果原来在7020上是用AXI GP端口做DMA迁移后7045上有更多高性能接口选项如HP端口可以降低CPU参与度。4.3 裸机USB与libusb通信的坑Zynq的PS端自带USB控制器通常切换到Device模式做USB从设备和上位机通信。这块在7020和7045上差别不大但很多团队从旧工程迁移后会在USB上踩坑。常见现象USB插入电脑后枚举成Unknown Device或者枚举成功但端点传输一直失败。排查顺序一般是先量USB PHY的参考时钟是否正常Zynq PS USB需要外部USB PHY常用的有USB3320等PHY的CLKOUT要连到PS的USB时钟脚再看MIO配置USB接口的MIO引脚是否被其他外设复用最后查软件里USB描述符和端点配置。Xilinx裸机USB Device驱动里比较常见的坑是配置了错误的端点地址主机端请求的端点号和Zynq端实际注册的不一致导致控制传输之后数据端点一直处于STALL状态。上位机用libusb访问裸机Zynq USB设备首先要解决驱动识别问题。Windows下libusb需要WinUSB驱动通常用Zadig把设备驱动替换成WinUSB否则libusb找不到设备Linux下要写udev规则否则普通用户没有权限open设备。通信时的坑主要来自端点空闲状态处理Zynq裸机USB设备端如果没有及时调用接收接口主机发数据时会超时。建议把端点读取放在循环线程里配合中断事件做联动。4.4 上位机QT串口库编译与波特率不准这个场景很多做Zynq上位机的人都会遇到。QT里用串口有两类方案老工程可能用qextserialport新版直接用QSerialPort。qextserialport在较新QT版本里编译偶尔会报错主要是因为connect语法或者信号槽宏不兼容建议新工程直接选QSerialPort省去维护第三方库的麻烦。Zynq端串口波特率不准导致上位机乱码是另一个高频问题。PS端UART时钟来自IO PLL如果PLL配置和实际晶振频率不匹配波特率分频就会产生误差误差超过2%就可能出现乱码。排查时先用示波器测TXD引脚的电平宽度比如9600波特率时一个bit宽度大约是104微秒如果明显偏差就去核对UART时钟配置。换器件后最容易碰到的问题是时钟向导里的输入频率没按新板子的晶振改或者PS_CLK频率和BootROM预期不一致导致整个系统时钟偏了。还有个小细节QT上位机和Zynq设备之间如果经过USB转串口某些廉价转换芯片在高速波特率下会乱码这并不是Zynq端问题。测试时尽量用示波器或硬件串口直连先排除链路问题再定位是软件还是硬件。最后再分享一个我自己的心得。迁移到7045后不要把旧工程里的资源使用率优化习惯丢掉。7045虽然资源多但布线规模大综合实现时间也比7020慢不少。如果能在算法层面把DSP用量降下来比如用CSA近似乘法替代部分乘法器或者把BRAM的位宽利用率提升7045跑起来会更从容。项目选型也是一样7020和7045之间不是简单二选一而是要看整机功耗、成本、PCB改版周期和团队维护能力。如果只是资源紧张先试试逻辑优化和IP调参可能根本不用换芯片如果确实要换硬件账、软件账、测试账三笔一起算才能把迁移风险降到最低。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进