2. UPF基本概念与电源域建模

低功耗验证的核心,是把设计者写在 UPF 里的“电源意图”变成仿真器能够执行、能够检查的行为。VCS 在编译阶段读取 UPF,把电源域、电源开关、隔离、电平转换、状态保持等语义映射为仿真模型,再在运行时根据电源状态控制信号传播。理解这些基本概念,是后续写 UPF、跑仿真、看波形、定位违例的前提。

电源域:低功耗验证的第一层划分

电源域(Power Domain)是一组共享同一电源开关策略的实例、端口和信号的集合。它回答的是“哪些逻辑一起上电、一起断电”。在 UPF 中通常用 create_power_domain 建立,例如:

create_power_domain PD_CPU -include_scope
create_power_domain PD_GPU -elements {u_gpu}
create_power_domain PD_AON -elements {u_aon}

这里 PD_CPU 覆盖当前 scope,PD_GPU 只包含 u_gpu 子模块,PD_AON 是常开域。电源域划分决定了后续所有低功耗单元的插入位置:隔离单元放在“被关断域到常开域”的边界,电平转换器放在不同电压域之间,状态保持寄存器放在需要跨断电保存状态的寄存器上。划分错了,后面的策略全部会错位。

与电源域紧密相关的是电源网络(Supply Network)和电源状态(Power State)。电源网络描述电源端口、电源网、电源开关如何连接;电源状态描述某个域处于 ON、OFF、RETENTION 等哪种状态。UPF 用 create_supply_port、create_supply_net、connect_supply_net 建立网络,用 add_port_state 和 create_pst 描述状态表。VCS 在 elaboration 阶段会检查电源网络是否完整、状态表是否自洽。

电源开关、隔离单元与电平转换器

电源开关(Power Switch)是控制电源域通断的器件,通常用 create_power_switch 描述。它有三个关键端口:控制端、输入电源、输出电源。例如:

create_power_switch sw_gpu \
  -domain PD_GPU \
  -input_supply_port {vin VDD} \
  -output_supply_port {vout VDD_GPU} \
  -control_port {sleep ctrl_sleep} \
  -on_state {on vin {!sleep}} \
  -off_state {off {sleep}}

这段描述的含义是:当 sleep 为 0 时开关导通,VDD_GPU 由 VDD 供电;当 sleep 为 1 时开关断开,域断电。VCS 会据此在仿真中把该域内部节点拉到对应状态,并检查是否有信号在断电域中仍然被驱动。

隔离单元(Isolation Cell)解决的是“关断域输出到常开域”的浮空问题。当 PD_GPU 断电后,它的输出可能处于不确定态,如果直接连到常开逻辑,会引入 X 传播。UPF 用 set_isolation 指定隔离策略:

set_isolation iso_gpu \
  -domain PD_GPU \
  -isolation_power_net VDD_AON \
  -isolation_ground_net VSS \
  -clamp_value 0 \
  -applies_to outputs

这里 -clamp_value 0 表示断电时把输出钳位到 0,隔离电源来自常开域 VDD_AON。VCS 会在仿真中检查隔离单元是否在正确时机使能,以及被隔离信号是否真的被钳位。

电平转换器(Level Shifter)处理的是不同电压域之间的信号传递。例如 1.2V 域驱动 1.8V 域,或 1.8V 域驱动 1.2V 域,都需要电平转换。UPF 用 set_level_shifter 描述:

set_level_shifter ls_gpu2aon \
  -domain PD_GPU \
  -applies_to outputs \
  -rule both \
  -location self

-rule both 表示高低压转换都处理,-location self 表示转换器放在源域。VCS 会检查跨域信号是否都有对应的电平转换策略,缺少时会在编译或仿真阶段报出 UPF 违例。

状态保持寄存器

状态保持寄存器(Retention Register)用于在电源域断电时保存关键状态,重新上电后恢复。它通常由 set_retention 和 set_retention_control 描述:

set_retention ret_cpu \
  -domain PD_CPU \
  -retention_power_net VDD_AON \
  -retention_ground_net VSS

set_retention_control ret_cpu \
  -domain PD_CPU \
  -save_signal {save_posedge high} \
  -restore_signal {restore_posedge high}

含义是:在断电前 save 有效,把寄存器值存入保持单元;上电后 restore 有效,把值恢复回寄存器。VCS 会检查 save/restore 时序是否与电源状态切换匹配,以及保持电源是否始终存在。

UPF 命令与 VCS 编译选项的配合

UPF 文件写好后,需要在 VCS 编译时加载。常用方式有两种:

vcs -full64 -sverilog -upf upf_top.upf \
    -power=upf \
    -debug_access+all \
    top.sv tb.sv

或者用 -upf 指定文件,用 -power=upf 启用 UPF 低功耗仿真。如果 UPF 分多个文件,可以多次使用 -upf,VCS 会按顺序加载。编译完成后,仿真运行时 VCS 会根据 UPF 建立电源状态机,并在波形中提供电源域状态、隔离使能、保持信号等观测点。

需要特别注意的是,UPF 命令有作用域和加载顺序。例如 create_power_domain 必须在 set_isolation 之前,电源网络必须在电源开关之前建立。VCS 在编译时会做 UPF 语法和语义检查,常见错误包括:电源域未定义、隔离电源网络不存在、状态表不完整、跨域信号缺少电平转换等。这些错误会在编译日志中以 UPF 相关错误码出现,需要逐条定位。

UPF 电源域建模与低功耗单元关系图 PD_CPU(可关断域) CPU 逻辑 / 寄存器 状态保持寄存器 save / restore 控制 保持电源 VDD_AON PD_GPU(可关断域) GPU 逻辑 / 输出 电源开关 sw_gpu sleep 控制通断 VDD → VDD_GPU PD_AON(常开域) 常开控制 / 隔离电源 VDD_AON 供电 始终 ON 为隔离/保持供电 隔离单元 clamp_value 0 电平转换器 rule both 断电输出 钳位后送常开域 跨域信号 电压匹配 VCS 编译与 UPF 检查 vcs -full64 -sverilog -upf upf_top.upf -power=upf -debug_access+all top.sv tb.sv 检查项:电源域定义 / 电源网络完整性 / 状态表自洽 / 隔离策略 / 电平转换 / 保持控制 运行时观测:电源状态、隔离使能、save/restore、跨域信号钳位与转换

建模顺序与常见检查点

一个可执行的 UPF 建模顺序通常是:先建电源域,再建电源网络和电源开关,然后设置隔离、电平转换、状态保持,最后定义电源状态表。VCS 编译时会按这个顺序做一致性检查。如果顺序颠倒,例如在电源域未定义时就写 set_isolation,编译会直接报错。

实际工程中,建议把 UPF 分成“结构层”和“策略层”两个文件:结构层只写 create_power_domain、create_supply_port、create_supply_net、connect_supply_net;策略层写 set_isolation、set_level_shifter、set_retention。这样便于复用和版本管理。VCS 支持多个 -upf 按顺序加载,正好匹配这种分层方式。

最后要强调的是,UPF 不是“写完就完了”的静态描述。VCS 在仿真中会持续监控电源状态变化,并在波形中记录电源域状态、隔离使能、保持信号等。验证工程师需要结合波形和 UPF 违例报告,判断隔离是否在断电前使能、保持是否在断电前保存、恢复是否在上电后完成。只有把这些基本概念和建模动作对应起来,后续的 UPF 验证才不是盲跑。