4. 电源域划分与层次化设计

电源域(Power Domain,PD)是UPF中承载“哪些逻辑共享同一供电策略”的基本容器。它不是一个单纯的物理区域,而是把RTL层次、电压域(Voltage Domain,VD)和开关域(Switch Domain,SD)三种视角绑定在一起的逻辑边界。理解这三者的关系,是后续插入隔离单元、电平转换器和电源开关的前提。

先明确三个概念的分工:电压域描述“工作在什么电压”,决定是否需要电平转换;开关域描述“电源是否可被切断”,决定是否需要隔离与保持;电源域则是UPF中实际创建的对象,它通常与一个电压域和一个开关域对应,但也可以多个电源域共享同一电压域,或一个电源域内部再细分。三者的关系可以这样理解:电压域和开关域是“属性维度”,电源域是“管理单元”。

电源域划分的三维视角与边界处理 RTL 层次结构 top (SoC) u_cpu_subsys u_gpu u_ddr_ctrl u_always_on 电压域 (VD) VD_CPU 0.9V VD_GPU 0.8V VD_DDR 1.2V VD_AON 0.9V 开关域 (SD) SD_CPU_SW (可关断) SD_GPU_SW (可关断) SD_DDR_RET (保持) SD_AON (常开) RTL层次提供划分依据 → 电压域决定电平转换需求 → 开关域决定隔离/保持需求 → 三者交汇形成电源域边界

从RTL层次到电源域:划分依据与粒度选择

电源域划分的第一步是确定粒度。粒度过粗,低功耗效果差;粒度过细,隔离和电平转换单元数量激增,面积和验证成本上升。工程上通常以RTL层次中的功能子系统为基本单位,例如CPU子系统、GPU、DDR控制器、常开域等。每个子系统内部如果存在多个电压需求,可以再细分。

以示例SoC为例,RTL顶层包含五个主要子模块:u_cpu_subsys、u_gpu、u_ddr_ctrl、u_always_on以及顶层胶合逻辑。根据功能与供电需求,可以规划如下电源域:

电源域对应RTL层次电压域开关域供电策略
PD_CPUu_cpu_subsysVD_CPU 0.9VSD_CPU_SW可关断,需隔离
PD_GPUu_gpuVD_GPU 0.8VSD_GPU_SW可关断,需隔离
PD_DDRu_ddr_ctrlVD_DDR 1.2VSD_DDR_RET可关断,需保持
PD_AONu_always_onVD_AON 0.9VSD_AON常开,不关断
PD_TOP顶层胶合逻辑VD_AON 0.9VSD_AON常开,不关断

这里PD_TOP与PD_AON共享同一电压域和开关域,但逻辑上分开管理,便于后续单独约束。注意:电源域边界不一定与RTL模块边界完全重合,但强烈建议对齐,否则边界端口处理会变得复杂。

边界、端口与feedthrough的处理

电源域边界是UPF实现中最容易出问题的地方。当信号从一个电源域穿越到另一个电源域时,需要根据两边的电压关系和开关状态决定插入什么单元。

情况一:电压不同、都常开。例如PD_CPU(0.9V)到PD_DDR(1.2V),信号从低压域到高压域,需要插入电平转换器(Level Shifter,LS)。方向为低压→高压时,通常使用带使能的LS;方向为高压→低压时,普通LS即可。UPF中通过set_level_shifter命令指定规则,工具会在边界自动插入。

情况二:一边可关断、一边常开。例如PD_GPU关断时,其输出信号会浮空,必须插入隔离单元(Isolation Cell),将信号钳位到已知电平(通常为0或1),防止常开域收到不确定值。隔离单元放在常开域一侧,由常开域的控制信号使能。UPF中使用set_isolation命令指定隔离策略、钳位值和使能信号。

情况三:可关断域需要保留状态。例如PD_DDR关断时,某些配置寄存器需要保持,此时使用保持寄存器(Retention Register)。UPF中通过set_retention指定需要保持的寄存器列表和保持电源。

情况四:feedthrough。信号从PD_A出发,穿过PD_B,到达PD_C,但PD_B并不使用该信号。此时信号在PD_B内部只是“路过”,但PD_B关断时信号会被切断。处理方式有两种:一是将feedthrough信号在PD_B边界处打拍并隔离,二是将该路径改为不经过PD_B的直连。工程上优先选择后者,减少不必要的边界单元。

边界处理检查要点:每个跨域信号都应明确:源域、目的域、两边电压、两边开关状态、是否需要LS/ISO/RET。建议在UPF编写前先输出一份跨域信号清单,逐条确认,避免遗漏。

UPF中的电源域创建与边界约束示例

以下示例展示如何用UPF命令创建上述电源域并设置边界规则。假设顶层为top,电源域按RTL层次划分:

# 创建电源域
create_power_domain PD_CPU -elements {u_cpu_subsys}
create_power_domain PD_GPU -elements {u_gpu}
create_power_domain PD_DDR -elements {u_ddr_ctrl}
create_power_domain PD_AON -elements {u_always_on}
create_power_domain PD_TOP -elements {.} -exclude {u_cpu_subsys u_gpu u_ddr_ctrl u_always_on}

# 创建电源开关(示例:CPU域可关断)
create_power_switch sw_cpu \
  -domain PD_CPU \
  -output_supply_port {vout VD_CPU_SW} \
  -input_supply_port {vin VD_CPU} \
  -control_port {sleep_ctrl cpu_sleep_n} \
  -on_state {on_state vin {!sleep_ctrl}}

# 设置隔离策略:PD_GPU输出到常开域时隔离
set_isolation iso_gpu \
  -domain PD_GPU \
  -isolation_power_net VD_AON \
  -isolation_ground_net VSS \
  -clamp_value 0 \
  -applies_to outputs \
  -isolation_signal gpu_iso_en

# 设置电平转换:PD_CPU到PD_DDR
set_level_shifter ls_cpu_to_ddr \
  -domain PD_CPU \
  -applies_to outputs \
  -rule low_to_high \
  -location self

# 设置保持寄存器:PD_DDR中配置寄存器
set_retention ret_ddr \
  -domain PD_DDR \
  -retention_power_net VD_AON \
  -retention_ground_net VSS \
  -elements {u_ddr_ctrl/cfg_reg[*]}

上述命令中,create_power_domain的-elements指定该域包含的RTL实例;-exclude用于顶层域排除已划分的子模块。set_isolation的-applies_to outputs表示只对输出信号隔离,-clamp_value 0表示钳位到低电平。set_level_shifter的-location self表示LS放在源域一侧,也可以设为other放在目的域一侧,或both。

常见错误:隔离单元的使能信号必须来自常开域,否则当可关断域断电时,使能信号本身失效,隔离单元无法正常工作。同理,保持寄存器的保持电源必须来自常开域。UPF检查工具(如Cadence UPF Checker)会报告此类跨域控制信号问题。

层次化设计中的电源域嵌套与继承

在复杂SoC中,电源域可以嵌套。例如PD_CPU内部可以再划分PD_CPU_CORE和PD_CPU_L2,两者共享VD_CPU但开关域不同。UPF支持create_power_domain时指定-parent或通过层次路径自动继承。嵌套时需要注意:子域的边界处理规则会继承父域,但可以在子域中覆盖。例如父域设置了隔离钳位0,子域可以改为钳位1。

层次化设计的另一个关键点是电源域与RTL例化路径的对应关系。UPF中的-elements使用RTL例化名,因此RTL层次调整时UPF需要同步更新。建议在RTL稳定后再冻结电源域划分,或在UPF中使用参数化路径,减少后期维护成本。

最后,电源域划分完成后,应通过UPF的check_power_domain或工具自带检查命令验证:每个域是否有明确的电压域和开关域绑定、跨域信号是否都有对应的LS/ISO/RET策略、常开域是否确实不包含可关断逻辑。这些检查通过后,才能进入后续的电源开关插入和低功耗仿真阶段。