ARTICLE DETAIL

资讯详情

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

UPF低功耗设计核心:电源开关与状态保持详解

UPF低功耗设计核心:电源开关与状态保持详解 做SoC的同学应该都有感觉功耗问题已经不是后端设计末期补一刀能解决的事了。芯片规模越大、工艺节点越小漏电流和动态功耗的约束就越紧尤其做物联网、可穿戴这些电池供电的产品低功耗设计甚至从一开始就决定了方案能不能落地。这几年我用得最多的工具就是UPFUnified Power Format统一功耗格式它能把“哪个模块在什么时间关电、关电后信号怎么隔离、哪些寄存器要保存状态、恢复供电后怎么回来”这些功耗意图从RTL阶段一路带到后端物理实现。这篇文章我打算把UPF里两块最核心的内容——Power Switch和State Retention——结合一个典型的多电压域设计案例完整拆一遍并分享一些我看过和踩过的坑。适合正在做数字前端设计、低功耗综合、后端实现以及低功耗验证的朋友参考当然如果你只是对SoC功耗架构感兴趣也能从中弄清楚很多“软件层控制不了”的硬件细节。1. 先从功耗架构说起为什么需要UPF1.1 功耗意图必须前移我记得早期做设计时RTL代码里基本只描述功能逻辑时钟门控、多电压、电源关断都是后端实现阶段才考虑的事情。工艺老一点漏电问题没那么突出差不多能对付过去。但是到了28nm以下漏电流成为待机功耗的主要来源光靠时钟门控已经关不掉漏电必须真正把某些模块的电源切掉。而这个“切电源”的动作牵扯到一大堆设计意图哪个模块是一个电压域这个域什么时候可以关关的时候输出怎么处理哪些状态要保留这些意图如果不在前端定义好后端和验证根本没法做。UPF就是这个功耗意图的统一载体。它在IEEE 1801标准里定义了一种描述电源架构的语言把电源端口、电源网络、电压域、电源开关、隔离单元、电平转换、状态保持等要素用标准命令描述出来。同一个UPF文件前端综合、形式验证、低功耗仿真、后端布局布线、静态时序分析、功耗分析都能读整个流程就不会出现“前端说跟后端理解不一致”的扯皮。提示UPF的完整标准是IEEE 1801。现在多数工具支持UPF 2.1和UPF 3.0。写文件前最好先确认工具版本支持哪种语法后面我会单独说版本兼容问题。1.2 多电压域到底在管什么多电压域就是芯片内部存在多个电压值不同的电源域不同模块各用各的电压。这么做一是性能需要比如CPU内核要跑高频需要0.9V甚至更高电压音频、传感器接口这类小电路用0.8V就够。二是功耗需要低电压运行模块的动态功耗可以显著降低。而真正的低功耗收益来自电源关断某个电压域在不工作时通过电源开关把供电切断让这个域内所有逻辑彻底没有静态功耗。为了支撑这种“既可以独立供电、又可以独立断电”的结构芯片里会加几类基础单元电源开关Power Switch串联在供电路径上的开关单元控制一个域是否上电。隔离单元Isolation Cell当某个域断电时它的输出会变成未知态必须用隔离单元把输出钳到一个固定值避免影响仍然上电的域。电平转换单元Level Shifter当两个域工作电压不同信号跨域时必须做电平转换否则会出现逻辑误判。状态保持寄存器Retention Flop在主电源关断后备份电源继续给保持用的锁存器供电保住关键状态恢复供电时再把状态装回去。打个比方整套芯片就像一个办公楼。大楼总电闸是主电源各楼层配电箱是电压域房间里插座是模块。Power Switch就是房间的墙开关关灯后房间里虽然不耗电但走廊还要亮着隔离就是门口那道门防止黑房间里的人朝走廊喊话Retention就像是房间里的应急照明和不断电保险柜断电了但关键东西没丢。1.3 UPF在整个流程里的角色UPF文件本身不直接生成电路它描述的是意图由EDA工具去具体实现。我做过的项目里UPF的输入通常包括电源端口定义、电压域划分、电源开关映射、隔离和电平转换的插入规则、状态保持规则、上下电状态定义。综合工具拿到RTL和UPF后会按照电源域重新组织设计把需要的低功耗单元插入网表并产出带UPF注释的网表。后端PR继续用同一套UPF信息做电源网络布局与绕线验证工具则用它做低功耗仿真的电源意图配置。可以说UPF是整个低功耗设计的主线。刚开始接触低功耗设计的朋友经常把UPF想得很玄其实它就是一份文本文件核心是“说清楚谁跟谁在一个域、谁的电源由谁控制、断掉之后怎么办”。所有命令都围绕这三个问题展开。理解了这一点看懂和使用UPF就不难了。2. Power Switch核心细节如何管好每一路电源2.1 开关类型与选型原理Power Switch是power gating的核心器件。它做的事情很简单在电源网络和电压域内部电源网络之间加一个开关使能信号为高时域供上电为低时域断电。常见实现分两种。一种是header switch就是把PMOS开关串在VDD和内部VDD之间控制上管电源另一种是footer switch把NMOS开关串在VSS和内部VSS之间控制地。实际SoC里用得最多的是header switch因为对于同样的导通电流PMOS压降特性更好控制而且把开关放在VDD侧地网络更干净对噪声和闩锁效应也更好。也不是说footer不用有些库也会提供footer结构主要取决于工艺库和电源网络布局习惯。开关单元不是单个管子而是一组管子并联在一起做成标准单元或者可综合的库单元。开关尺寸设计要平衡几个矛盾尺寸太小导通阻抗大电压域内部IR drop明显严重时逻辑翻转速度下降甚至功能出错尺寸太大芯片面积大而且关断状态下的泄漏路径也更宽。往往需要在版图阶段做多轮IR drop和EM电迁移检查。另一个常被忽略的参数是开关的输入电容控制信号EN要驱动大量并联管子的栅极这个电容会影响PMU的面积和时序收敛。2.2 UPF里怎么声明电源开关用set_power_switch命令描述电源开关。一个典型的写法create_power_switch SW_CPU -domain PD_CPU \ -output_supply_port {VDD_CPU VDD_CPU} \ -input_supply_port {VDDC VDDC} \ -control_port {EN EN} \ -on_state {on_state VDDC {EN}}这条命令表示在PD_CPU域内创建一个名为SW_CPU的电源开关输入电源是VDDC输出是VDD_CPU控制信号EN为高时开关导通VDDC和VDD_CPU连通。这里的信号名要和库单元引脚对应好具体取决于你用的库。如果开关单元的电源引脚命名和这个不完全一致工具在PR阶段会报错或者无法自动连接。有些库的电源开关还支持低有效控制或者多个控制端口比如增加一个retention控制端口用于在Main Switch关闭时让retention电源继续供电。这类语法在UPF里通常是给电源开关增加额外的on_state或者单独用bind_unrelated_supply_net把备份电源绑到开关单元。具体字段可以在工具参考手册里查我一般先确认库单元的电源架构再写文件。2.3 控制信号与上下电时序Power Switch本身不难难的是控制它的时机。芯片里通常有一个常开的PMU电源管理单元负责决定什么时候关哪个域、什么时候恢复。关电不是简单把EN拉低就完必须保证域内逻辑处于安全状态否则会产生X态传播、总线冲突、数据丢失等问题。一次典型的关电顺序是这样停止新事务处理器或总线先通知域内模块进入空闲状态。保存关键状态给retention寄存器发save信号把需要保持的内容锁存到备份锁存器。隔离域输出置位隔离单元的使能信号让域输出被钳到安全值。关断时钟切断该域时钟避免关电瞬间还有时钟沿触发逻辑。拉低电源开关EN真正断掉主电源。上电恢复顺序基本相反先拉高EN恢复供电等电源稳定后解除隔离恢复时钟然后发restore信号把之前保存的状态装回去。每步之间可能都要等若干微秒级延迟具体时间来自电源稳定时间和时序约束不能拍脑袋乱写。UPF本身不负责生成这个顺序时序由PR和约束保证顺序逻辑由PMU实现。但UPF里会描述电源状态power states和开关状态方便验证工具检查这些时序。2.4 实现阶段必须避开的坑我在实际项目里遇到过几个跟Power Switch相关的坑。首先是开关关断后输出端浮空的问题。VDD_CPU被开关断开后域内所有逻辑失去电源但网络不是立刻变到0V会有个浮空残留电压。如果不做隔离这些浮空信号飘到其他上电域很容易导致通路漏电甚至闩锁。所以只要有power gating域隔离不是可选项是必选项。隔离使能信号必须来自常开电源域不能来自被关断的域否则隔离单元自己都没电。其次是开关单元的驱动能力分配。一个大电压域内部可能有几万个标准单元需要的电流很大单个开关单元不够通常会在电源网格上均匀分布几百个开关单元。分布不均匀会导致域内不同区域IR drop差别很大——靠近开关的地方电源干净远端电压低。这个问题我在低功耗仿真的功耗分析阶段通常能发现IR drop不好时会直接在物理设计阶段爆出来。比较好的做法是让后端工具基于UPF中的电压域面积自动综合power switch组然后再人工检查密度。注意EN控制信号必须是常开域的信号并且路径延迟要检查。我看到过因为EN信号经过长走线导致开关开启时间不一致部分区域先上电、部分后上电产生短时间大电流。3. State Retention电源断了数据不能丢3.1 Retention寄存器的工作原理Power Switch负责关电但很多系统希望在唤醒后继续执行关电前的任务比如CPU的流水线状态、硬件定时器计数值、加密引擎的上下文这些数据如果断电就丢了重新初始化成本很高。Retention单元就是为了解决这个问题。Retention寄存器和普通寄存器结构不一样。普通寄存器在电源关断后完全失态而retention寄存器内部多了一套由备份电源供电的保持锁存器、还有一套保存/恢复机制。正常工作模式寄存器本身由主电源供电功能上就是个普通寄存器进入关断前发出save信号把主寄存器里的数据复制到备份锁存器里保存主电源关断后备份锁存器靠VDD_AON这个常开电源维持恢复上电后发restore信号把备份锁存器里的数据写回主寄存器。要注意的是save和restore信号本身不能来自会被关断的逻辑一般由PMU统一产生并且要保证时序裕量。save之后、电源稳定之前的窗口长度需要满足库单元要求太短数据还没锁存就断电那就白保存了。从版图上看retention cell比普通寄存器多一组电源引脚布局时要保证备份电源网络能覆盖到这些单元而且这些单元的备份电源引脚不能走太细的金属线否则在关断状态下也会出现近端远端供电差异影响保持可靠性。3.2 UPF里怎么描述状态保持用set_retention命令描述状态保持意图。一个典型的写法set_retention -domain PD_CPU \ -retention_power_net VDD_AON \ -retention_control {SAVE_EN SAVE_EN} {RESTORE_EN RESTORE_EN} \ -elements {U_CPU/CORE_REGS}参数含义domain指定要加状态保持的电压域retention_power_net指定备份电源网络也就是常开的电源retention_control指定保存和恢复的控制信号elements指定要保留状态的寄存器或寄存器组。综合工具看到这条命令后会把这些寄存器map到库里的retention cell然后把保留电源网络正确连到它们的备份电源引脚。在实际RTL里如果某个模块的所有寄存器都要保持可以在UPF里用模块scope引用如果只想保一部分可以列出具体的寄存器路径。后端实现阶段retention cell会额外占用面积备份电源网络也要在布局布线中单独留出。所以做UPF时最好明确哪些状态必须保持、哪些可以从头再来。还有一个容易被忽略的地方retention控制信号的时序约束。SAVE_EN和RESTORE_EN都是异步控制信号需要设置set_false_path或者set_max_delay防止综合工具把它们当成数据路径去优化导致控制时序不满足库的要求。3.3 保留哪些状态怎么权衡整个域都加retention听起来很安稳但代价不小。retention cell面积比普通寄存器大30%到50%而且即便在主电源关断后备份锁存器仍然消耗漏电流几十万个retention cell的静态功耗加起来很可观。所以做设计时要做保留覆盖率分析对每个模块问三个问题第一唤醒后是不是继续执行第二如果状态丢失重建状态需要的软件或硬件开销有多大第三保留这些状态带来的额外漏电是否小于重建状态的开销。没有绝对答案比如音频解码器需要保留FIFO的位置和头信息加密引擎希望保留会话密钥CPU常用浅睡眠模式保留寄存器上下文GPU这类图形任务可以从头清屏往往不做retention直接整套关掉。我之前做过一款低功耗MCU一开始给整个CPU域所有寄存器都加了retention结果唤醒时间快了但DeepSleep下漏电流超标。后来把retention范围缩小到程序计数器、栈指针、状态寄存器这几个关键项其他通用寄存器通过软件压栈到备份SRAM漏电流降了不少。这个经验也说明UPF里写retention不是越多越好而是要跟软件配合起来找平衡点。4. 多电压域案例完整拆解从UPF文件到收敛4.1 案例顶层结构与电压域划分我拿一个典型物联网SoC来演示。这个芯片包含一个CPU域、一个GPU域、一个音频编解码域和一个常开电源域。系统的外部主电源是1.0V和1.8V其中1.0V给核心逻辑1.8V给IO和一些模拟模块。为了演示多电压域假设CPU和GPU逻辑电压需要1.0V音频编解码需要1.2V常开域和备份内存只用1.0V。划分如下PD_AON常开域包含PMU、实时钟、唤醒控制器、备份SRAM。这个域永远不关使用1.0V。PD_CPUCPU子系统的电压域可关断内部保留处理器关键寄存器上下文使用1.0V。PD_GPU图形或AI加速模块可关断不需要保留状态使用1.0V。PD_AUDIO音频编解码可关断需要保留少量状态使用1.2V。物理上这些域可能共用同一个主电源不同开关控制也可能单独由不同电源引脚供电。这里CPU、GPU、AON共用VDDC1.0VAUDIO用VDD_AUDIO1.2V。CPU域和GPU域分别由自己的开关控制这样可以单独控制。4.2 完整UPF文件示例与逐行说明下面是一个简化但结构完整的UPF描述包含电源端口、电压域、电源开关、隔离、电平转换和状态保持。注意实际项目里命令会更多我注释了一些关键点方便对照。# 顶层电源定义 create_supply_port VDDC -domain top # 1.0V主电源 create_supply_port VDD_AUDIO -domain top # 1.2V音频电源 create_supply_port VSS -domain top # 地 # 电压域划分 create_power_domain PD_AON -include_scope # 常开域 create_power_domain PD_CPU -include_scope # CPU域 create_power_domain PD_GPU -include_scope # GPU域 create_power_domain PD_AUDIO -include_scope # 音频域很多刚接触UPF的同事还会问create_power_domain怎么知道域里有哪些单元实际上就是靠include_scope加RTL的层次路径来划分。UPF里还可以用-elements手动指定但实际项目一般用include_scope把一个模块scope全部划进一个域简单直接。接下来要建立每个域内部的电源网络# 域内电源网络 create_supply_net VDD_AON -domain PD_AON create_supply_net VDD_CPU -domain PD_CPU create_supply_net VDD_GPU -domain PD_GPU create_supply_net VDD_AUDIO_INT -domain PD_AUDIO create_supply_net VSS_CPU -domain PD_CPU这些网络是域内的“虚拟电源轨”最终要跟顶层端口连接。连接方式有两种一种是通过电源开关连接一种是直接连接常开电源。对于AON域直接把VDDC连接过来connect_supply_net VDD_AON -ports {VDDC} connect_supply_net VDD_AON -domains {PD_AON}CPU域需要电源开关create_power_switch SW_CPU -domain PD_CPU \ -output_supply_port {VDD_CPU VDD_CPU} \ -input_supply_port {VDDC VDDC} \ -control_port {EN_CPU EN_CPU} \ -on_state {on_state VDDC {EN_CPU}}GPU域同理create_power_switch SW_GPU -domain PD_GPU \ -output_supply_port {VDD_GPU VDD_GPU} \ -input_supply_port {VDDC VDDC} \ -control_port {EN_GPU EN_GPU} \ -on_state {on_state VDDC {EN_GPU}}音频域因为是独立电源端口可以直接连接create_supply_net VDD_AUDIO_INT -domain PD_AUDIO connect_supply_net VDD_AUDIO_INT -ports {VDD_AUDIO}接着是隔离和电平转换。CPU域关断时它的输出要钳到安全值需要在PD_CPU上做隔离同时PD_CPU的输出要送到AON域两者电压相同不需要电平转换但如果CPU输出到音频域1.2V就需要电平转换。以CPU域输出隔离为例set_isolation ISO_CPU -domain PD_CPU \ -isolation_power_net VDD_AON \ -isolation_control {ISO_EN_CPU ISO_EN_CPU} \ -clamp_value 0 \ -applies_to output set_isolation_control ISO_CPU -domain PD_CPU \ -isolation_sense high \ -location self这条定义要求PD_CPU域的所有输出信号在ISO_EN_CPU有效时被钳到0V。isolation_power_net指定隔离单元接常开电源保证即使PD_CPU断电隔离单元也能工作。isolation_sense high表示信号高有效。location self表示隔离单元放在输出端本域一侧。电平转换比如CPU与音频域之间set_level_shifter LS_CPU_AUDIO -domain PD_CPU \ -applies_to output \ -threshold 0.7再比如状态保持对CPU域核心寄存器set_retention -domain PD_CPU \ -retention_power_net VDD_AON \ -retention_control {SAVE_CPU SAVE_CPU} {RESTORE_CPU RESTORE_CPU} \ -elements {U_CPU/regs/core_*}最后是电源状态定义也就是所谓的power state tableadd_power_state PD_CPU -state normal -supply_expr {VDD_CPU eq VDDC} add_power_state PD_CPU -state off -supply_expr {VDD_CPU eq OFF} create_pst PST_TOP -supplies {VDDC VDD_AUDIO} add_pst_state ON_ON -pst PST_TOP -state {normal normal} add_pst_state ON_OFF -pst PST_TOP -state {normal off}这些命令加起来基本就是一个多电压域UPF的骨架。实际项目还会增加UPF closures、isolation rule、retention rule的细分比如针对不同输出方向、不同信号网络单独设置。4.3 多域协同关断的顺序与策略多电压域设计里比单域麻烦的是域间依赖。以这个芯片为例CPU关断前如果音频域还在工作且CPU有信号要发给音频域隔离是必须的。而GPU自己可以随时关断关断时对CPU的影响要看有没有跨域数据通路。通常PMU里会维护一个“当前允许进入的电源状态机”比如CPU要关断需要先让总线和中断控制器停止对这个域发起请求AON域里的唤醒控制器在低功耗状态下仍然工作能检测外部事件按键、定时器、RTC闹钟并触发恢复流程。恢复时PMU首先给EN_CPU拉高等待电源稳定后解除ISO_CPU然后恢复时钟再给retention发restore。这套时序在验证阶段要专门跑低功耗仿真检查每条约束是否满足尤其是save/restore与开关时序之间不能有交叠。还有一个实际问题是域与域之间的电平转换位置。如果CPU输出到音频域SL应放在PD_CPU输出还是PD_AUDIO输入会影响功耗和时序。按UPF默认规则level shifter一般放在发送域或接收域都有取决于工具library支持。通常我倾向放在接收域因为电平转换后的高电平要与接收域电压一致更符合信号完整性要求。不过如果接收域经常断电shifter放接收域就会因为缺电失效这时反而要放发送域这点要根据具体power down组合来定。4.4 工具检查与收敛清单UPF写得好不好不是编译过了就算结束。实践中我至少会做三类检查。第一是UPF静态检查。用EDA工具的UPF check功能检查电源连接是否有悬空、隔离规则是否覆盖所有需要隔离的输出、retention元素的电源网络是否都已连接、是否存在一个域同时接两个主电源之类的问题。第二是低功耗仿真。在仿真工具里加载UPF加入低功耗单元的行为模型模拟关断、保持、恢复过程。这种仿真能暴露X态传播、隔离时序冲突、retention save窗口不够等问题。低功耗仿真的关键是要给UPF里的控制信号EN、ISO_EN、SAVE、RESTORE配合实际的testbench激励只做语法编译没有意义。第三是物理实现的电源网络检查。IR drop、EM、电源网格密度都是这阶段重点。多电压域里尤其注意不同电源网络的布线层设置防止电压域间电源网络意外短路或间距违例。以下是我常用的收敛清单检查项工具/方法通过标准电源网络连接完整性UPF静态检查无悬空、无漏连隔离规则覆盖连接性分析所有关断域输出已隔离retention备份电源网表检查备份电源连到常开电源电源开关逻辑低功耗仿真上下电时序无X态IR drop功耗分析各域IR drop在库要求范围内电平转换覆盖跨压域分析所有跨域信号已加shifter5. 常见问题与排查技巧实录5.1 唤醒后数据错乱retention失效现象芯片从低功耗状态唤醒后程序跑飞或者硬件状态错乱反复复现。排查思路我会先看retention cell的备份电源网络是否真连到了常开电源。网表里逐个检查retention cell的备用电源引脚百分之百能查出问题。常见原因有两个一是create_supply_net和connect_supply_net没有把VDD_AON连到顶层端口工具可能默认把备份电源接到了可关断电源结果一断电备份也没了二是save信号时序没满足导致保存的是中间态。对前者建议在UPF里显式给所有retention cell的retention_power_net指定不要依赖工具的默认推断对后者要用低功耗仿真专门分析save窗口。5.2 输出悬空引发功能异常现象某个被关闭模块的邻居模块出现不定态或者漏电异常。这种大多数是隔离缺失或者隔离使能信号接错。检查时先从UPF里查set_isolation的规则看是否覆盖了该域所有输出再看隔离单元的使能信号是不是连接到常开域。我遇到过因为隔离logic sense搞反本来用高有效写成低有效结果域一关隔离没生效把整个总线都带崩了。这种检查其实很机械就是在网表里跟随信号路径确认使能连接。5.3 上电时动态压降过大现象电源开关打开瞬间系统复位或者误触发看门狗。这是因为多个大电流域同时上电产生很大的inrush current。一种是硬件上错开上电时间比较常用另一种是UPF里定义电源状态让工具做上电顺序检查。如果开关驱动能力写得太大也会加剧浪涌需要控制在PMU允许范围内。还有个小细节很多库的power switch带软启动功能上电时通过限制栅极驱动电流慢慢打开管子类似限流电阻的效果能有效降低浪涌。如果库里没有这个功能就要在PMU状态机里加时间错开各域的EN。5.4 工具链对UPF的差异UPF标准存在版本差异Synopsys、Cadence、Siemens EDA的工具对部分命令的支持不完全一致。不同工具可能对默认的isolation location有不同处理有的默认支持unplaced retention cell有的需要显式指定。跨工具流程时最好先做UPF AST check再进入主流程。如果老代码是用UPM旧格式写的迁移到UPF 2.1要注意命令改名比如dont_touch改成preserve语义也可能有变化。我见过团队因为工具升级旧UPF文件被新工具拒绝一查是-dont_touch和-preserve差异改完就过了。5.5 从MCU到SoC低功耗设计的分层实现讲完芯片级UPF我顺便提一句嵌入式方向。像STM32L151C8T6A这类超低功耗MCU芯片内部其实也做了类似“电源域划分”的处理只是对用户来说它们体现为软件可配置的Sleep、Stop、Standby等模式。你写一句HAL_PWR_EnterSTANDBYMode()背后就有模拟低功耗模块关掉主电源、保留唤醒逻辑在运行的过程唤醒后系统像复位一样重新启动就是因为它没有保留CPU上下文。而Stop模式会保留SRAM内容唤醒后从断点继续执行这就是retention策略在芯片上的体现。硬件工程师用UPF把这些策略设计出来嵌入式工程师通过配置寄存器和低功耗模式去使用两边目标一致在正确的时间关掉不必要的东西在唤醒时保持必要的状态。理解硬件层面这些机制再去选MCU和写低功耗固件思路会清楚很多。问题现象可能原因排查重点唤醒后数据错乱retention备份电源未连接、save时序不满足检查retention cell的备用电源引脚、save窗口被关域输出导致邻居域异常隔离缺失、使能信号接错set_isolation覆盖、隔离单元使能路径上电时复位或误触发watchdoginrush current过大、上电顺序不当检查开关驱动能力、错开各域上电时间工具报UPF语法错误版本差异、命令不兼容确认IEEE 1801版本、AST check、改命令名以上是我在实际项目中常用的排查方法不一定全面但对多电压域的常规问题足够用了。6. 最后再分享一个排查小习惯我最后想聊一个偏方法论的体会。做低功耗验证时很多人喜欢把所有信号都拉起来看波形结果又慢又乱。我的习惯是重点关注几个关键信号每个域的电源开关EN、隔离使能ISO_EN、retention的SAVE和RESTORE以及代表电源状态的assertion信号。把这几个信号按时间对齐看一遍上下电顺序和保持策略有没有问题基本一目了然。另一个技巧是给UPF里的控制信号单独做一条“功耗状态断言”比如在PMU里写一段SystemVerilog断言检查“CPU域断电期间ISO_EN必须保持有效”“SAVE有效后不能立即关EN”这类规则。有了断言回归测试的时候就可以自动发现时序违例不用等波形出来了再一条条翻。UPF跑多了以后你会发现真正的难点不在语法而在于你对你芯片的功耗策略理解得深不深——想清楚什么时候该关、保留什么、怎么恢复UPF只是把你的想法写出来而已。
返回列表