ARTICLE DETAIL

资讯详情

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

FPGA功耗优化5大硬核技巧:从动态功耗公式到实战降耗指南

FPGA功耗优化5大硬核技巧:从动态功耗公式到实战降耗指南 上周在实验室调一块Zynq边缘采集板上电不到五分钟封装表面就已经烫得让人不敢久碰。拿热成像扫了一下核心区域直逼85℃整机电流比规格书预估高了快三分之一。再查项目进度第二天就要交给客户做环境测试那叫一个焦头烂额。后来翻出Vivado的功耗报告逐项核对又花了两个通宵把时钟、总线和数据调度全部梳理了一遍才把温度压下来。这件事之后我养成了一个习惯不管项目多急功耗问题一定要提前算、提前设计。原因很简单FPGA的功耗问题很少是单一因素造成的但它发作起来非常快——发烫、复位、时序劣化、电池续航崩全都跟着来。这篇文章我就把实际项目里最常用的5个硬核优化技巧捋一遍涉及动态功耗公式拆解、时钟树设计、数据翻转率控制、资源选型、电压档位和运行期功耗管理。适合正处于FPGA入门到实战过渡期的开发者也适合那些正在做图像处理、多端口DDR读写、SPI ADC采集、边缘网关这类项目被功耗和温度折磨得想摔开发板的工程师。1. 功耗到底烧在哪先把能量账算清楚1.1 动态功耗的计算方式FPGA的功耗主要分成动态功耗和静态功耗两块。动态功耗的经典公式是P α × C × V² × fα是节点翻转率C是节点电容V是电源电压f是时钟频率。这个公式但凡做过硬件的人都知道但真正把它用在设计里的没几个。原因很简单公式是死的芯片内部几十万个节点每个节点的α、C都不一样真要一个个算根本算不过来。不过做功耗优化不需要精确到每个节点只需要抓住大局。以一颗中等规模的Artix-7系列FPGA为例在200MHz时钟、内核电压1.0V的情况下内部逻辑和布线网络的总等效翻转电容大约在20nF到30nF的量级。把这些数字代进去假设平均翻转率30%左右就可以估算出动态功耗大约在1.2W到1.8W之间。这个数字虽然粗糙但作为优化前的基准是够用的。关键是要理解每一项参数的分量。C几乎是固定的工艺和芯片架构决定了你改不动。V是平方项内核电压哪怕只降0.1V动态功耗都能降一截。f是线性的时钟频率砍一半动态功耗就少一半。α最容易被忽略但它同样能带来几倍的差距。后面讲的5个技巧本质上都是在动V、f和α这三样东西。1.2 静态功耗被很多人忽视的隐藏耗电大户静态功耗来自晶体管的泄漏电流跟逻辑翻转没有关系只要芯片上电就一直消耗。工艺制程越先进泄漏电流比重往往越高。28nm工艺的FPGA静态功耗占整颗芯片的10%到30%到了16nm、7nm工艺静态功耗比重还能再往上走。更麻烦的是泄漏电流随温度升高呈指数级上升。芯片越烫静态功耗越大静态功耗越大芯片越烫整个系统进入恶性循环。这一点在功耗分析时一定要留意。很多时候你优化了一圈动态功耗发现整机功耗还是压不下去结果一查静态功耗已经因为温度过高而悄悄翻倍了。所以功耗优化的第一步不是急着改代码而是先看看当前芯片温度、当前静态功耗的基线是多少。如果静态功耗占比已经超过40%先解决散热和温度问题再谈动态功耗优化。1.3 一张表看功耗来源与可优化空间功耗来源主要决定因素占比参考可优化手段时钟网络时钟频率、BUFG数量、时钟域数量30% - 50%合并时钟域、门控时钟、时钟使能逻辑单元LUT/FF数量、翻转率20% - 40%宏单元替代、逻辑复用、FSM编码I/O接口I/O标准、翻转率、终端匹配10% - 30%降低I/O电压、换低功耗标准高速收发器通道数量、链路速率、终端电流视场景而定链路休眠、速率降档、数据突发静态功耗工艺、温度、配置状态10% - 40%控制温度、器件选型、休眠模式这张表是我做功耗估算时习惯用的框架。拿到一颗新芯片、一个新设计先按这张表把各部分占比估一遍再决定从哪下手。时钟网络永远是头号目标因为一个FPGA里动辄几万个寄存器的时钟端都挂在同一棵时钟树上频率翻一下整个芯片的开关活动都跟着翻。2. 硬核技巧一时钟搞定时钟就搞定一大半功耗2.1 降频不是无脑砍关键是时钟使能与门控很多工程师一听到降功耗第一反应是把系统主频从200MHz降到100MHz。这种做法见效快但容易把系统性能一起砍掉。实际上FPGA里很大一部分时钟能量消耗在根本不需要工作的模块上。一个UART接收模块在等待起始位的时候它的接收状态机根本没有数据进来但时钟照样在每个周期打满所有寄存器白白翻动几万个节点。业内常用的做法是时钟使能。把计数器生成的慢时钟脉冲当作使能信号而不是真正去生成一个新时钟。比如需要1Hz的LED翻转可以用一个100MHz主时钟驱动计数器计数到5000万时拉高一个使能脉冲LED模块只在使能有效的那个周期翻转而不是让LED模块自己挂在1Hz的慢时钟上。这种写法在Vivado里综合出来的结果只会占用很少的额外逻辑却可以省掉一棵完整时钟树的功耗。代码层面的标准写法类似下面这样reg [25:0] cnt; reg ce_1hz; always (posedge clk) begin if (cnt 26d49_999_999) begin cnt 0; ce_1hz 1b1; end else begin cnt 26d49_999_999 1; ce_1hz 1b0; end end always (posedge clk) begin if (ce_1hz) led ~led; end注意这里不要写成always (posedge clk) begin if (cnt 26d49_999_999) begin cnt 0; led ~led; end end这两种写法功能几乎一样但区别在于后一种写法把LED翻转的逻辑直接挂在了100MHz主时钟上综合工具会认为LED的翻转活动率为每周期1%。前一种写法把LED逻辑放在一个以1Hz频率翻转的使能条件下综合工具能识别出翻转活动率只有0.000004%。功耗估算结果能差出一个量级实测也有明显区别。2.2 多时钟域下如何安排BUFG与同步器每增加一个时钟域就要至少占用一个全局时钟缓冲器BUFG同时要在这棵新时钟树下面增加同步器。BUFG的驱动能力很强几百上千个负载都在它下面任何一次翻转都意味着大量的电容充放电。所以时钟域越少越好能共用主时钟的模块尽量不要自己分频。常见的问题是模块A需要一个12.5MHz模块B需要一个9.6MHz模块C需要一个25MHz于是工程师直接用MMCM生成三个时钟输出。MMCM本身功耗倒不算特别大但三棵全局时钟树的功耗加起来比合并成两个时钟域明显高出一截。更合理的做法是评估一下模块C能不能直接跑在MMCM的同一路25MHz上模块A和B能不能通过时钟使能的方式共享12.5MHz或者9.6MHz。如果你确实需要真正的次生时钟域那么同步器的位置和级数要非常小心。跨时钟域的同步器FF必须布局在目标时钟域附近否则路径变长不仅时序难收敛中间节点的多余翻转还会额外耗电。建议每个跨时钟域信号至少打两拍并对多bit信号使用握手或者异步FIFO不要自作聪明直接打拍那种做法在功耗和可靠性上都埋雷。2.3 实例UART_RX接收器与SPI ADC采样的时钟优化UART_RX是FPGA入门几乎必写的模块。很多教程会教你直接用本地时钟分频出一个比特率时钟比如9600bps就分频得到9600Hz。这种做法从功能上没错但从功耗角度非常不划算。9600Hz的时钟树在整个芯片上传播为了一个慢速串口白白让几千个寄存器的时钟端每个周期翻转一次。更好的做法是保持所有逻辑挂在系统主时钟上用波特率时钟的使能脉冲来采样RX引脚。接收状态机仍然以系统主时钟运行但只有当波特率使能有效时才判断电平、移动位索引。这样接收逻辑的功能不变时钟树却只有一棵。同样道理SPI ADC采样的SCLK信号在FPGA内部也应该尽量用IO资源直接输出而不是用任意计数器分频产生的内部时钟驱动。SPI的SCLK完全可以由状态机在系统主时钟下翻转引脚产生采样点则用时钟使能判个延时。这种设计还有一个额外的好处就是STA时序分析变得简单。所有时序路径都在同一个时钟域内不再需要处理跨时钟域的约束工程收敛速度快得多功耗也更低。3. 硬核技巧二数据翻转率省电的“隐形赛道”3.1 翻转率与总线编码动态功耗公式里的α讲的就是信号翻转的频率。信号每翻转一次负载电容上的电荷就要被充放一次。一个32位总线在100MHz下如果每个周期所有位都在0和1之间来回跳相当于每秒钟有32亿次电平翻转功耗相当可观。很多高性能设计的功耗问题根源不在逻辑本身的复杂度而在总线上的数据模式太“活跃”。常见的优化手段是给总线做编码。最经典的是格雷码相邻两个值只有一位不同计数器、FIFO指针这类连续递增的信号用格雷码翻转率能砍掉一大截。异步FIFO的读写指针本来就是跨时钟域传递用格雷码既是功耗优化又是跨时钟域安全的标准做法。对于随机数据总线格雷码就派不上用场了可以用总线反转编码Bus-Invert。思想很简单发送端把当前数据与前一个数据逐位比较如果将要翻转的位数超过总线宽度的一半就把数据取反再发送同时用额外的标志位告诉接收端数据被反转了。这样任意两个随机数据之间实际翻转的位数最多只有一半加上标志位也划算。这个方案在DDR控制器内部可能用不上因为协议固定了但用在自定义的板级并行总线、片间通信链路上效果非常直接。3.2 乒乓缓存、DDR突发与FIFO指针的功耗设计多端口DDR读写程序是很多FPGA项目里最烧功耗的部分尤其是多个主机端口共享同一个DDR控制器的时候。如果各端口随机发起小的读写请求DDR控制器会频繁在不同bank之间切换命令总线和数据总线上的翻转率都会很高更不用说刷新和预充电带来的额外命令。优化手法是引入乒乓缓存把各端口零散的读写请求先在FPGA内部攒成比较大的数据块再以较长的突发长度统一写到DDR里。举个例子一个图像采集端口每个水平行产生几千字节数据如果来一行就写一次DDR总线上的读写命令密集且分散如果先把几行的数据攒进乒乓缓存凑够16KB甚至32KB再以DDR burst方式一次性写入DDR控制器的调度压力会小很多总线的有效翻转率也会下降。实测下来仅这一个调整就能让DDR相关功耗降低20%到30%同时带宽利用率反而更高。乒乓缓存本身也是功耗优化的一部分。两块BRAM轮流作为写入缓冲和读取缓冲避免了数据在单块缓冲里读写冲突造成的等待与空转。空闲的一方可以关闭BRAM的片选使能减少位线充放电。3.3 图像处理场景里的数据调度技巧图像处理项目里双线性插值、边缘检测这类算法会频繁读取窗口内的像素数据。如果每个像素都去DDR里重新取总线上的数据访问毫无规律翻转率会高到吓人。正确做法是用Line Buffer把一行甚至几行数据缓存在BRAM里窗口滑动时只需要从BRAM里取相邻像素。BRAM内部的位线和数据线比外部DDR总线短得多翻转功耗小一个数量级。以边缘检测特征提取项目为例一个3x3的Sobel卷积核需要同时访问当前行、上一行、下一行的相邻像素。用两个Line Buffer分别缓存相邻行窗口逻辑只做寄存器阵列的平移和复用既把乘法器数量压到最少又避免了反复访问外部存储器。还有一点容易被忽略图像数据本身有天然的连续性和周期性。对相同场景的相邻像素差分编码后再搬运比直接传输原始像素值少很多翻转。比如传输一帧纯色背景图像像素值几乎不变差分编码时数据总线基本不跳但原始RGB24格式每个像素三位都在跳。这类编码不改变算法的数学结果却能从源头降低总线活动率。4. 硬核技巧三资源瘦身——DSP和BRAM比LUT更省电4.1 乘累加用DSP块而不是LUT阵列FPGA里的乘加运算可以用两种方式实现用通用LUT搭出来的组合逻辑或者用硬件乘法器DSP块。很多初学者在做SPI ADC数据滤波或者Costas环计算误差项时顺手写几行乘法代码就交给综合器处理谁知综合器默认可能用LUT实现结果就是几百个LUT同时翻转功耗又高、时序又紧。DSP块是芯片上专门为乘加运算设计的硬核电路它的内部布线极短信号翻转需要的能量比LUT网络低得多。一个乘法宽度在25x18以内的乘法器放到DSP块里实现总体功耗通常只有LUT实现的一半甚至更低。Vivado里的写法很简单直接用乘法运算符并且让综合工具推断DSP块即可。如果发现没有被推断可以用综合属性强制指定例如(* USE_DSP yes *) wire [15:0] mul_result; assign mul_result a * b;在Vivado的SYNTHESIS属性里也有一项DSP Utilization建议设成Auto或者Max让工具尽量把乘加运算映射到DSP块。需要注意DSP块在空闲时也有基础功耗所以不是所有乘法都适合塞进去。极端重要的浅流水运算比如一个周期做大量并行的乘法全用DSP反而可能让DSP资源拥塞、布局变差。平衡点是占用率控制在总DSP资源的70%以内。4.2 用BRAM替代寄存器堆布线电容大幅下降另一个常见的资源浪费是用大量寄存器FF来实现数据存储。FPGA里的FF是分布在逻辑单元里的每个FF所在的位置距离其他逻辑的物理距离都有差异大量FF互连需要经过可编程布线资源布线电容远大于BRAM内部的专有位线。所以数据量稍大的存储无论FIFO、移位寄存器还是缓存阵列都应该优先考虑BRAM或分布式RAM而不是FF。以图像处理里的Line Buffer为例一帧1080p图像的一行是1920个像素灰度图每像素8bit一行就是15360bit。如果用FF存储就要一万五千多个FF它们之间的移位互连功耗很高。如果用BRAM一行数据被组织成1920x8的存储单元每个时钟周期读写一个地址位线长度固定且极短。实测在这种场景下BRAM方案比FF方案省电至少40%同时逻辑资源占用也大幅下降。很多FPGA入门项目里的经验值单个32bit FIFO深度不超过16时用FF没问题深度超过64就应该换成BRAM或分布式RAM串行移位寄存器超过32拍可以考虑SRL16实现。SRL16是FPGA里专用于移位寄存器的硬结构它的功耗和资源消耗只是普通FF链路的零头。4.3 综合策略FSM编码与逻辑复用状态机FSM的编码方式也直接影响翻转率。常说的独热码One-Hot编码每个状态只有一个bit为1状态转换时只需要翻转两个bit组合逻辑简单时序容易收敛所以在高频设计中很受欢迎。但代价是独热码的寄存器数量等于状态数量状态多时翻转的bit总数并不少功耗比二进制编码高。二进制编码每一个周期可能多个bit同时翻转但寄存器数量少。折中的是格雷码适合状态数量少且状态切换呈顺序性的FSM。我的经验是状态数量少于8且切换有规律的FSM用二进制或者格雷码状态数量多、状态跳转发散、需要跑高频率的FSM用独热码但尽量增加状态译码逻辑的复用度。Vivado里可以通过综合属性修改FSM编码方式也可以用工具自动选择合适的编码策略。另一个重要的瘦身方向是逻辑复用。很多模块都有相似的运算结构比如多个通道都需要做相同的滤波系数计算完全可以把通道运算单元合并成单个算子通过时分复用和时间片轮转来实现多通道。代价是性能会略降但只要数据吞吐量允许功耗收益非常明显。多端口DDR读写项目里多个主机的命令仲裁逻辑如果写得很散每个端口一套独立的调度状态机那么控制逻辑的翻转面积会成倍放大。把仲裁器集中起来所有端口共享一个调度核心功耗与代码可维护性都能改善。5. 硬核技巧四电压与选型从源头锁死功耗5.1 内核电压、I/O电压与功耗的平方关系动态功耗公式里电压是平方项这意味着电压对功耗的影响远非线性。内核电压从1.2V降到1.0V动态功耗会降到原来的0.69倍相当于直接省了大约30%的功耗。所以很多有低功耗需求的FPGA项目在选型时就会选低电压系列的器件比如Artix-7系列主内核电压就是1.0V相比一些老工艺的1.2V内核先天就占了便宜。I/O电压同样遵循平方关系。同样是LVCMOS信号从3.3V降到1.8V每个引脚的翻转功耗只有原来的三分之一不到。如果一块板子上有几十路GPIO在高速翻转这个差距会非常明显。举个例子一个项目原本用3.3V LVCMOS驱动并行LCD屏数据总线16bit、时钟几十MHz调整到1.8V电平标准后接口部分功耗从200多mW降到100mW以内而逻辑功能完全不受影响只需要电平转换芯片和相应配置。5.2 I/O标准与终端匹配电阻的取舍I/O功耗里有一块容易被忽略的开销那就是终端匹配电阻。高速接口如LVDS、LVPECL通常要求端接电阻这些电阻上流过的直流偏置电流是持续存在的。LVDS的电流大约3.5mA单通道功耗不算高但要是有几十对LVDS接收通道几十毫安的持续电流就出来了。LVPECL更夸张端接电阻上的电流能有十几毫安功耗比LVDS翻几倍。设计时对非高速信号尽量选CMOS接口对高速信号能用LVDS就不用LVPECL。MIPI、LVDS这类差分接口的功耗主要是终端电流而不是翻转频率所以通道数量和链路速率才是优化重点。如果板卡上有多路LVDS图像输入并且同时工作可以评估是否能用时分复用把多路合并到更少通道上或者在不采样时把接收通道置于闲置状态。另外FPGA内部默认的上拉、下拉电阻也不要忽视。一个引脚上拉到3.3V如果外部驱动为低电平漏电流就会一直存在。几十个误设为上拉的输入引脚加起来可能几十毫瓦看似不大但在电池供电的便携设备里就是续航掉电的隐患。5.3 器件选型速度等级、温度等级与静态功耗买FPGA时速度等级几乎默认选最高的那档因为速度快意味着时序裕量足。但高速级器件往往需要更高的内核电压或者更灵敏的工艺调节静态泄漏也会略微增大。对不需要极高性能的项目选中档速度等级反而更省功耗。温度等级的影响主要分成两方面一是在同样功耗下工业级芯片可以承受更高环境温度板卡设计时可以少用风扇或者不用风扇二是前面说过静态功耗随温度指数上升如果环境温度经常超过70℃泄漏功耗增长会非常明显高温应用该用工业级就选工业级别在商用级上硬扛。还有一点对长续航设备非常重要就是FPGA配置完成后如果长期处于空闲状态应该进入配置保持或待机模式。很多FPGA支持在空闲时关断PLL输出、使能低功耗模式甚至通过配置接口进入掉电保持状态。这些功能在数据手册里都有但实际项目里往往只要不跑功能就默认保持全速运行白白浪费几百毫瓦。6. 硬核技巧五动态功耗管理与运行期策略6.1 模块级时钟门控与电源域划分前面说的时钟使能属于长期静态优化实际运行时功耗管理还可以更动态一点。比如通信测试终端这类设备大部分时间工作在待机状态只有收到命令才需要启动收发逻辑。这时待机逻辑应该只保留必要的唤醒电路其余模块的时钟全部关闭。FPGA里的时钟门控可以用BUFGCE原语完成。BUFGCE是带时钟使能的全局缓冲器使能拉低时时钟树停止翻转所有由该时钟驱动的寄存器都不再动态消耗能量。需要注意BUFGCE的使能信号必须与时钟同步否则容易产生毛刺。更稳妥的做法是先由全局时钟采样使能信号再输出到BUFGCE的CE端口避免门控边界出现glitch。电源域划分属于更高级的方案只针对支持多个供电域的型号才有意义。一般来说把高速收发器供电、DDR接口供电、核心逻辑供电拆成不同的电源轨软件可以独立开关每个电源域。这在ARM/FPGA边缘网关这类需要考虑整机功耗的产品里是常见做法。硬件设计阶段就把电源域规划好软件才能做细粒度的功耗管理这个诀窍最好在原理图阶段就想清楚。6.2 边缘网关与通信终端的动态降档方案边缘网关通常同时跑ARM和FPGAARM处理协议栈FPGA做数据采集和预处理。整机功耗里FPGA往往不是最大的耗电源但FPGA的动态功耗管理做不做直接影响整个网关能不能用电池供电。我在一个通信测试终端项目里的做法是划分四种工况空闲、扫描、抓包、满负载。空闲时FPGA只保留一个定时唤醒模块所有高速接口和PLL关闭整板电流降了一半多扫描时打开部分采样通道时钟跑一个低频率档位抓包时保持高速收发器工作但只在触发条件满足时连续抓取满负载才运行全部逻辑和多端口DDR读写。这几种工况之间通过ARM端的控制寄存器切换FPGA内部的时钟管理器根据寄存器值动态切换PLL输出频率和时钟使能。动态切换时钟频率时要注意两点一是切换过程必须先切换时钟源到稳定状态再关闭旧时钟否则存储器件里的数据可能丢失二是时序约束必须覆盖最低频率和最高频率两个工作点确保任何一档都能满足建立保持时间。6.3 接口链路自适应速率切换的做法高速接口的功耗大头在收发器。PCIe、EMMC、MIPI这类接口在高速模式下消耗的电流是固定偏置和实际传输多少数据关系不大。所以最省电的做法不是降低接口速率而是尽量缩短高速工作时间让接口尽快进入低功耗状态。以PCIe为例链路支持L0s、L1等节能状态。在数据传输间隙可以让链路进入L1状态物理层的发送和接收电路停止工作。速率本身也可以从Gen3降到Gen2甚至Gen1代价是带宽减半但功耗能降一大截。对实时性要求不高的通信测试终端来说这种动态速率切换很实用。MIPI接口同样可以在空闲时关闭时钟通道和数据通道。需要注意关闭再唤醒是有延时开销的所以切换策略要做滞后处理避免因为频繁进进出出而导致性能抖动。比较好的做法是设定一个空闲超时时间比如连续10ms没有数据就进入休眠一旦检测到新的帧起始信号再快速唤醒。7. 功耗测量与排查别靠摸用数据说话7.1 实测功耗的方法与工具靠手摸判断温度是很多工程师的通病这玩意儿根本没有量化标准。我现在的习惯是在硬件调试阶段就把功耗测量通道预留好核心电源和IO电源的磁珠或者跳线位置留出电流采样电阻位置方便用万用表串进去测量。条件好一点的直接用直流电源分析仪或者高端万用表记录电压电流曲线。测量时要注意采样电阻位置。如果采样电阻放在负载的高侧万用表内阻会造成额外的压降FPGA内核电压可能跌落影响工作状态。最好放在低侧GND回路或者用4线开尔文接法避免线损。高速翻转的大电流瞬变也需要关注如果万用表无法捕捉瞬态可以并联一个示波器电流探头或者用功率分析仪。7.2 VIVADO功耗分析流程Vivado自带的Report Power可以给出比较准确的预估前提是你提供的信息足够完整。跑完综合或实现后在Flow Navigator里点Report Power先把环境温度设置成实际工况再加载仿真得到的信号翻转信息VCD或者SAIF文件都可以。如果不加载翻转信息工具会按默认的无脑翻转率估算结果偏差很大。我的用法是先写一个覆盖主要工作状态的Testbench把所有关键模块都激励起来跑几十微秒生成VCD文件再用这个VCD更新功耗报告。这样算出来的数值比纯静态估算靠谱得多。有了报告之后按第一章说的分类框架看每部分的占比时钟网络占比太高就回头查时钟域设计逻辑部分占比高就查FSM编码和算法实现方式I/O占比高就查电平标准和端接。7.3 发烫排查清单与常见误区如果板子已经很烫光靠功耗报告还不够快速排查顺序建议如下外部负载的问题优先查GPIO有没有对外短路或电平冲突终端电阻是否接错上拉电阻是否过大。时钟频率确认有没有模块其实根本不需要那么高频率只是因为“一直这么写的”而跑着高速时钟。复位逻辑检查很多项目里每个寄存器都接了异步复位复位信号翻转时所有寄存器同时动作功耗高且时序难收敛。不是所有寄存器都需要同步复位能省则省。综合约束检查有没有为了凑时序margin而牺牲面积和功耗比如综合策略选错了优化目标。散热再确认如果芯片长期接近满载运行散热片、风扇、PCB铜箔散热面积都能影响静态功耗的恶性循环。还有一个常见误区是“功耗优化就是降频”。频率降低确实能省动态功耗但如果性能指标是在特定频率下才能满足的降频会导致系统需要更长时间工作总耗电量反而更高。真正该做的是减少无谓的时钟翻转和数据翻转而不是一刀切降频。正确顺序是先做时钟使能、减少冗余翻转、优化总线访问模式最后才考虑整体降频。另外要特别提醒Vivado的布局布线策略里有一项Power Optimization实际效果通常有限但它会显著增加编译时间。真正起决定性作用的是RTL设计阶段的时钟与数据调度决策工具层面的优化只是锦上添花。这套方法在最近几个FPGA项目实战里反复用过。从最初盲目加散热片到后来把功耗算清、把时钟域合并、把总线翻转率控住整个过程下来最早那块Zynq板卡的整机功耗降了大概三分之一核心温度压到了60℃出头交付后的长稳测试也没有再出现热复位。省下的不仅仅是电费更是整个系统的可靠性和调试时间。希望这篇文章能让你下次遇到FPGA发烫、续航崩的问题时先拿起计算器和功耗报告而不是伸手去摸散热片。
返回列表