文章目录
参考文献
[1](数字IC)低功耗设计入门
[2]Verilog低功耗设计
[3]低功耗设计基础:DVS, AVS和DVFS都是如何降低功耗的?
一、低功耗设计的必要性
- 低功耗设计有利于降低便携式电子产品的体积。
- 功耗越大,产生的热量越多,会导致热噪声越大,会影响器件的正常工作。随着温度的上升,会降低芯片的工作频率。
- 低功耗设计有利于降低封装成本。
二、功耗的构成
功耗一般只关注动态功耗和静态功耗。
1. 动态功耗
动态功耗包括开关功耗(翻转功耗)、短路功耗(内部功耗)。
1) 翻转功耗(switching power)
翻转功耗的产生原因是在数字CMOS电路中,对负载电容进行充放电时消耗的功耗。
以上面的CMOS非门为例, 当Vin=0时, 上面的PMOS管导通,下面的NMOS管截止,VDD对负载电容
C
l
o
a
d
C_{load}
Cload进行充电,充电完毕后,Vout的电平为高电平。当Vin=1时,上面的PMOS管截止,下面的NMOS管导通,负载电容通过NMOS进行放电,放电完毕后,Vout为低电平。
翻转功耗的计算公式为
P
s
w
i
t
c
h
=
V
D
D
2
C
L
f
=
1
2
V
D
D
2
C
L
T
r
P_{switch} = V_{DD}^2C_Lf = \frac{1}{2}V_{DD}^2C_LT_r
Pswitch=VDD2CLf=21VDD2CLTr
其中,
V
D
D
V_{DD}
VDD为供电电压,
C
L
C_L
CL为等效负载电容,f为时钟频率(翻转率Tr=2f)。
2)短路功耗(Internal power)
短路功耗是因为在输入信号进行翻转时,信号的翻转不可能瞬间完成,也就是说PMOS和NMOS不可能总是一个截止一个导通,总有一段时间是PMOS和NMOS同时导通,因此,在这段时间内从电源VDD到地VSS之间就有了通路,如此便形成了短路电流,如下图所示
短路功耗的计算公式为
P
s
h
o
r
t
=
V
D
D
T
r
Q
x
P_{short} = V_{DD}T_rQ_x
Pshort=VDDTrQx
其中,
V
D
D
V_{DD}
VDD为供电电压,
T
r
T_r
Tr为翻转率,
Q
x
Q_x
Qx为一次翻转过程中从电源流向地的电荷量。
综上所述,动态功耗主要有开关功耗和短路功耗,其中开关功耗占比大。并且动态功耗主要是跟供电电压、翻转率、负载电容有关。
2. 静态功耗
静态功耗的产生原因是在CMOS电路中,静态功耗主要是漏电流引起的功耗,如下图所示
漏电流有下面几个部分组成:
- PN结反向电流I1(PN-junction Reverse Current)
- 源极和漏极之间的亚阈值漏电流I2(Sub-threshold Current)
- 栅极漏电流,包括栅极和漏极之间的感应漏电流I3(Gate Induced Drain Leakage)
- 栅极和衬底之间的隧道漏电流I4(Gate Tunneling)
一般情况下,漏电流主要是指栅极泄漏电流和亚阈值电流(进入超深亚微米工艺之后,隧道漏电流成为主要电流之一)
栅极泄漏功耗:在栅极上加信号后(即栅压),从栅到衬底之间存在电容,因此在栅衬之间就会存在有电流,由此就会存在功耗。
亚阈值电流:使栅极电压低于导通阈值,仍会产生从漏极到源极的泄漏电流。此电流称为亚阈值泄漏电流。在较狭窄的晶体管中,漏极和源极距离较近的情况下会产生亚阈值泄漏电流。晶体管越窄,泄漏电流越大。要降低亚阈值电流,可以使用高阈值的器件(HVT器件,相较于LVT器件,功耗低但是速度慢),还可以通过衬底偏置进行增加阈值电压,这些属于低功耗设计。
静态功耗的计算公式为
P
p
e
a
k
=
V
D
D
I
p
e
a
k
P_{peak} = V_{DD}I_{peak}
Ppeak=VDDIpeak
其中, I p e a k I_{peak} Ipeak为泄漏电流,此外静态功耗往往与工艺有关。
三、低功耗设计方法
芯片的低功耗设计通过不同的设计层次可以分为系统级低功耗设计,行为级低功耗设计,RTL级低功耗设计,逻辑级低功耗设计和物理级低功耗设计,其设计层次越高对功耗降低的效果越明显。
四、如何从设计的角度降低功耗
根据前面分析,动态功耗主要是跟供电电压、翻转率、负载电容有关,静态功耗往往与工艺有关。从前端设计角度来看,无疑只能通过降低信号的翻转率来降低功耗。下面介绍几种常用的降低翻转率的方案。
1)使用格雷码、独热码进行状态机的编码和解码;
在状态机的编码和解码过程中,采用格雷码最符合低功耗设计。因为格雷码的相邻码元之间只变化一位,所以在发生状态转换时实际上只有一个触发器发生了翻转。对于状态编码常用的二进制码和独热码来说,在发生一次状态转换时可能存在多个触发器发生了翻转,在状态转换过程中也就消耗了更多的能量。另外使用格雷码的一个好处就是降低了亚稳态发生的概率。
case(state)
2'b00: out = a;
2'b01: out = b;
2'b11: out = c;
2'b10: out = d;
default:out = 0;
endcase
此外,除了格雷码外,还可以考虑独热码来实现状态机编码,独热码虽然需要更多的触发器进行编码,但是独热码更能减少组合逻辑资源。假如需要判断状态机是否处于某状态S1,对于格雷码来说,需要assign S1 = (State==2’b01); 而对于独热码来说,只需要assign S1 = (State[1])。无疑对于条件复杂但是状态少的状态机来说,独热码也是一个不错的选择。
2)操作数隔离,数据保持;
操作数隔离原理为,如果在某一段时间内,数据通路的输出是无用的,将输入置成固定值,数据通路部分没有翻转,功耗就会降低。
一个示例乘法器电路如下图所示,当 sel0 = 0 或 sel1 = 1 时,乘法器 Multiplier 的输出结果并不能通过两个 Mux 到达寄存器的输入端。即寄存器并不能保存当前乘法器的结果,此次乘法运算是没有必要的。在此种条件下,采用操作数隔离,使乘法器不工作保持静态,也可以节省功耗。
一般来说,操作数隔离的操作发生在代码综合的时候。这个过程往往是人为可设置、编译器可自动识别的。当然,在编写 RTL 电路时就考虑周全,更加有助于实现操作数隔离,从而降低功耗。以下是操作数隔离的示例写法。
//no isolation
module oper_isolation1
(
input clk , //100MHz
input [1:0] sel ,
input [3:0] din1 , //data in
input [3:0] din2 , //data in
output reg [7:0] dout
);
reg [7:0] res ;
always @(*) begin
res = din1 * din2 ;
end
always @(posedge clk) begin
if (sel == 2'b01) begin
dout <= res ;
end
end
endmodule
//using isolation
module oper_isolation2
(
input clk , //100MHz
input [1:0] sel ,
input [3:0] din1 , //data in
input [3:0] din2 , //data in
output reg [7:0] dout
);
wire [3:0] mul1 = sel == 2'b01 ? din1 : 0 ;
wire [3:0] mul2 = sel == 2'b01 ? din2 : 0 ;
reg [7:0] res ;
always @(*) begin
res = mul1 * mul2 ;
end
always @(posedge clk) begin
if (sel == 2'b01) begin
dout <= res ;
end
end
endmodule
3)添加使能、片选信号,减少不必要的信号翻转
在实际电路设计中,并不是所有时刻输入都是有效的。比如说一个乘法器,可以添加一个en信号,用来使能输入操作数是否有效,有效时输出,无效时数据保持。
module top(
input clk,
input en ,
input [7:0] opt1,
input [7:0] opt2,
output reg [15:0] result
);
always @(posedge clk)begin
if(en)
result <= opt1*opt2;
else
result <= result;
end
endmodule
4)逻辑复用
当设计中一些相同的运算逻辑在多处使用时,就可以使用逻辑复用的方法避免多个运算逻辑的重复出现,减少资源的消耗。虽然说EDA工具会在一定程度上,对相同逻辑进行复用,但是在实际设计过程中,也需要保证良好的代码风格,提高EDA的工具的可靠性和综合速度。以下是逻辑复用的一个例子。
//未优化前
always @(*) begin
case (mode) :
3'b000: result = 1'b1 ;
3'b001: result = 1'b0 ;
3'b010: result = value1 == value2 ;
3'b011: result = value1 != value2 ;
3'b100: result = value1 > value2 ;
3'b101: result = value1 < value2 ;
3'b110: result = value1 >= value2 ;
3'b111: result = value1 <= value2 ;
endcase
end
// 对上述代码进行优化,描述如下:
wire equal_con = value1 == value2 ;
wire great_con = value1 > value2 ;
always @(*) begin
case (mode) :
3'b000: result = 1'b1 ;
3'b001: result = 1'b0 ;
3'b010: result = equal_con ;
3'b011: result = equal_con ;
3'b100: result = great_con ;
3'b101: result = !great_con && !equal_con ;
3'b110: result = great_con && equal_con ;
3'b111: result = !great_con ;
endcase
end
5)逻辑重拍
以下图为例, a信号变化得最频繁,为了降低输出信号的翻转,我们可以将a和d信号位置互换,实现逻辑的重新排序,也就是将快速变换的信号移至逻辑锥体的前部。此方法同样适用于“if-else-”表达式,可以重拍判断条件,优先判断变化较慢的条件。
又比如,电路中b信号是翻转率比较大的信号,在排序前的电路中,b的每次翻转要驱动4个门,在排序后的电路中,b的每次翻转只需要驱动2个门,显然有效地降低了系统的动态功耗。下图所示为排序前后的两个电路模块。
6)时钟门控(clock gating)
通常情况下,时钟树由大量的缓冲器和反相器组成,时钟信号为设计中翻转率最高的信号,时钟树的功耗可能高达整个设计功耗40%。加入门控时钟电路后,由于减少了时钟树的翻转,节省了翻转功耗。同时,由于减少了寄存器时钟引脚的翻转行为,寄存器的内部功耗也减少了。采用门控时钟,可以非常有效地降低设计的功耗,一般情况下能够节省20%~60%的功耗。
在实际设计中,我们是不需要在rtl中自己实现时钟门控的,现在的综合工具会自动插入时钟门控。如下图所示当插入时钟门控后,电路中的MUX就不需要了,如果数据D是多bit的,那么插入CG后面积会减少。
常用的时钟门控单元如下图所示。
也就是说只有D位宽超过一定的bit数后,插入CG的收益才会大。而这个位宽的临界值在DC中默认值为3。也就是说,如果D的位宽超过了3bit,那么DC就会默认插入CG。可以使用DC命令来修改默认值。
set_clock_gating_style -minimum_bitwidth 4
当然,虽然现在综合工具可以自动插入门控时钟,但是如果编码风格不好,也不能达到自动插入CG的目的。
//写法1, 能够自动插入clock gating
always @(posedge clk or negedge rst_n)begin
if(~rst_n)
Q <= 'd0;
else if(EN)
Q <= D;
end
//写法2, 不能够自动插入clock gating
always @(posedge clk or negedge rst_n)begin
if(~rst_n)
Q <= 'd0;
else if(EN)
Q <= D;
else
Q <= 'd0;
end
五、如何从后端的角度降低功耗
1)多电压域(Multi-Voltage Domain)—— 降低工作电压
对于多电压域设计,要在不同的电压域之间使用一些电平转换单元(Level Shifter),将输入电压范围转换成输出需要的不同电压范围。
如果不同电压与之间的驱动信号与接受信号之间的距离很长,需要插入特殊的驱动单元(Repenter)来增强信号的驱动能力;如果不同的电压域可以单独断电(MV with Power Gating),还要考虑添加保持寄存器(Retention Register)和电压隔离单元(Isolation Cell)。
2)使用HVT高阈值晶体管 —— 降低泄露电流
对绝大多数工艺,任何一种标准单元(standardcell)都有不同种速度的 Library,也就是常说的不同 Vt 的 cell,比如 HVT(High V threshold), SVT(Standard V threshold)和LVT(Low V threshold)。HVT 逻辑门的特点是速度慢,功耗低,因为其阈值电压高,所以需要更高的电压才能打开晶体管。SVT 逻辑门速度和功耗相对于 HVT 和 LVT 之间,因为其阈值电压在标准范围内。LVT 逻辑门速度快,功耗高,因为其阈值电压低,只需要较小的电压就可以打开晶体管。
对于系统设计来说,可以在时序紧张的路径上使用LVT,然后在时序宽松的路径上使用HVT,来达到降低系统功耗的目的。此外,HVT/SVT/LVT 三种cell的面积是一样的。
3) DVS, AVS和DVFS
- DVS(Dynamic Voltage Scaling)和AVS(Adaptive Voltage Scaling), 核心目的都是通过调节芯片整体或者部分power domain的电源电压来实现降低功耗的目的。
- DVFS(Dynamic Voltage Frequency Scaling),可以根据芯片的性能和功耗需求调整电压和频率,从而在各个不同的工作需求中都已最小的功耗实现需求。在实现DVFS的过程中,需要一个输出电压控制器,一般来说叫做EMU(Energy Management Unit)。它在芯片中的基本逻辑结构如下: