Appearance
RC 暂态响应:为什么信号传输有延迟
概念
上一篇讲的都是直流稳态:电源接通很久之后,电流不再变化。
但数字电路真正关心的恰恰是变化的那一瞬间。门从 0 变 1,输出端要驱动一段导线和下一个门的输入电容——这个电容不会瞬间充电,电压得一点点爬上去。
RC 暂态响应讲的就是这个过程:电压怎么随时间变化、多久才能被下一个门认出来。
一句话:数字电路的"速度上限",本质上是一个 RC 充电问题。 这一篇是 L0 的"开关延迟"到 L1 的"时序分析"之间的桥。
原理
一、电容:一个"电压的存储器"
电容是储存电荷的元件:
这两行是全部:电容两端的电压不能突变(要突变需要无穷大电流)。所以电容是"电压状态记忆"的物理载体。
注意:电容上的电压是连续的,电流可以跳变。这正好和电感相反(电感电流连续、电压可跳变)。"谁不能突变"是解一阶电路的核心抓手。
一个重要事实:数字电路的"负载"基本全是电容。MOS 栅极的输入阻抗在直流下是无穷大(不吸电流),但每个栅极都有几 fF 的输入电容,每段导线也有寄生电容。所以"驱动负载"= "给一堆电容充电"。
典型量级:
| 负载来源 | 典型电容 |
|---|---|
| 一个标准单元输入 | 1 ~ 5 fF |
| 片上短线(100 μm 以内) | 1 ~ 10 fF |
| 片上长线(1 mm 量级) | 50 ~ 200 fF |
| 片外走线 + 引脚 + 板级 | 5 ~ 50 pF |
| 标准测试负载 | 15 pF(手册常用)或 50 pF |
二、一阶 RC 的三个基本事实
考虑最简单的电路:一个电压源
时间常数:
单位验算:
充电过程(电容初始为 0,
放电过程(电容充到
为什么是指数:
其解就是上面那个指数式。初值 + 稳态值 + 时间常数就能唯一定出解。
三、把时间点换算成 :一张必背的表
| 时刻 | 说明 | |
|---|---|---|
| 10% | 数字门"开始能看见"的门槛(以下按 10%/90% 定义) | |
| 50% | 门延迟 | |
| 63.212% | 时间常数本身 | |
| 86.466% | ||
| 95.021% | ||
| 98.168% | ||
| 99.326% | 工程上约定"到 5τ 就算稳定" | |
| 99.909% |
推导 50% 时刻:令
推导 10% 和 90% 时刻:
上升时间
记住这两个数字:
, 。几乎所有门延迟估算都是它们的变体。
四、CMOS 门的延迟为什么是 RC
回顾 L0 的结论:CMOS 门导通时,上拉或下拉的 MOS 管工作在线性区,等效为一个电阻
VDD
│
┌┴┐ PMOS(导通时 ≈ R_p)
└┬┘
├──────● Vout ──┬── C_L(下一级输入 + 线电容)
┌┴┐ │
└┬┘ NMOS │
│ │
GND ┘于是充放电就是一个 RC 过程:
关键推论:
| 想加速 | 怎么做 | 代价 |
|---|---|---|
| 减小 | 加宽晶体管( | 面积↑,自身栅电容↑,驱动前级变难 |
| 减小 | 减小扇出、缩短导线 | 功能受限于电路结构 |
| 提高 | 增大过驱动 | 功耗 |
这就是"延迟—功耗—面积"三角的物理来源。任何优化都是在这三者之间搬账。
五、扇出的延迟代价:线性还是平方?
设一个门要驱动
看起来是线性。但注意:如果同一个信号要穿过一连串门(
仍然是线性(这是"级联门")。真正的平方关系出现在导线上——下面讲。
易混点:扇出(同一级带 N 个)是线性的,级联(N 个门串联)也是线性的。平方出现在"用一整根导线连 N 段"的分布 RC 里。
六、分布参数:导线不是"一个电容"
前面的
一根总电阻
| 模型 | 延迟 | |
|---|---|---|
| 集总(当成一个 RC) | 10.0 ns | |
| 分布式(沿线的电阻电容连续分布) | 5.0 ns |
为什么分布式只有一半:靠近驱动端的电容"隔着"的电阻少,充得快;远端电容要经过整根导线的电阻,充得慢。平均下来是一半。
用 N 段阶梯逼近(每段电阻
代
验证(
| 趋势 | ||
|---|---|---|
| 1 | 10.000 ns | 集总模型(上界) |
| 2 | 7.500 ns | |
| 5 | 6.000 ns | |
| 10 | 5.500 ns | |
| 20 | 5.250 ns | |
| 5.000 ns | 真值 |
结论:
七、为什么插入缓冲器能加速
分布 RC 线的延迟
长度平方增长——这是长导线最要命的地方。
对策:把长线切成
变成
(
| 分段数 | 总延迟 |
|---|---|
| 1(不插缓冲) | 6.900 ns |
| 2 | 3.450 ns |
| 4 | 1.725 ns |
| 8 | 0.862 ns |
但缓冲器本身有延迟和功耗。所以存在一个最优级数:分得越细,线延迟越小,但缓冲器自身的延迟和功耗累加起来。经典结论是:
这就是"时钟树为什么要插那么多缓冲器""长走线为什么要中继"的答案,也是后面 L2 里"流水线为什么能提高频率"的物理基础——插寄存器 = 把长路径切成短路径。
八、什么时候必须抛弃 RC 模型
RC 模型的前提是集总参数:导线的传播时间远小于信号的上升时间。
导线上的电磁波速度约为光速的 1/2:
经验判据("1/6 波长"或"上升时间 vs 往返时间"):
算个例子:
结论:PCB 上超过约 7.5 mm 的走线,在 100 ps 上升时间下就必须当传输线处理(要阻抗控制、要端接电阻)。
这就是"高速数字设计"的入门门槛:当信号快到来不及"等它稳定",导线就不再是导线,而是一段有特征阻抗的传输线。此时会出现反射、振铃、串扰——这些不再是 RC 问题,而是波动问题。L2 及以后的信号完整性、DDR 布线规则,都从这句话出发。
示例
例 1:给一套典型参数算延迟(完整计算)
某 7 nm 标准单元:
( ,典型工艺角),负载 。求 、 、 、到达 99% 的时间。
第一步:时间常数。
第二步:门延迟(50% 点)。
第三步:上升时间。
第四步:到 99% 的时间。 令
结论:
注意
:这是很常见的困惑点。"门延迟 69 ps"指的是输出到 50% 电平的时间,而波形还要继续爬 150 ps 才到 90%。这两个数在时序分析里用途不同( 用于路径延迟, 用于判断是否需要考虑传输线效应)。
例 2:长导线——集总 vs 分布式(完整计算)
一段片上金属线:
, 。分别用集总模型、分布式模型、 段 Elmore 估算延迟。
集总:
分布式真值:
结论:集总模型给出 10 ns,真值是 5 ns——高估一倍。
工程含义:如果拿集总模型做时序收敛,你会过度悲观,把本来能过的设计判死。长线必须用分布式(或至少
段的阶梯)模型。
例 3:插入缓冲器把延迟从平方降成线性(完整计算)
接例 2,把这段线均分成 4 段,每段之间插一个缓冲器(缓冲器本征延迟
,暂忽略)。求总延迟。
第一步:每段的时间常数。
第二步:每段延迟(50% 点)。
第三步:总延迟。 4 段级联:
第四步:加上缓冲器自身延迟。 3 个中间缓冲器(首尾不计):
结论:从 10 ns(集总)/ 5 ns(分布式)降到 1.785 ns——约 2.8 倍加速,代价是 3 个缓冲器的面积与功耗。
与公式对照:
继续加分段的收益与代价:
| 线延迟 | + 缓冲器延迟 | 总计 | |
|---|---|---|---|
| 1 | 6.900 ns | 0 | 6.900 ns |
| 2 | 3.450 ns | 1×0.020 | 3.470 ns |
| 4 | 1.725 ns | 3×0.020 | 1.785 ns |
| 8 | 0.862 ns | 7×0.020 | 1.002 ns |
看出趋势了吗:
从 4 到 8,线延迟又降了一半,但缓冲器延迟从 0.06 涨到 0.14 ns。再往下分,收益会被缓冲器自己吃掉。这就是"最优级数"的直觉。
用程序复算
#include <stdio.h>
#include <math.h>
int main(void) {
/* --- 例1: 单个门的 RC --- */
printf("--- 例1 标准单元 ---\n");
double Req = 5e3, CL = 20e-15;
double tau = Req * CL;
printf(" tau = %.4f ns\n", tau * 1e9);
printf(" tpd(50%%) = %.4f ns\n", 0.6931 * tau * 1e9);
printf(" tr(10-90%%) = %.4f ns\n", 2.1972 * tau * 1e9);
printf(" t(99%%) = %.4f ns\n", log(100.0) * tau * 1e9);
/* --- 充电曲线 --- */
printf("--- 充电曲线 ---\n");
double ks[] = {1, 2, 3, 4, 5, 7};
for (int i = 0; i < 6; i++)
printf(" t=%g tau -> %6.3f%%\n", ks[i], 100*(1-exp(-ks[i])));
printf(" 10%%=%.4f tau, 50%%=%.4f tau, 90%%=%.4f tau, ln9=%.4f\n",
log(10.0/9), log(2.0), log(10.0), log(9.0));
/* --- 例2/3: 分布 RC 与缓冲器 --- */
printf("--- 例2/3 分布 RC ---\n");
double Rtot = 10e3, Ctot = 1e-12;
printf(" 集总 RC = %.4f ns\n", Rtot*Ctot*1e9);
printf(" 分布 RC/2 = %.4f ns\n", Rtot*Ctot/2*1e9);
int Ns[] = {1, 2, 5, 10, 20};
for (int i = 0; i < 5; i++) {
int N = Ns[i];
double r = Rtot/N, c = Ctot/N;
printf(" N=%2d 节 Elmore = %.4f ns\n", N, r*c*N*(N+1)/2*1e9);
}
printf("--- 插缓冲器(每段 0.69rc)---\n");
int Mb[] = {1, 2, 4, 8};
double tbuf = 0.020;
for (int i = 0; i < 4; i++) {
int N = Mb[i];
double r = Rtot/N, c = Ctot/N;
double twire = N * 0.69 * r * c * 1e9;
double tb = (N - 1) * tbuf;
printf(" N=%d 段: 线延迟 %.4f ns + 缓冲 %.4f ns = %.4f ns\n",
N, twire, tb, twire + tb);
}
/* --- 传输线判据 --- */
printf("--- 传输线判据 ---\n");
double v_wire = 1.5e8; /* m/s, 约 c/2 */
double tr = 100e-12;
printf(" 上升时间 %.0f ps, v=%.1e m/s -> 临界长度 %.2f mm\n",
tr*1e12, v_wire, tr/2*v_wire*1e3);
return 0;
}
c 本站为静态站,不提供在线运行;可复制到本地用 gcc / python 执行
import math
print("--- 例1 标准单元 ---")
Req, CL = 5e3, 20e-15
tau = Req * CL
print(f" tau = {tau*1e9:.4f} ns")
print(f" tpd(50%) = {0.6931*tau*1e9:.4f} ns")
print(f" tr(10-90%) = {2.1972*tau*1e9:.4f} ns")
print(f" t(99%) = {math.log(100)*tau*1e9:.4f} ns")
print("--- 充电曲线 ---")
for k in (1, 2, 3, 4, 5, 7):
print(f" t={k} tau -> {100*(1-math.exp(-k)):6.3f}%")
print(f" 10%={math.log(10/9):.4f} tau, 50%={math.log(2):.4f} tau, "
f"90%={math.log(10):.4f} tau, ln9={math.log(9):.4f}")
print("--- 例2/3 分布 RC ---")
Rtot, Ctot = 10e3, 1e-12
print(f" 集总 RC = {Rtot*Ctot*1e9:.4f} ns")
print(f" 分布 RC/2 = {Rtot*Ctot/2*1e9:.4f} ns")
for N in (1, 2, 5, 10, 20):
r, c = Rtot/N, Ctot/N
print(f" N={N:2d} 节 Elmore = {r*c*N*(N+1)/2*1e9:.4f} ns")
print("--- 插缓冲器 ---")
tbuf = 0.020
for N in (1, 2, 4, 8):
r, c = Rtot/N, Ctot/N
twire = N * 0.69 * r * c * 1e9
tb = (N - 1) * tbuf
print(f" N={N} 段: 线延迟 {twire:.4f} ns + 缓冲 {tb:.4f} ns = {twire+tb:.4f} ns")
print("--- 传输线判据 ---")
v_wire, tr = 1.5e8, 100e-12
print(f" tr={tr*1e12:.0f} ps, v={v_wire:.1e} m/s -> 临界长度 {tr/2*v_wire*1e3:.2f} mm")
python 本站为静态站,不提供在线运行;可复制到本地用 gcc / python 执行
输出(节选):
tau = 0.1000 ns
tpd(50%) = 0.0693 ns
tr(10-90%) = 0.2197 ns
t(99%) = 0.4605 ns
t=5 tau -> 99.326%
10%=0.1054 tau, 50%=0.6931 tau, 90%=2.3026 tau, ln9=2.1972
集总 RC = 10.0000 ns
分布 RC/2 = 5.0000 ns
N= 1 节 Elmore = 10.0000 ns
N=10 节 Elmore = 5.5000 ns
N=4 段: 线延迟 1.7250 ns + 缓冲 0.0600 ns = 1.7850 ns
tr=100 ps, v=1.5e+08 m/s -> 临界长度 7.50 mm考点
考点
1. 必背的三个常数
推导链:
易错:
2. 为什么是
因为 10% 和 90% 的表达式都是
3. RC 与门延迟的关系
- 扇出增加 → 延迟线性增加
- 加宽管子 →
减小但自身 增大,是零和博弈 - 电压升高 → 过驱动增大 →
减小,但功耗 增加
4. 分布 RC(★ 高频计算)
| 模型 | 延迟 |
|---|---|
| 集总(单节 RC) | |
| 分布(真值) | |
| 插 |
必答的结论:导线延迟
5. Elmore 延迟的通用公式
对树状 RC 网络:
用法:从每个电容节点往源"回望",把沿途电阻加起来,乘上该节点电容,全部求和。不用解微分方程——这是它最大的价值。
6. 传输线的临界长度(常考概念)
导线速度
记一个数:
7. 易错点清单
- 把"电容电压不能突变"说成"电容电流不能突变"。反了:电容电压连续、电流可跳变;电感相反。
只对一阶电路成立。二阶电路(LC 振荡、RLC)没有单一时间常数,会出现阻尼振荡。- 用集总模型估长线延迟,结果高估一倍。只在小尺寸/短线下可用。
- 以为插缓冲器"越多越快"。缓冲器自身有
和功耗,存在最优级数。 - 混淆
与 。 是到 50% 的时间(路径延迟用), 是 10%→90%(判断传输线效应用)。 - 忽略负载电容的温度/电压依赖。
和 都随工艺角(TT/FF/SS)变化,最坏情况(SS 角 + 高温 + 低压)才是签核用的数。 - 算"到稳定"用
却忘了是相对最终值还是绝对误差。 对应 0.67% 误差;若要求 0.1%(10 位精度)需 。
小结
- 电容电压不能突变,一切一阶 RC 行为都从
出发;解的形状是"初值 + 稳态值 + 时间常数"。 ; , ( ), 视为稳定。- CMOS 门延迟的物理本质就是 RC 充电:
。加速只有三条路——减小 、减小 、提高 ,各自都要付出代价。 - 导线延迟
;分布 RC 的真值是 ,集总模型高估一倍, 段 Elmore 给出 。 - 插缓冲器把
变成 ,但缓冲器自身有代价,存在最优级数。 - 上升时间够短时,导线变成传输线:
就要阻抗控制。 时临界长度约 7.5 mm。
回到主线:L0 讲了"开关延迟是电容充放电",这一篇把它算清楚了——延迟是 RC,速度上限由 RC 定。
但数字电路不只有"0"和"1"两个绝对电平。真实世界里,门与门之间还要能认出对方的电平,还要能被外部的小信号驱动。这就是为什么需要第三篇:模拟电路——放大器把微弱信号恢复成干净的数字电平,运放做比较、做滤波、做驱动。
评论(0)
当前浏览器不允许本地存储,评论无法保存。
还没有评论,来说两句。