1. 一颗四核A7在28nm下到底难在哪
28nm这个节点,放在今天看确实不算先进,但它是个特别有意思的工艺分水岭。HKMG(High-K Metal Gate)在28nm上开始大规模铺开,漏电控制比40nm好了不少,可跟后来的FinFET比,平面晶体管在亚阈值漏电上的天花板已经摸到了。你要在这上面塞四个Cortex-A7核心,还得把功耗压住,这事儿的难度不在于“能不能跑起来”,而在于“跑起来之后电够不够用、热扛不扛得住”。
四核A7的典型应用场景是入门级移动设备、车载信息娱乐系统的主控、工业网关这类产品。这些场景有个共同特点:常年插着电或者电池容量不大,但要求7x24小时在线,待机功耗必须做到毫瓦级,满载又不能超过散热设计的阈值。我见过太多项目,芯片回来一测,待机功耗比预期高了3倍,查来查去发现是某个电源域没关干净,或者时钟树上的门控漏了。
Hierarchical Flow(层次化流程)在这里不是可选项,是必选项。为什么?因为四核A7加上L2 cache、互连总线、DDR控制器、各种外设,晶体管规模轻松上亿门。你如果用一个扁平的流程从头跑到尾,综合和布局布线的时间会把你拖死,而且后端团队根本没法并行协作。层次化流程的核心思路是把芯片切成若干物理分区,每个分区独立做综合、布局、时序收敛,最后在顶层拼起来。听起来简单,做起来全是坑。
这篇文章我打算把整个流程拆开讲,从电源域划分、UPF编写、分区策略、时钟树设计,到后端实现和功耗签核,每一步都结合28nm工艺的特点来说。适合正在做或者准备做低功耗SoC的工程师,不管你是前端还是后端,都能从中找到自己需要的那块拼图。
2. 低功耗设计的整体架构与电源域划分
2.1 为什么电源域划分决定了项目成败
电源域划分是低功耗设计的第一步,也是最关键的一步。你在这个阶段做的决定,后面改起来代价极大。我个人的经验是,电源域划分要遵循三个原则:功能相关性、电压域一致性、开关频率可控性。
四核A7的典型划分方式是这样的:四个CPU核心各自一个电源域(或者两两一组),L2 cache单独一个域,互连总线和DDR控制器一个域,常开外设(比如中断控制器、看门狗、RTC)一个域,其他外设按功能分组。为什么要分这么细?因为CPU核心在待机时可以完全断电,L2 cache可以保留内容但降低电压,互连总线在低负载时可以降频,常开域必须一直供电。
28nm工艺下,电源域的开关实现通常用MTCMOS(Multi-Threshold CMOS)开关管。具体做法是在电源网络和标准单元之间插入高阈值电压的PMOS开关,控制信号来自Power Management Unit(PMU)。这里有个细节:开关管的尺寸和数量要仔细算,太小了IR drop扛不住,太大了面积浪费还增加漏电。
注意:电源域划分不是越细越好。每增加一个电源域,就多一套隔离单元、电平转换器、电源开关,面积和验证复杂度都会上升。我的建议是,先按功能划分,再根据实际功耗数据合并。
2.2 UPF编写中的实战细节
UPF(Unified Power Format)是描述电源意图的标准格式。写UPF不是写代码,是在描述一个“电源管理的法律条文”,每一条都要经得起验证工具的推敲。
一个典型的四核A7 UPF结构大概长这样:
create_power_domain PD_CPU0 -elements {u_cpu0} create_power_domain PD_CPU1 -elements {u_cpu1} create_power_domain PD_L2 -elements {u_l2} create_power_domain PD_TOP -elements {u_top} -include_scope create_supply_port VDD_CPU -domain PD_CPU0 create_supply_port VDD_L2 -domain PD_L2 create_supply_port VDD_TOP -domain PD_TOP create_supply_net VDD_CPU -domain PD_CPU0 create_supply_net VDD_L2 -domain PD_L2 create_supply_net VDD_TOP -domain PD_TOP set_domain_supply_net PD_CPU0 -primary_power_net VDD_CPU -primary_ground_net VSS set_domain_supply_net PD_L2 -primary_power_net VDD_L2 -primary_ground_net VSS set_domain_supply_net PD_TOP -primary_power_net VDD_TOP -primary_ground_net VSS create_power_switch sw_cpu0 \ -domain PD_CPU0 \ -input_supply_port {vin VDD_TOP} \ -output_supply_port {vout VDD_CPU} \ -control_port {sleep_ctrl cpu0_sleep} \ -on_state {on_state vin {!sleep_ctrl}} \ -off_state {off_state {sleep_ctrl}}这段代码的关键在于create_power_switch的定义。on_state和off_state的条件必须和PMU的控制逻辑完全一致,否则仿真和实际芯片行为会对不上。我踩过的坑是:控制信号的极性搞反了,结果仿真时CPU一直处于断电状态,查了两天才发现是!sleep_ctrl写成了sleep_ctrl。
隔离单元(Isolation Cell)的插入策略也需要仔细考虑。当一个电源域断电时,它的输出信号会变成不确定态,如果直接连到常开域,会产生漏电甚至逻辑错误。隔离单元的作用就是在断电时把输出钳位到固定电平。UPF里用set_isolation命令来指定:
set_isolation iso_cpu0 \ -domain PD_CPU0 \ -isolation_power_net VDD_TOP \ -isolation_ground_net VSS \ -clamp_value 0 \ -applies_to outputs-clamp_value 0表示断电时输出钳位到0。具体钳位到0还是1,取决于接收端的逻辑需求。比如中断信号通常钳位到0(无效态),而某些使能信号可能需要钳位到1。
2.3 电平转换器的选择与布局
如果不同电源域的工作电压不同,比如CPU域跑0.9V,常开域跑1.0V,那就需要电平转换器(Level Shifter)。28nm下,电平转换器的延迟和面积都不能忽略。我的做法是:在RTL阶段就规划好电压域边界,把需要跨域的信号尽量集中,减少电平转换器的数量。
电平转换器有两种类型:H2L(高到低)和L2H(低到高)。H2L通常用简单的反相器链就能实现,L2H需要特殊的电路结构来保证驱动能力。在布局时,电平转换器要放在两个域的边界附近,但必须放在常开域内,否则断电时它自己也没电了。
3. Hierarchical Flow的分区策略与实现
3.1 分区方案的选择:按层次还是按物理
Hierarchical Flow的分区有两种思路:按逻辑层次分区和按物理位置分区。按逻辑层次分区就是按照RTL的模块层次来切,比如CPU子系统、互连子系统、外设子系统各一个分区。按物理位置分区则是根据芯片的floorplan,把芯片切成几个物理区域,每个区域包含不同模块的组合。
对于四核A7这种结构规整的设计,我推荐混合方式:CPU核心按逻辑层次分区,因为四个核心完全对称,可以复用同一套流程和脚本;互连和外设按物理位置分区,因为它们和floorplan强相关。
分区的粒度怎么定?太粗了,并行度不够,综合时间还是长;太细了,顶层集成的复杂度爆炸。我的经验值是每个分区控制在500万到2000万门之间。四核A7加上L2和互连,大概切成6到8个分区比较合适。
3.2 分区边界的时序约束
分区边界是层次化流程里最容易出问题的地方。因为每个分区独立做时序收敛,边界上的路径时序信息必须准确传递,否则顶层拼起来之后会发现大量违例。
具体做法是:在分区的SDC(Synopsys Design Constraints)里,对输入输出端口设置准确的set_input_delay和set_output_delay。这些值不能拍脑袋定,要根据顶层时钟周期和边界路径的预估延迟来算。
举个例子:假设顶层时钟周期是1ns,分区A到分区B的路径预估组合逻辑延迟是0.3ns,那么分区A的输出延迟可以设为0.3ns,分区B的输入延迟设为0.3ns。这样两个分区各自优化时,都会为边界路径留出足够的余量。
实操心得:边界时序约束宁紧勿松。我通常会在预估延迟上加20%的余量,给顶层集成留出调整空间。如果一开始设得太松,顶层拼起来发现违例,回头改分区约束再重新跑,时间成本极高。
3.3 顶层集成的关键步骤
顶层集成不是简单地把各个分区的网表拼在一起。你需要处理以下几件事:
第一,电源网络的连接。每个分区的电源端口要和顶层的电源环、电源条连接起来。28nm下,电源网络的IR drop分析必须做,尤其是CPU满载时,瞬态电流可能达到安培级。
第二,时钟树的平衡。每个分区内部的时钟树是独立做的,但顶层需要保证跨分区的时钟偏斜(skew)在可控范围内。通常的做法是在顶层插入时钟树缓冲器,把时钟信号分发到各个分区,分区内部再做局部时钟树。
第三,边界时序的最终收敛。顶层集成后,用STA工具跑全芯片时序,重点检查跨分区路径。如果发现违例,可能需要调整分区内部的布局或者顶层缓冲器的位置。
4. 28nm工艺下的功耗优化手段
4.1 时钟门控的层次化实现
时钟门控是动态功耗优化的第一手段。在28nm下,时钟树的功耗能占到总动态功耗的30%到40%,门控做得好不好,直接影响芯片的续航。
层次化流程下,时钟门控要分两级做:分区内部用细粒度的门控单元(Integrated Clock Gating Cell),在RTL阶段就插入;顶层用粗粒度的门控,控制整个分区的时钟开关。
RTL阶段插入ICG的典型代码风格:
always @(posedge clk or negedge rst_n) begin if (!rst_n) data_reg <= 0; else if (enable) data_reg <= data_in; end综合工具会自动识别这种带使能的寄存器,插入ICG。但要注意,enable信号必须满足ICG的建立保持时间要求,否则会产生毛刺。我的做法是在enable路径上插入一个锁存器,用时钟的反相沿锁存,保证使能信号在时钟有效沿附近稳定。
4.2 多阈值电压单元的使用策略
28nm工艺提供多种阈值电压的标准单元:HVT(高阈值)、SVT(标准阈值)、LVT(低阈值)。HVT漏电小但速度慢,LVT速度快但漏电大。低功耗设计的核心策略是:在满足时序的前提下,尽可能用HVT。
具体怎么操作?综合阶段先用SVT跑一遍,看看时序余量有多少。如果余量充足,把非关键路径上的单元替换成HVT。如果某些路径时序紧张,再局部替换成LVT。这个替换过程可以迭代几轮,直到功耗和时序达到平衡。
有个经验数据:在28nm下,HVT相比SVT能降低约50%的漏电,但延迟增加约20%。所以关键路径上不要用HVT,否则时序会崩。
4.3 电源门控的时序验证
电源门控的验证是低功耗设计里最容易被忽视的环节。很多团队功能仿真过了就以为万事大吉,结果芯片回来发现断电再上电后,某些寄存器状态丢失,系统起不来。
验证电源门控需要做几件事:
第一,用UPF-aware的仿真工具跑断电上电序列。检查隔离单元是否正确钳位,电平转换器是否正常工作,电源开关的时序是否符合预期。
第二,做保留寄存器(Retention Register)的验证。如果某些寄存器需要在断电时保留状态,必须用特殊的保留寄存器单元,并且在UPF里正确声明。
第三,检查电源域的上电顺序。有些域必须在其他域之前上电,否则会产生大电流冲击。这个顺序要在PMU的状态机里严格实现。
5. 常见问题与排查技巧实录
5.1 功耗签核时发现漏电超标怎么办
漏电超标是28nm低功耗设计的高频问题。排查思路是从大到小,先定位是哪个域、哪个模块、哪类单元的问题。
第一步,看功耗报告的分域数据。如果某个域的漏电明显偏高,先检查这个域的电源开关是否在待机时完全关闭。有时候开关控制信号被其他逻辑拉住了,导致开关管没有完全关断。
第二步,看标准单元的阈值分布。如果LVT单元占比过高,漏电肯定大。用脚本统计各阈值单元的比例,把非关键路径上的LVT替换成HVT或SVT。
第三步,检查存储器(SRAM)的漏电。SRAM的漏电在28nm下占比很大,如果SRAM没有做电源门控或者没有用低漏电的位单元,整体漏电很难降下来。
5.2 跨分区时序违例的定位方法
跨分区时序违例的定位比分区内部违例麻烦,因为路径跨越了两个分区的网表,STA工具需要正确的边界约束才能准确分析。
我的排查流程是这样的:先用顶层STA跑一遍,导出所有跨分区违例路径。然后按分区对分组,看违例集中在哪些分区对之间。如果某个分区对的违例特别多,说明这两个分区之间的边界约束可能有问题。
接下来,检查边界端口的set_input_delay和set_output_delay是否合理。有时候分区内部的布局变化会导致边界延迟和预估不符,需要重新调整约束。
如果约束没问题,那就是分区内部的布局或逻辑需要优化。这时候可能需要回到分区内部,调整关键路径的布局或者插入流水线寄存器。
5.3 电源域上电时的浪涌电流问题
浪涌电流是电源门控设计里的隐形杀手。当一个大电源域突然上电时,所有开关管同时导通,瞬间电流可能达到正常工作电流的10倍以上,导致电源网络电压塌陷,芯片复位。
解决办法是分级上电:把电源域内的开关管分成若干组,按顺序依次导通。每组之间的间隔由PMU控制,通常在微秒级。这样浪涌电流就被分散到多个时间段,峰值大幅降低。
具体实现时,UPF里要定义多个电源开关,每个开关控制一部分开关管。PMU的状态机按顺序使能这些开关。验证时要检查上电序列的时序,确保每组开关完全导通后再开下一组。
| 常见问题 | 排查方向 | 解决手段 |
|---|---|---|
| 待机漏电超标 | 电源开关未完全关断 | 检查控制信号极性,确认开关管关断 |
| 跨分区时序违例 | 边界约束不准确 | 重新计算边界延迟,加余量 |
| 上电浪涌电流大 | 开关管同时导通 | 分级上电,PMU控制时序 |
| 断电后状态丢失 | 保留寄存器未正确声明 | 检查UPF中retention定义 |
| 时钟树功耗高 | 门控粒度太粗 | 增加ICG,细化门控层次 |
5.4 层次化流程中的版本管理
层次化流程涉及多个团队并行开发,版本管理是个容易被低估的问题。每个分区有自己的网表、约束、UPF,顶层集成时需要确保所有分区的版本是匹配的。
我的做法是:用Git管理所有分区的源文件,每个分区打tag。顶层集成时,在脚本里明确指定每个分区的tag号。这样任何时候都能复现某个版本的完整芯片。
另外,分区的接口文件(比如LEF、LIB、Verilog网表)要统一放在一个共享目录,由专人维护。接口文件更新时,必须通知所有相关团队,避免因为接口不一致导致集成失败。
6. 后端实现中的功耗与面积权衡
6.1 Floorplan对功耗的影响
Floorplan不是简单的“把模块摆进去”,它直接决定了电源网络的IR drop、时钟树的长度、以及跨分区路径的延迟。对于四核A7,我推荐的floorplan是:四个CPU核心呈2x2排列,L2 cache放在中间,互连和DDR控制器放在一侧,常开外设放在角落。
为什么这样摆?CPU核心之间的通信主要通过L2 cache,把L2放在中间可以缩短互连长度,降低动态功耗。互连和DDR控制器放在一侧,方便和外部接口连接。常开外设放在角落,因为它的电源网络相对独立,放在边缘可以减少对核心区域的影响。
电源网络的设计要重点考虑CPU满载时的IR drop。28nm下,CPU核心的瞬态电流密度很高,电源条要足够宽,电源环要足够密。我通常会用RedHawk或者Voltus做IR drop分析,目标是把静态IR drop控制在5%以内,动态IR drop控制在10%以内。
6.2 时钟树综合的低功耗技巧
时钟树综合(CTS)是后端功耗优化的关键环节。时钟树的功耗和它的长度、缓冲器数量、以及翻转率成正比。降低时钟树功耗的手段有:
第一,用时钟门控单元替代普通缓冲器。ICG在使能关闭时,下游的时钟树完全不翻转,功耗为零。
第二,优化时钟树的拓扑结构。H-tree和Fishbone是两种常见的低偏斜时钟树结构,H-tree适合规整的布局,Fishbone适合长条形布局。四核A7的CPU核心区域比较规整,用H-tree比较合适。
第三,控制时钟树的缓冲器尺寸。缓冲器越大,驱动能力越强,但功耗也越大。在满足偏斜要求的前提下,尽量用小尺寸缓冲器。
6.3 布线阶段的功耗优化
布线阶段的功耗优化主要针对互连线的寄生电容。28nm下,互连线的寄生电容已经和晶体管电容相当,长线的动态功耗不可忽视。
优化手段包括:用高层金属走长线(高层金属的厚度大,电阻小,但电容也大,需要权衡);增加线间距减少串扰;对关键信号做屏蔽。我的经验是,时钟线和高速数据线一定要做屏蔽,否则串扰会导致额外的翻转功耗。
7. 功耗签核与流片前的最终检查
7.1 功耗签核的完整流程
功耗签核是流片前的最后一道关卡。签核不通过,绝对不能流片。完整的功耗签核包括:
静态功耗分析:用PrimePower或者PTPX跑不同场景下的漏电和动态功耗。场景要覆盖待机、典型负载、满载、以及各种电源状态切换的瞬态。
动态功耗分析:用VCD或者FSDB文件作为输入,跑真实工作负载下的功耗。VCD文件要尽可能长,覆盖各种工作模式。
IR drop分析:用RedHawk或者Voltus跑静态和动态IR drop,检查电源网络的完整性。
电迁移分析:检查电源线和信号线的电流密度是否超过工艺限制。
7.2 流片前的检查清单
流片前的检查清单很长,我挑几个和低功耗直接相关的说:
- UPF和网表的一致性检查:确保所有电源域、开关、隔离单元在网表中正确实现。
- 电源开关的仿真验证:跑完整的断电上电序列,检查所有电源状态。
- 保留寄存器的功能验证:断电后上电,检查保留寄存器的值是否正确恢复。
- 时钟门控的覆盖率检查:确保所有应该被门控的时钟都正确门控了。
- 电平转换器的方向检查:确保H2L和L2H的方向没有搞反。
最后再分享一个小技巧:在流片前,用形式验证工具跑一遍UPF和RTL的一致性检查。这个步骤能发现很多仿真覆盖不到的边界情况,我靠它抓过好几次电源域定义的错误。
7.3 硅后调试的功耗问题定位
芯片回来之后,如果功耗不达标,怎么定位?我的经验是:先测待机功耗,再测满载功耗,最后测不同电源状态下的功耗。
待机功耗高,通常是漏电问题。用红外热像仪看芯片表面的温度分布,热点区域就是漏电大的地方。然后对照floorplan,定位到具体模块。
满载功耗高,通常是动态功耗问题。用电流探头测电源网络的电流波形,看峰值电流和平均电流。如果峰值电流远超预期,可能是时钟树或者互连的翻转率太高。
电源状态切换时的功耗异常,通常是电源门控的时序问题。用示波器抓电源域的电压波形,看上电和下电过程中有没有异常震荡或者电流尖峰。
整个Hierarchical Flow走下来,我最深的体会是:低功耗设计不是某一个环节的事,它是从架构定义到后端实现、从RTL到GDSII的全流程系统工程。任何一个环节的疏忽,都可能在硅后变成无法挽回的功耗超标。28nm虽然成熟,但要把四核A7的功耗做到极致,依然需要每个环节都抠到细节。