当前位置: 首页 > news >正文

9.【UPF】UPF Retention Strategies(UPF留存策略)

第一步:UPF Retention Strategies 分析与知识整理

1. 为什么学习Retention Strategies

  • 电源门控会丢失所有触发器状态。保持策略通过最小保持电压保留关键状态,实现快速唤醒。
  • 唤醒延迟从毫秒级(完全重新初始化)降到微秒级,使激进电源门控在响应式系统中可行。

2. 你将学到什么

  • 状态保持的概念及使用场景
  • 使用set_retention定义保持策略
  • 指定保持电源和控制信号
  • 为关键状态实现选择性保持

3. 理解状态保持

  • 问题:电源门控时,所有触发器状态丢失。唤醒后需要软件重新初始化,耗时毫秒级。
  • 解决方案:保持触发器具有双电源:
    • 主电源(VDD_domain):正常工作,可开关
    • 保持电源(VDD_RET):常开、低电压(0.6-0.8V),用于状态保存
  • 工作流程
    • 断电:断言保持控制信号 → 保持FF切换到VDD_RET → 关断VDD_domain → 保持单元用VDD_RET维持状态(极低漏电)
    • 上电:恢复VDD_domain → 解除保持控制 → 保持FF切回VDD_domain → 状态恢复,无需软件初始化
  • 唤醒时间:微秒级(vs 毫秒级无保持)

4. 何时使用保持

场景使用保持?理由
频繁电源循环快速唤醒值得保持开销
关键状态需保留重新初始化代价高或不可能
长时间睡眠(小时)可能保持漏电累积可能超过重新初始化成本
短时间睡眠(<1ms)重新初始化开销占主导
不频繁断电罕见唤醒时简单重新初始化更优

5. 保持触发器单元

  • 标准FF vs 保持FF
    • 保持FF额外需要VDD_RET电源和SAVE/RESTORE控制信号
    • 面积:1.3-1.5倍(大30-50%)
    • 活跃功耗:+5-10%
  • 重要:不要对所有FF使用保持,仅对关键状态使用。非关键状态可用标准单元以节省面积。

6.set_retention语法

  • 基本形式

    set_retention strategy_name -domain domain_name \ -retention_supply_set supply_set_name \ [options]
  • 关键参数

    • strategy_name:策略名(必须)
    • -domain:应用保持的域(必须)
    • -retention_supply_set:保持电源的供电集(必须)
    • -retention_condition {expr}:布尔表达式控制保持
    • -save_signal {signal sense}:保存状态的信号
    • -restore_signal {signal sense}:恢复状态的信号
    • -elements {instance_list}:指定保留的实例(默认所有FF)
  • 使用变体

    1. 基本保持(域内所有FF):
      set_retention RET_CPU -domain PD_CPU -retention_supply_set SS_CPU_RET -retention_condition {cpu_retention_enable}
    2. 显式保存/恢复信号:
      set_retention RET_GPU -domain PD_GPU -retention_supply_set SS_GPU_RET -save_signal {gpu_save_state high} -restore_signal {gpu_restore_state high}
    3. 选择性保持(特定实例):
      set_retention RET_CRITICAL -domain PD_CPU -retention_supply_set SS_CPU_RET -retention_condition {retention_en} -elements {cpu_inst/control_regs cpu_inst/status_regs}

7. 定义保持供电集

保持需要单独的常开保持电源。

  • 主电源VDD_CPU(可开关)
  • 保持电源VDD_RET(常开,0.6V)
  • 两个供电集:SS_CPU_ACTIVE(主)和SS_CPU_RET(保持)
  • 关联主供电集到域,保持供电集在set_retention中引用

8. 保持控制信号

  • -retention_condition:单信号控制,信号=1时保持激活(使用VDD_RET),=0时正常(使用VDD_CPU)
  • -save_signal-restore_signal:显式控制保存和恢复时序,用于复杂电源序列
  • 信号极性highlow,例如-retention_condition {!ret_en_n}表示低有效

9. 选择性保持

  • 使用-elements指定需要保持的实例,不指定则域内所有FF都替换为保持FF。
  • 优点:面积小、保持漏电低、综合快
  • 候选:控制寄存器、缓存标签阵列、TLB项、电源管理状态
  • 不保留:数据路径寄存器(ALU操作数)、临时变量、可重新计算状态

10. 完整保持示例

原教程给出了CPU域的完整UPF:包括常开TOP域、CPU域(主电源+保持电源)、电源开关、保持策略。并描述了断电和上电序列。

11. 保持单元映射:map_retention_cell

  • 语法map_retention_cell strategy_name -domain domain_name -lib_cells {cell_list}
  • 示例map_retention_cell RET_CPU -domain PD_CPU -lib_cells {DFFR_X1 DFFR_X2 DFFR_X4}
  • 综合工具将标准D触发器替换为保持变体。

12. 保持 vs 重新初始化权衡

  • 保持好处:快速唤醒、软件复杂度低、响应性好
  • 保持成本:面积+30-50%、常开保持电源(非零功耗)、额外控制逻辑、设计验证复杂度
  • 盈亏分析:当唤醒频率 × 节省时间 × 软件代价 > 保持面积 + 保持功率 × 睡眠时间 × 唤醒频率时,使用保持。

13. 常见初学者错误

  • 错误1:忘记创建保持供电集 → 必须先create_supply_set
  • 错误2:保持供电集使用可开关电源 → 必须用常开保持电源。
  • 错误3:不必要地保持所有FF → 使用选择性保持。

14. 实践练习

要求为GPU域实现选择性保持:主电源0.9V可开关,保持电源0.6V常开,仅保留配置寄存器和着色器状态,控制信号gpu_retention_enable高有效。

15. 总结

  • 状态保持通过常压低电压电源保留触发器内容,实现微秒级唤醒。
  • set_retention定义策略,需要保持供电集和控制信号。
  • 保持单元面积大30-50%,需双电源。
  • 选择性保持减少开销。
  • 适用于频繁电源循环的域,不适用于罕见或极长睡眠。

第二步:用费曼学习法学习UPF保持策略

保持策略(Retention)就是给芯片的“记忆”配一个UPS不间断电源——主电源断了,备用小电池还能记住关键数据,一恢复主电就能瞬间醒来。作为验证工程师,我的任务是确保这个备用电池(保持电源)永远有电,切换开关(控制信号)时序正确,并且不要给每个寄存器都配电池(太浪费)。本文用“电脑休眠”的比喻,帮你彻底搞懂:为什么需要保持?保持触发器怎么工作?如何用set_retention指定策略?以及如何避免“全盘保留”的面积陷阱。

我们着重讲什么?需要关注什么?为什么这样做?好处?如何学习使用?

着重讲解

  1. 保持的本质:双电源触发器,主电断后由低电压常开电源维持状态。
  2. set_retention的三要素:保持供电集、控制信号(条件或保存/恢复)、可选的选择性实例。
  3. 保持 vs 重新初始化:何时用保持,何时用重启。
  4. 选择性保持:只保留关键寄存器,面积和漏电都省。
  5. 必须的电源和开关配合:保持电源必须常开,且电源门控必须与保持控制协调时序。

为什么这样做:没有保持,电源门控后唤醒需要软件重新初始化所有寄存器,耗时毫秒级,用户体验差(手机亮屏慢)。有了保持,唤醒只需微秒级,瞬间恢复。

好处

  • 快速唤醒(微秒 vs 毫秒)
  • 软件简化(无需重新初始化代码)
  • 允许更频繁的电源门控,进一步省电

如何学习使用

  1. 先理解保持触发器结构:两个电源引脚,一个控制引脚。
  2. 手写一个简单的保持UPF:一个域,主电源1.0V,保持电源0.6V,一个控制信号。
  3. 用仿真器跑序列:断言保持控制 → 关主电 → 等一段时间 → 开主电 → 解除保持控制,检查寄存器值是否保留。
  4. 加入选择性保持:指定-elements只保留一部分寄存器,观察综合报告里哪些FF被替换为保持单元。
  5. 分析实际设计:找出哪些状态必须保留(如配置寄存器、状态机状态),哪些可以重新计算(如数据缓冲)。

下面按知识点展开,每个部分有通俗解释、代码示例和验证工程师的实战视角。


一、保持是什么?用“电脑休眠”比喻秒懂

通俗解释:你正在写文档,突然要离开。你可以选择:

  • 关机:完全断电,所有未保存数据丢失。回来要重新开机、打开软件、加载文档(毫秒到秒级)→ 相当于无保持的电源门控
  • 休眠:电脑把内存数据存到硬盘,然后断电。恢复时从硬盘读回内存,比关机快但仍有延迟 → 相当于无保持的电源门控但加了外部存储
  • 睡眠:电脑保持内存供电,其他大部分断电。一按键盘,瞬间恢复 → 这就是保持!内存(相当于寄存器)由低电压小电源维持,唤醒快如闪电。

在芯片里,保持触发器就是那个“睡眠模式下的内存”——用一个小电池(保持电源VDD_RET,0.6V)维持数据,主电源(VDD_domain,1.0V)可以完全关断。

技术实现:保持触发器内部有一个锁存器,当控制信号有效时,锁存器切换到VDD_RET供电,主电源断开后数据不丢。


二、set_retention三要素:电源、控制、范围

要素1:保持供电集(必须)

保持触发器需要第二个电源——常开的低电压电源。这个电源必须永远不断电(即使域关断)。在UPF中用独立的供电集表示。

create_supply_net VDD_CPU_RET -domain PD_CPU create_supply_set SS_CPU_RET -function {power VDD_CPU_RET} -function {ground VSS}

验证检查:VDD_CPU_RET必须来自常开域(如PD_TOP),并且add_power_state中不能有off状态,只能是ONRETENTION

要素2:控制信号

告诉触发器何时切换到保持电源。

  • 简单方式-retention_condition):一个信号,高电平表示保持模式,低电平表示正常模式。
    set_retention RET_CPU -domain PD_CPU -retention_supply_set SS_CPU_RET -retention_condition {cpu_retention_enable}
  • 精细方式-save_signal/-restore_signal):分开控制保存和恢复,适合复杂握手。
    set_retention RET_GPU -domain PD_GPU -retention_supply_set SS_GPU_RET -save_signal {gpu_save high} -restore_signal {gpu_restore high}

验证重点:控制信号必须来自常开域,否则断电后信号丢失,无法切换。另外,控制信号的时序必须正确:断电前先断言保持,主电源稳定后再解除。

要素3:范围(选择性保持)

默认set_retention会替换域内所有触发器为保持触发器,面积大增。通过-elements只保留关键寄存器。

set_retention RET_CRITICAL -domain PD_CPU \ -retention_supply_set SS_CPU_RET \ -retention_condition {ret_en} \ -elements { cpu_inst/control_regs cpu_inst/status_regs cpu_inst/mmu/tlb_entries }

验证检查:综合后查看报告,确认只有指定的实例被替换为保持FF,其他仍是标准FF。如果发现意外替换,可能是通配符范围过大。


三、保持电源电压:0.6V的秘密

为什么保持电压通常是0.6V左右?因为:

  • 太低(<0.5V):数据可能丢失,保持触发器内部锁存器翻转。
  • 太高(>0.8V):漏电显著增加,失去省电意义。
  • 工艺库会给出最小保持电压(V_ret_min),通常0.5-0.6V。

验证检查:确认add_power_state中定义的保持电压(如0.6V)不低于库的最小保持电压。同时检查保持电源是否独立于主电源——不能把VDD_RET和VDD_CPU短路。


四、完整序列:断电和上电的正确姿势

断电序列(以-retention_condition为例):

  1. 软件准备睡眠。
  2. 断言cpu_retention_enable = 1→ 所有保持FF切换到VDD_RET供电。
  3. 等待几个时钟周期(确保切换完成)。
  4. 电源门控:cpu_power_enable = 0→ VDD_CPU关断。
  5. 域断电,但VDD_RET仍供电,保持FF状态不丢。

上电序列

  1. cpu_power_enable = 1→ VDD_CPU恢复。
  2. 等待电压稳定(通常有power_good信号)。
  3. 解除保持:cpu_retention_enable = 0→ 保持FF切回VDD_CPU。
  4. 释放复位,CPU从之前的状态继续执行,无需重新初始化。

验证测试:写一个仿真用例:

  • 向保留寄存器写入已知值(如0x5A5A)。
  • 执行断电序列,模拟电源关闭(可用force使VDD_CPU为0)。
  • 等待一段时间。
  • 执行上电序列,读取寄存器,检查值是否仍为0x5A5A。

如果值改变,说明保持失效。常见原因:保持控制信号时序错、保持电源在主电断后也断了、或者该寄存器没有被替换为保持FF。


五、选择性保持:不要给整个房子装UPS

假设一个CPU有10万个寄存器,但只有1000个是关键的(配置寄存器、状态机、TLB),其余都是数据路径临时寄存器(可以重新计算)。如果对所有10万寄存器都使用保持FF,面积增加30-50%,可能多花几百万门,而且保持电源的漏电也会显著增加。

正确做法:只保留那1000个关键寄存器。其他寄存器断电后丢失没关系,软件唤醒后重新初始化即可(比如从内存加载配置)。

如何决定哪些寄存器需要保持?

  • 必须保留:电源管理状态、中断控制器设置、时钟分频系数、已配置的基址寄存器。
  • 可以不保留:正在处理的算术运算中间值、FIFO中的数据(可以从外部重新灌入)、缓存数据(可以从下一级缓存或内存重新加载)。

UPF实现

set_retention RET_CPU_CORE -domain PD_CPU \ -retention_supply_set SS_CPU_RET \ -retention_condition {core_retention} \ -elements { cpu_top/ctrl_regs cpu_top/status_regs cpu_top/mmu/tlb_valid }

验证检查:使用report_retention -elements查看哪些实例被保留。同时写测试:只保留部分寄存器,断电后检查未保留的寄存器是否变为X(表示未保持),而保留的寄存器值不变。


六、保持 vs 重新初始化:何时用保持?

原教程的决策表

  • 频繁电源循环(每秒多次)→ 用保持。
  • 关键状态必须保留 → 用保持。
  • 长时间睡眠(数小时)→ 可能不用,因为保持电源的微小漏电累计可能超过重新初始化的能耗。
  • 不频繁断电 → 不用,简单重新初始化更省事。

实际例子

  • 智能手机的CPU核心:在屏幕点亮时,可能每秒多次进入空闲再唤醒。用保持非常值得。
  • 物联网传感器:每隔几分钟采集一次数据,中间深度睡眠。如果保持漏电很低(nA级),也可以保持;如果漏电较高,不如完全断电后重新初始化。

验证建议:与系统架构师讨论唤醒频率和可接受的唤醒延迟。如果规格要求唤醒<50µs,则必须用保持;如果允许1ms,也许可以不保持。


七、保持单元映射:map_retention_cell

UPF的set_retention是抽象策略。综合时需要知道用库里的哪个具体单元来实现保持功能。

map_retention_cell RET_CPU -domain PD_CPU \ -lib_cells {DFFR_X1 DFFR_X2 DFFR_X4}
  • DFFR可能是“D Flip-Flop with Retention”的缩写。
  • X1,X2,X4表示驱动强度,工具会根据负载自动选择。

验证检查:综合后打开网表,搜索DFFR,确认数量与预期一致。同时检查没有用到不支持保持的库单元。


八、常见错误与避坑

错误后果正确做法
保持供电集使用可开关电源断电后保持电源也断,状态丢失保持电源必须来自常开域
忘记创建保持供电集就引用工具报错create_supply_set
对所有FF都用保持面积爆炸,漏电增加使用-elements选择性保持
控制信号来自可关断域断电后控制信号悬空,无法恢复控制信号必须来自常开域
断电序列中先断主电再断言保持保持未激活主电已断,状态丢失先断言保持,稳定后再断主电

九、完整代码示例:GPU域选择性保持

原练习要求:GPU域,主电源0.9V可开关,保持电源0.6V常开,只保留config_regsshader_state,控制信号gpu_retention_enable高有效。

答案(带注释):

# 顶层常开域 create_power_domain PD_TOP -include_scope create_supply_net VDD_TOP -domain PD_TOP create_supply_net VSS -domain PD_TOP create_supply_set SS_TOP -function {power VDD_TOP} -function {ground VSS} associate_supply_set SS_TOP -handle PD_TOP add_power_state VDD_TOP -state {ON 1.2} # GPU域 create_power_domain PD_GPU -elements {gpu_inst} create_supply_net VDD_GPU -domain PD_GPU create_supply_net VDD_GPU_RET -domain PD_GPU create_supply_net VSS -domain PD_GPU # 主供电集 create_supply_set SS_GPU_ACTIVE -function {power VDD_GPU} -function {ground VSS} associate_supply_set SS_GPU_ACTIVE -handle PD_GPU # 保持供电集 create_supply_set SS_GPU_RET -function {power VDD_GPU_RET} -function {ground VSS} # 电源状态 add_power_state VDD_GPU -state {ACTIVE 0.9} -state {OFF off} add_power_state VDD_GPU_RET -state {RETENTION 0.6} # 电源开关(假设输入来自VDD_TOP) create_power_switch PSW_GPU -domain PD_GPU \ -input_supply_port {in VDD_TOP} \ -output_supply_port {out VDD_GPU} \ -control_port {ctrl gpu_power_enable} \ -on_state {on in {ctrl}} # 保持策略(选择性) set_retention RET_GPU -domain PD_GPU \ -retention_supply_set SS_GPU_RET \ -retention_condition {gpu_retention_enable} \ -elements { gpu_inst/config_regs gpu_inst/shader_state } # 映射库单元(示例) map_retention_cell RET_GPU -domain PD_GPU \ -lib_cells {RET_FF_X1 RET_FF_X2}

验证步骤

  1. 检查UPF语法:check_upf -verbose
  2. 仿真:写测试,向config_regs写入值,断言gpu_retention_enable,关gpu_power_enable,等待,恢复电源,解除保持,读回值,验证不变。
  3. 检查shader_state之外的寄存器(如gpu_inst/temp_data)是否在断电后变为X(表示未保持)。
  4. 综合后检查网表:只有config_regsshader_state对应的触发器被替换为RET_FF

十、学习路线图

  1. 第1天:理解保持触发器的双电源概念,手写一个单域带保持的UPF,用仿真器跑基本序列。
  2. 第2天:加入电源开关,练习保持控制信号与电源门控的时序配合。
  3. 第3天:实现选择性保持,用-elements只保留几个寄存器,对比综合报告的面积差异。
  4. 第4天:分析一个真实IP的UPF,找出其保持策略和保留实例列表。
  5. 第5天:编写验证测试,覆盖错误序列(如先断主电再断言保持),检查工具是否报错或仿真出现X。

推荐命令

  • report_retention -domain PD_CPU:查看保持策略详情。
  • check_mv_design -retention:检查保持电源和控制信号的合法性。

保持策略是UPF中实现“快速唤醒+低漏电”的关键。掌握了它,你就能让芯片在睡眠时几乎不耗电,醒来时瞬间恢复状态。

http://www.jsqmd.com/news/661259/

相关文章:

  • CBAM注意力机制实战:从原理到代码的即插即用指南
  • HarmonyOS6 ArkTS CheckboxGroup
  • Rust的闭包最佳实践
  • 终极指南:5分钟学会用FanControl掌控Windows风扇智能控制
  • 打破平台壁垒:在Windows上轻松安装安卓应用的三大突破
  • AI 搜索排名优化GEO系统 支持私有化源码部署与 OEM 贴牌,具备私有化部署能力与深度定制技术正在占据产业链的高价值环节 - 速递信息
  • React原理深入
  • 配置Anaconda Jupyter Notebook AI通用工作环境
  • QSpectrumAnalyzer终极指南:10分钟掌握专业SDR频谱分析工具
  • 从Copilot到CodeWhisperer,智能生成代码的依赖熵增问题全解析,Google/微软内部治理白皮书首度公开
  • M4S转MP4工具:三分钟掌握B站缓存视频永久保存方案
  • GLM-4.1V-9B-Base在复杂网络协议分析中的应用构想
  • Outfit字体:如何用开源方案实现品牌视觉一致性并降低80%设计成本
  • Phi-4-mini-reasoning开源镜像:Phi系列最小推理模型的CSDN GPU适配版
  • 源代码论文分享|别再只收藏不打开了,这份在线试题库系统资料真的值得你认真看一遍!
  • 如何在5分钟内实现Word到LaTeX的完美转换:docx2tex终极指南
  • Python处理遥感大图内存爆炸?手把手教你用Rasterio分块读取Tiff(附内存监控代码)
  • 【Linux】ARM篇七--UART串口驱动开发与调试实战
  • WeChatExporter:专业级微信聊天记录本地化备份解决方案
  • AGI爆发临界点倒计时(2025±18个月):MIT+DeepMind联合白皮书未公开数据首次披露
  • 如何在Windows上安装安卓应用:APK Installer的终极解决方案
  • 终极指南:使用applera1n免费解锁iOS 15-16设备的激活限制
  • 重塑企业数字资产边界:基于Go高并发架构的壹信即时通讯源码全景解析与商业落地实战 - 壹软科技
  • FigmaCN技术实现:如何通过浏览器扩展实现Figma界面实时汉化
  • CVE(Common Vulnerabilities and Exposures 通用漏洞披露)介绍(给每个已公开安全漏洞分配一个唯一编号)MITRE公司、CNA、CVE-年份-编号、CVSS评分
  • k8s配置nfs存储类
  • macOS视频预览终极指南:3个技巧让Finder识别所有视频格式
  • 3个关键步骤:用PyBullet构建专业级无人机强化学习环境
  • 欧卡北欧超写实影调画质丨雪月光照+Ultimate Graphics Mod+Reshade特调滤镜+PNG、JBX——鲜艳配置
  • 告别重复劳动:用CodeGeeX的‘交互模式’和‘智能问答’,5分钟搞定C#单元测试和代码解释