4. 电源域划分与层次化设计
电源域(Power Domain,PD)是UPF中承载“哪些逻辑共享同一供电策略”的基本容器。它不是一个单纯的物理区域,而是把RTL层次、电压域(Voltage Domain,VD)和开关域(Switch Domain,SD)三种视角绑定在一起的逻辑边界。理解这三者的关系,是后续插入隔离单元、电平转换器和电源开关的前提。
先明确三个概念的分工:电压域描述“工作在什么电压”,决定是否需要电平转换;开关域描述“电源是否可被切断”,决定是否需要隔离与保持;电源域则是UPF中实际创建的对象,它通常与一个电压域和一个开关域对应,但也可以多个电源域共享同一电压域,或一个电源域内部再细分。三者的关系可以这样理解:电压域和开关域是“属性维度”,电源域是“管理单元”。
从RTL层次到电源域:划分依据与粒度选择
电源域划分的第一步是确定粒度。粒度过粗,低功耗效果差;粒度过细,隔离和电平转换单元数量激增,面积和验证成本上升。工程上通常以RTL层次中的功能子系统为基本单位,例如CPU子系统、GPU、DDR控制器、常开域等。每个子系统内部如果存在多个电压需求,可以再细分。
以示例SoC为例,RTL顶层包含五个主要子模块:u_cpu_subsys、u_gpu、u_ddr_ctrl、u_always_on以及顶层胶合逻辑。根据功能与供电需求,可以规划如下电源域:
| 电源域 | 对应RTL层次 | 电压域 | 开关域 | 供电策略 |
|---|---|---|---|---|
| PD_CPU | u_cpu_subsys | VD_CPU 0.9V | SD_CPU_SW | 可关断,需隔离 |
| PD_GPU | u_gpu | VD_GPU 0.8V | SD_GPU_SW | 可关断,需隔离 |
| PD_DDR | u_ddr_ctrl | VD_DDR 1.2V | SD_DDR_RET | 可关断,需保持 |
| PD_AON | u_always_on | VD_AON 0.9V | SD_AON | 常开,不关断 |
| PD_TOP | 顶层胶合逻辑 | VD_AON 0.9V | SD_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的直连。工程上优先选择后者,减少不必要的边界单元。
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。
层次化设计中的电源域嵌套与继承
在复杂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策略、常开域是否确实不包含可关断逻辑。这些检查通过后,才能进入后续的电源开关插入和低功耗仿真阶段。