4. 电源门控技术基础:电源门控的原理,MTCMOS实现,电源开关单元,状态保持单元

各位同学,今天我们来聊聊电源门控。说实话,这是低功耗设计里最“硬核”的技术之一。我刚开始接触这个领域时,觉得不就是把电源切掉嘛,有什么难的?结果第一次做项目就被“浪涌电流”和“数据丢失”两个问题折腾得够呛。嗯,今天我就把踩过的坑和积累的经验,一次性讲清楚。

4.1 电源门控的原理:为什么要“断水断电”?

电源门控,说白了就是——芯片里有些模块暂时不用,那就把它的电源彻底关掉。你想想看,一个模块不工作,但电源还供着,漏电流照样在跑。这就像家里没人住,水龙头却一直开着,白白浪费。

我个人的习惯是,在设计初期就要想清楚:哪些模块可以“睡觉”,哪些必须“24小时待命”。比如手机里的基带处理器,通话时工作,待机时就可以关掉。但实时时钟(RTC)模块,你永远不能关,否则闹钟就废了。

核心要点:电源门控的目标是消除空闲模块的漏电流。静态功耗(漏电)在先进工艺下占比越来越高,7nm以下甚至超过50%。不关电源,功耗根本压不住。

为什么会这样?因为晶体管尺寸越小,栅氧化层越薄,漏电通道越多。我做过一个28nm的项目,关掉一个CPU核心的电源,静态功耗直接降了98%。这个收益,你想想看有多大。

4.2 MTCMOS实现:多阈值的神奇组合

MTCMOS,全称是Multi-Threshold CMOS。说白了,就是在一个芯片里同时用两种晶体管:高阈值(HVT)和低阈值(LVT)。

  • 高阈值管(HVT):漏电小,但速度慢。适合做电源开关。
  • 低阈值管(LVT):速度快,但漏电大。适合做逻辑电路。

我记得第一次看MTCMOS的版图时,觉得这设计太聪明了。用HVT管做“总闸”,控制整个模块的电源。模块内部全是LVT管,跑得飞快。关掉总闸,内部LVT管的漏电就被彻底切断。

个人经验:我在一个AI加速器项目中,把核心计算阵列全部用LVT管实现,外围用HVT管做电源开关。性能提升了15%,漏电反而降了40%。但要注意,HVT管的导通电阻比LVT大,开关尺寸要留够余量。

4.3 电源开关单元:这个“总闸”怎么设计?

电源开关单元,就是那个控制电源通断的“总闸”。常见的有两种:

  • Header开关:放在VDD和逻辑电路之间。PMOS管实现。
  • Footer开关:放在逻辑电路和VSS之间。NMOS管实现。

我个人更倾向于用Header开关。为什么?因为PMOS管的衬底可以接VDD,噪声隔离更好。但Footer开关也有优势——NMOS管面积更小,导通电阻更低。具体选哪个,要看你的设计约束。

这里有个关键参数:开关尺寸。尺寸太小,IR drop(电压降)会很大,逻辑电路可能跑不起来。尺寸太大,开关本身的漏电和面积又受不了。我一般用经验公式:开关总宽度 = 逻辑电路总电流 / (每微米宽度能承受的电流)。

避坑指南:我曾经在一个项目中,为了省面积把开关尺寸算得太紧。结果芯片一上电,电压直接从1.0V掉到0.85V,逻辑全部出错。后来不得不重新流片,损失惨重。记住:开关尺寸要留20%的余量,尤其是峰值电流场景。

另外,开关的开启和关闭不能太快。开启太快,浪涌电流会拉低电源电压,影响其他模块。关闭太快,内部电荷来不及泄放,可能造成浮空节点。我习惯用“斜坡控制”——让开关在几个时钟周期内慢慢打开或关闭。

4.4 状态保持单元:断电后怎么“续命”?

电源关了,模块里的寄存器数据就丢了。但有些状态必须保留,比如CPU的程序计数器、状态寄存器。这时候就需要状态保持单元。

状态保持单元,说白了就是一个“永不掉电”的寄存器。它有两个电源域:

  • 主电源(VDD):给正常逻辑供电,可以关掉。
  • 保持电源(VDD_ret):只给寄存器的存储节点供电,永远不关。

我常用的结构是“Balloon电路”。它像一个气球,主电源掉电时,数据被“吹”进保持电源域。恢复时,再“吹”回来。这个电路面积不大,但功耗极低。

// 状态保持单元简化代码(Verilog描述)
module retention_ff (
    input clk, d, rst_n,
    input retention_en,   // 保持使能
    input vdd_ret,        // 保持电源
    output reg q
);
    // 主寄存器(由VDD供电)
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) q <= 1'b0;
        else if (!retention_en) q <= d;
    end

    // 保持寄存器(由VDD_ret供电,永不掉电)
    // 实际实现中,这个寄存器用高阈值管,漏电极小
    reg retention_cell;
    always @(posedge retention_en) begin
        retention_cell <= q;  // 保存数据
    end
    always @(negedge retention_en) begin
        q <= retention_cell;  // 恢复数据
    end
endmodule

实用技巧:我建议在状态保持单元周围加一圈“隔离单元”。因为主电源掉电时,输出可能变成X态,会传播到其他模块。隔离单元在掉电时输出固定值(0或1),避免逻辑混乱。

最后,说一个容易忽略的点:保持电源的电压可以比主电源低。比如主电源1.0V,保持电源0.7V。这样漏电更小,数据也不会丢失。我在一个IoT芯片上试过,保持电压降到0.6V,数据依然稳定,漏电又降了30%。

好了,电源门控的基础就讲到这里。下一节我们会深入讨论“电源门控的时序设计”——什么时候关、什么时候开,才能不影响功能。记住一句话:电源门控不是简单的“切电源”,而是一场精密的“手术”。