news 2026/10/6 11:52:15

低功耗SoC设计的UPF配置实战:Level Shifter与Isolation cell跨电压域关键策略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
低功耗SoC设计的UPF配置实战:Level Shifter与Isolation cell跨电压域关键策略

从后端到前端这几年,低功耗设计一直是绕不开的大山。功耗预算卡得越来越死,光靠时钟门控早就扛不住了,多电压域基本成了标准操作。可一旦把芯片拆成多个电压域,跨域信号怎么处理就成了新问题——信号线不能随便直连,掉电域的浮空输出也不能放任不管。这时候UPF(Unified Power Format)就该上场了,而Level Shifter和Isolation cell这两类基础单元,恰恰是所有跨电压域方案里最容易被低估、也最容易配错的地方。

这篇文章我会直接讲实操:UPF到底用什么机制管住多电压域,Level Shifter和Isolation在UPF里怎么配置才算“精准”,以及走到物理实现和仿真验证时,哪些坑是我自己踩过、也看别人反复踩的。适合正在做低功耗SoC的数字前端/后端工程师,或者刚接触UPF、想把它真正跑通的同学。文章里的命令都是真实工具链会用的,你可以直接照着搭一套双电源域的样例工程。

1. 低功耗设计为什么绕不开UPF

1.1 多电压域方案与UPF的诞生

先想一个问题:一颗SoC里如果既有1.0V的高性能逻辑,又有0.6V左右的低电压待机逻辑,功耗怎么控最划算?答案不是把整颗芯片都降到低电压,而是把“能低耗的部分”切出来单独供电,平时可以让它彻底关断或降到更低电压。这就有了电压域(Power Domain)的概念。

但问题是,RTL本身是不带电源信息的,综合工具也不知道哪个模块属于哪个电压域。低功耗设计从架构定义到物理实现,中间隔了好几个环节,如果每个环节各说各话,信号跨域谁负责、谁插入转换器、谁保证隔离,根本对不上。UPF(Unified Power Format)就是用来统一描述“电源意图”的标准格式,最早由几家EDA公司联合推动,后来成为IEEE 1801标准。它基于Tcl语法,核心作用就是把某个模块属于哪个供电域、哪些信号需要跨域处理、以及芯片各个电源状态怎么切换,全部提前写成一份机器可读的“说明书”。

我打过一个比方:UPF相当于给芯片画了一张供电管网图。RTL是楼里的房间布局,电源网络是水管和阀门,而Level Shifter和Isolation cell就是每个房间门口加装的调压器和防火门。没有这张图,施工队根本不知道哪里该装什么。

1.2 UPF里最基本的三个概念:域、网络、状态

UPF体系里概念不少,但实际写配置时高频用到的就是三个:电源域、供电网络、电源状态。

电源域用create_power_domain定义。一个域就是一组逻辑单元的集合,这些单元共享同一组供电终端。比如:

create_power_domain PD_TOP -include_scope create_power_domain PD_LP -include_scope {u_ret}

这条命令是说,顶层属于PD_TOP,而u_ret这个实例单独划到PD_LP。划域之前一定要先想清楚:掉电边界在哪、哪些模块需要常开、哪些接口是跨域的。域划得太粗,省电效果差;划得太细,Level Shifter和Isolation面积会压垮芯片。

供电网络用create_supply_port、create_supply_net和connect_supply_net描述。它把外部电源pin、内部供电线、以及每个域的主供电电源对应关系表达清楚。比如PD_TOP用1.0V,PD_LP用0.7V,这两路可能是外部PMIC提供的,也可能是片内LDO/DC-DC转出来的,UPF只需要描述连接关系即可。

电源状态用create_pst(Power State Table)定义。PST是一张二维表,描述不同供电状态组合下芯片处于什么模式。比如工作模式两路都开,待机模式PD_LP关断,休眠模式两路都关。PST会直接指导后端做电源门控检查,也影响仿真时怎么验证状态切换。

你去看一个完整的UPF文件,前面几十行往往就是把这些东西摊开写清楚。这块如果写得不干净,后面Level Shifter和Isolation策略再花哨也白搭。

2. Level Shifter:电平转换要怎么配才稳

2.1 跨电压域信号为什么不能直连

很多人一开始不理解:两个域的电压不一样,信号直接拉过去不就完了?真不行。数字电路判断逻辑电平靠的是阈值——1.0V域输出高电平“1”大概是1.0V,这个信号进入0.6V域,接收端可能能识别为高;反过来,0.6V域输出的高电平只有0.6V,进到1.0V域后,接收端根本判不出是高是低,甚至在阈值附近来回抖动,造成亚稳态和额外漏电。

所以跨电压域的信号必须经过Level Shifter(电平转换单元)。UPF里就是用它把信号从一个电压域的电平范围,平移到另一个域的电平范围。通常从低压到高压需要插,从高压到低压其实也建议插,因为高压域信号如果直接驱动低压域管子,栅氧应力、漏电路径都可能出问题,只是高压到低压的转换延迟预算更宽松,阈值判断更容易满足。

2.2 UPF中set_level_shifter的完整参数拆解

真正配置Level Shifter的UPF命令是set_level_shifter。只看一条命令表面很简单,但它每个参数都对应一个物理决策点:

set_level_shifter LS_TOP_OUT \ -domain PD_TOP \ -applies_to output \ -threshold 0.1 \ -rule both \ -location self \ -name LS_TOP_OUT_inst

逐项拆解:

  • -domain指定在哪个域上插。通常是信号的输出域或输入域,也可以放到公共域。
  • -applies_to指定是处理输出信号(output)、输入信号(input)还是两者都处理(both)。实际项目中,从PD_TOP输出到低压域的路径,一般把Level Shifter放在PD_TOP的输出边界附近。
  • -threshold是电压差阈值。它的含义是“只有当两个域电压差超过这个值时,才插入Level Shifter”。设成0.1V意味着电压差小于等于0.1V时可以容忍直连,大于则必须转换。这个值不是随便拍的,要结合标准单元库的输入判决电压和时序裕量来定。
  • -rule控制转换方向。both表示高低压双向都能转;如果方向确定,可以指定low_to_high或high_to_low节省面积。
  • -location控制插入位置。self表示把转换器放在源单元的紧邻输出处;fanout表示放在目标单元的输入端口前面。位置不同,对时序的影响差异很大。

我用的工程里,最稳妥的做法是先不加-rule,让工具自动分析;跑完电泳结果看哪些路径已经自然满足跨域要求,再收紧规则减少冗余Level Shifter。别一上来就both,Level Shifter本身也有功耗和面积,插多了反而吃亏。

2.3 Level Shifter插入的位置和顺序

Level Shifter插在哪,直接决定一条跨域路径的时序收敛难度。源端输出翻转后,信号要先经过转换器,再走长线到接收端;如果转换器离源端太远,中间那段还是不同电平域,信号完整性容易出问题。一般建议:

  • 数据信号:源域输出边界附近插入,保证进入长线之前已完成电平变换。
  • 时钟信号:必须由时钟树综合工具识别并处理,不要手动插到数据路径上,否则CTS阶段会很痛苦。
  • 复位/使能信号:不仅要转换电平,还要确认它们来自常开域(always-on),可靠供电。

举一个常见问题:有人为了省Level Shifter,把低压域信号直接连到高压域的一个高阈值接收单元上,仿真时功能正常,但做功耗分析时会发现这个单元静态漏电特别高。原因就是输入浮空或电平不到位,管子没有完全关断。这种问题在UPF检查里未必报错,但综合后仿真和硅后实测都会露馅。

3. Isolation:掉电域边界怎么挡“虚电”

3.1 Isolation cell的作用与原理

掉电域最烦的不是它不干活,而是它掉电之后输出端变成高阻或浮空。浮空信号进入常开域的逻辑门,会让接收端PMOS和NMOS同时部分导通,形成一条低阻通路,直接带来两个后果:一个是额外漏电,掉电域省下的电又从常开域漏回去了;另一个更严重,长时间半导通可能引发latch-up,芯片可靠性直接崩。

Isolation cell就是用来挡住这种浮空输出的。它在掉电域输出端或者接收端入口加一个钳位门,用独立控制信号把输出强制钳到固定电平(0或1)。常开域的逻辑永远收到一个确定值,不会出现半导通。

UPF里,Isolation通常配合Power Switch一起出现:控制信号先断开掉电域电源,再等几个周期后拉起Isolation使能,把输出钳住,然后才能安全掉电。唤醒顺序反之。

3.2 set_isolation命令的参数与语义

UPF配置Isolation的核心命令是set_isolation和set_isolation_control。前者定义隔离策略,后者指定隔离使能信号如何作用到隔离单元上。我习惯把这两个命令写在一起:

set_isolation ISO_LP_OUT \ -domain PD_LP \ -isolation_signal iso_ctrl \ -isolation_sense high \ -clamp_value 0 \ -applies_to output set_isolation_control ISO_LP_OUT \ -domain PD_LP \ -isolation_signal iso_ctrl \ -isolation_sense high \ -location self

参数拆解:

  • -isolation_signal指定隔离控制信号。这个信号必须来自不会掉电的域,否则掉电后隔离控制信号也没了,等于没隔离。
  • -isolation_sense指定控制信号的有效电平,high表示高有效,low表示低有效。这个要和控制信号的实际极性严格一致。
  • -clamp_value指定钳位值,0或1。到底钳0还是钳1,要看接收端的逻辑需求,下面细说。
  • -applies_to同样指定是管输入还是管输出。掉电域的输出要加隔离,常开域输入通常不需要,因为常开域不会掉电。
  • -location指定隔离单元放在哪,self表示放在掉电域边界。

我会特别检查-isolation_signal的约束。有一次项目里把隔离信号放在掉电域内部,工具不报错,但仿真一跑掉电流程,隔离功能完全失效。后来规范里直接要求:所有Isolation控制信号必须来自always-on域,并在UPF文件顶部用注释标出来。

3.3 clamp值的选择:0还是1

-clamp_value选0还是选1,其实是一个接收端逻辑的兼容性问题。没有绝对答案,我一般按这几种场景判断:

  • 如果接收端是低有效复位逻辑,掉电期间希望看到无效电平,往往钳1更安全,避免误触发复位。
  • 如果接收端总线协议规定空闲态为0,那钳0更合适。比如AHB总线HREADY等信号,掉电时钳0可以明确表示“从机未就绪”。
  • 如果接收端连接的是中断信号,通常钳1表示“无效”,避免掉电误触发中断。

下面这个表是我在不同项目里反复对比后的经验:

钳位值适用场景风险点
0总线数据、空闲态为0的控制信号可能误触发低有效复位
1低有效复位、中断信号可能让接收端一直处于等待状态
按接收端需求混合不同接口分别指定clamp值配置复杂,需要逐一确认

混合钳位的项目虽然麻烦,但面积和功耗最优。如果嫌麻烦,可以先统一钳0,后面仿真发现问题再局部改钳1。但我的建议是:在设计阶段就把每个跨域接口的接收端逻辑梳理一遍,把clamp值写进接口文档,别等仿真报错再猜。

另外注意,Isolation和Level Shifter一般一起出现。ISolation先钳住电平,然后Level Shifter再做电平变换。如果先插Level Shifter再隔离,掉电时浮空信号先进Level Shifter,转换器本身也可能因为输入悬空产生漏电。

4. 一个完整案例:双电源域UPF配置全流程

4.1 项目背景与需求设定

用一个真实项目里抽出来的场景:一颗低功耗SoC,分为PD_TOP常开域和PD_LP可关断域。PD_TOP用1.0V,PD_LP用0.7V。PD_LP里是一块待机时不需要工作的处理逻辑;PD_TOP里是常开控制逻辑,负责唤醒、中断管理。需求很简单但很典型:PD_LP掉电时,它输出到PD_TOP的所有信号必须被钳位在0;PD_LP正常工作时,两域之间双向数据都要经过Level Shifter。

设定模块:顶层soc_top,PD_LP包含子模块u_lp。我们先把域划出来,再把供电网络接好,最后加Level Shifter和Isolation策略。

4.2 UPF文件逐步搭建

第一步,定义两个电源域:

create_power_domain PD_TOP -include_scope create_power_domain PD_LP -include_scope {u_lp}

第二步,定义电源端口和网络。为了简化,这里直接用两个外部电源pin,一个给PD_TOP,一个给PD_LP,统一地VSS:

create_supply_port VDD_TOP create_supply_port VDD_LP create_supply_port VSS create_supply_net VDD_TOP_NET -domain PD_TOP create_supply_net VDD_LP_NET -domain PD_LP create_supply_net VSS_NET -domain PD_TOP connect_supply_net VDD_TOP_NET -ports {VDD_TOP} connect_supply_net VDD_LP_NET -ports {VDD_LP} connect_supply_net VSS_NET -ports {VSS} set_domain_supply_net PD_TOP \ -primary_power_net VDD_TOP_NET \ -primary_ground_net VSS_NET set_domain_supply_net PD_LP \ -primary_power_net VDD_LP_NET \ -primary_ground_net VSS_NET

第三步,给PD_LP输出信号加Isolation。我用高有效的隔离控制信号iso_ctrl,钳位到0:

set_isolation ISO_LP_OUT \ -domain PD_LP \ -isolation_signal iso_ctrl \ -isolation_sense high \ -clamp_value 0 \ -applies_to output set_isolation_control ISO_LP_OUT \ -domain PD_LP \ -isolation_signal iso_ctrl \ -isolation_sense high \ -location self

第四步,给两域之间的所有信号加Level Shifter。这里我选择了从PD_TOP视角配置,处理从PD_TOP输出到PD_LP的信号,以及从PD_LP输出到PD_TOP的信号,双向都转。为了保险,threshold设0.1V:

set_level_shifter LS_TOP_TO_LP \ -domain PD_TOP \ -applies_to output \ -threshold 0.1 \ -rule both set_level_shifter LS_LP_TO_TOP \ -domain PD_LP \ -applies_to output \ -threshold 0.1 \ -rule both

第五步,定义电源状态表。至少要有三个状态:正常工作、PD_LP关闭、全关(如果系统支持):

create_pst PST \ -supplies {VDD_TOP_NET VDD_LP_NET} add_power_state PST -state FULL_ON \ -supply_expr { {VDD_TOP_NET 1.0V} {VDD_LP_NET 0.7V} } add_power_state PST -state LP_OFF \ -supply_expr { {VDD_TOP_NET 1.0V} {VDD_LP_NET 0V} } add_power_state PST -state ALL_OFF \ -supply_expr { {VDD_TOP_NET 0V} {VDD_LP_NET 0V} }

这样一套UPF基本就齐了。实际工程里你还要加set_power_switch定义电源门控单元,再加set_retention处理需要保存状态的寄存器。但Level Shifter和Isolation的核心策略,就是上面这5步。

4.3 工具实现时的检查清单

UPF写完之后,接下来就是综合和物理实现。这个阶段最容易出问题。我总结了一份自检清单,每过一个项目都会跑一遍:

  • 用UPF checker跑一致性检查,重点看每个电源域的主供电网是否都定义完整。
  • 用低功耗仿真跑一遍掉电/唤醒流程,确认Isolation使能先于掉电、后于唤醒。
  • 检查iso_ctrl信号是否位于常开域,并且综合后没有被打到掉电域的buffer里。
  • 对照PST表检查电平转换路径是否和状态切换一致:比如PD_LP关闭时,从PD_LP到PD_TOP的输出已经被钳位,不能再靠Level Shifter输出高阻。
  • 看面积报告,确认Level Shifter和Isolation数量与手动估算一致。如果数量少得离谱,多半是漏插了;如果多到离谱,说明-threshold设得太激进,或-rule方向没收紧。

这些检查一开始要花时间,但能省掉后面好几个加班的晚上。

5. 低功耗UPF配置的常见坑与排查清单

5.1 现象与原因对照表

配置UPF久了,很多问题是反复出现的。我把它整理成一张速查表,遇事直接对表排查:

现象可能原因排查建议
仿真时掉电域输出出现X态传播Isolation没有插入,或隔离控制信号没生效检查set_isolation是否覆盖所有output端口;打印隔离信号波形,确认在掉电前已拉高
掉电后常开域漏电异常高clamp值选择不当,接收端仍存在半导通;或Level Shifter输入悬空用功耗分析工具看常开域漏电里是否有异常单元;检查信号路径上的转换器位置
唤醒后寄存器状态丢失缺少retention策略,或retention控制信号时序不对区分是否真的需要掉电保持;加set_retention并让保存使能信号早于掉电
Level Shifter数量异常少-threshold设得过大,低电压差路径被工具容忍直连打印UPF检查报告,列出所有跨域路径,逐个确认电压差和是否插转换器
工具报PST状态不一致create_pst里的供电状态和实际供电网定义冲突核对supply net名字、电压值大小写;确认每个状态都比对到同一个supply set
综合后面积暴增-rule both和-applies_to both组合使用,导致每个端口都插了双向转换改为按单向路径配置,手动标出不需要逆向转换的接口

有些问题是仿真工具报的,有些是物理实现工具报的,但根子大多在UPF策略定义阶段,尽早修掉比后面绕弯子省事太多。

5.2 几条实操心得

第一,UPF一定要在RTL冻结前就搭好框架,哪怕初始版本粗糙。等RTL都稳定了再补UPF,你会发现自己漏掉的跨域接口多到想哭。

第二,隔离控制信号和Level Shifter使能信号要统一管理,不要散落在这一个模块那一个模块。我习惯在UPF文件顶部维护一张“always-on信号表”,凡是被set_isolation_control用到的信号都登记进去,仿真验证时按这张表逐一检查。

第三,嵌入式低功耗逻辑别和UPF混为一谈。像STM32L151这类MCU低功耗设计,更多是固件关外设时钟、调低主频、进入stop/standby模式,它不涉及电压域隔离和电平转换的硬件流程。另一种是SoC级别UPF流程,把硬件电源域真正门控掉,两者是不同层级的事。搞混了你会在错误的层次找问题,白白浪费时间。

第四,每次改动UPF之后,把PST和Isolation Coverage报告打出来对照看一遍。很多问题不是首次配置引入的,而是后续为了修时序、补约束时,顺手改了一个信号,结果破坏了隔离时序。有一份baseline报告,回归时一眼就能看出哪里变了。

写在最后的几个小建议

UPF这个工具,语法本身并不复杂,难的是把电源意图拆解得足够清晰,再把它翻译成工具能严格执行的规则。我见过不少项目,UPF大几十行,Level Shifter和Isolation却配得乱七八糟,问题几乎都出在“没想清楚就开写”上。先把架构画清楚——多少个域、每个域什么电压、哪些接口跨域、哪个信号掉电时必须维持什么值——再动命令,效率会高很多。

还有一个小技巧:在工程目录里留一个UPF_README.md,把每次改动的背景和验证结果记下来。几次迭代之后,你会发现这个文件比大多数文档都好用,因为里面是你真实踩坑的痕迹。优化低功耗设计这件事,拼的不是谁命令背得熟,而是谁对自己设计的电源行为理解得更透。希望这些实战经验能让你在UPF配置的路上少走几步弯路。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 11:50:21

SOEM控制汇川SV660N实战:PDO映射与CiA402状态机详解

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:50:21

PCB表面缺陷检测数据集:1000张图六类缺陷与YOLO11训练实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:50:20

激光雷达与RTK标定实战:从坐标系对齐到轨迹精度闭环

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:45:50

FPGA多级降采样实战:CIC+FIR从150MHz到1MHz的Vivado实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:45:40

射频探针选型与S参数测量:从校准方法到PA匹配电路的特殊处理

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/6 11:45:32

MOC3081与MOC3061光耦可控硅驱动芯片:过零触发与电路设计指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华