从零构建半加器:深入CMOS晶体管级的设计艺术
你有没有想过,计算机里最基础的“1+1=2”是怎么在硅片上实现的?
不是用软件、也不是靠高级芯片,而是通过一个个微小的MOSFET晶体管——它们像开关一样,在纳米尺度上演绎着二进制世界的加法法则。
今天我们就来拆解一个看似简单却极具教学价值的电路模块:半加器(Half Adder),并聚焦于它在互补CMOS技术下的完整实现过程。我们将从逻辑真值表出发,一步步推导到晶体管连接方式,最终构建出完整的物理电路结构。
这不仅是一次理论推演,更是一场数字集成电路设计思维的真实演练。
半加器的本质:不只是“异或 + 与”
我们先来看半加器的功能定义:
| A | B | Sum (A⊕B) | Carry (A·B) |
|---|---|---|---|
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 0 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 |
功能很清楚:
-Sum = A ⊕ B→ 表示本位和
-Carry = A · B→ 是否向高位进位
但问题来了:
“为什么不能直接画两个门——一个XOR、一个AND,就完事了?”
因为在实际的CMOS工艺中,XOR门并不是基本单元。不像反相器或NAND那样可以高效地用对称结构实现,XOR天生复杂。它的布尔表达式是:
$$
A \oplus B = \overline{A}B + A\overline{B}
$$
这是一个“积之和”形式,意味着我们需要构造复杂的上下拉网络,或者采用多级逻辑组合。
而我们的目标是在纯互补CMOS架构下完成设计——即每个输出都由成对的PMOS上拉网络(PUN)和NMOS下拉网络(PDN)驱动,确保静态功耗为零、高低电平摆幅完整。
互补CMOS的核心思想:对偶性与低功耗
互补CMOS之所以成为VLSI设计的基石,关键在于其结构性优势:
- 当输出应为高时,PMOS导通,把VDD拉上来;
- 当输出应为低时,NMOS导通,把GND拉下去;
- 两者永不同时导通 → 静态电流几乎为零;
- 输出始终有强驱动能力,抗噪声能力强。
更重要的是,PUN和PDN互为对偶:
| PDN(NMOS) | 对应逻辑 | PUN(PMOS) |
|---|---|---|
| 串联 | AND | 并联 |
| 并联 | OR | 串联 |
所以,只要我们知道某个函数何时输出0(用于构造PDN),就能自动得到何时输出1(用于构造PUN)。这种对称美正是CMOS逻辑的魅力所在。
分步实现:先搞定简单的Carry,再攻克复杂的Sum
第一步:Carry = A·B —— 简单又高效
Carry信号非常直观:只有当A=1且B=1时才为1。这是标准的AND操作。
但在CMOS中,我们通常不用“直接实现AND”,因为那需要串并混合结构,不对称且难优化。取而代之的是使用NAND + 反相器的组合:
- 先做 NAND(A,B) → 得到 $\overline{A·B}$
- 再接一个反相器 → 恢复成 $A·B$
NAND门的CMOS结构(4T)
VDD | ┌──[PMOS_B]──┐ | | [PMOS_A] | | | +---- Output (to INV) | [NMOS_A] | [NMOS_B] | GND- PMOS并联:只要A或B为0,至少有一个PMOS导通 → 上拉有效
- NMOS串联:仅当A=1且B=1时,两个NMOS都导通 → 下拉有效
完美实现 NAND 功能。
接着加上一个标准反相器(2T),即可得到最终的Carry 输出。
✅ 总计:6个晶体管(4+2),延迟为两级门,速度快、面积小。
第二步:Sum = A⊕B —— 真正的挑战开始了
现在轮到难题了:如何用互补CMOS实现异或?
我们回顾一下:
$$
Sum = A \oplus B = \overline{A}B + A\overline{B}
$$
这个表达式的PDN(下拉网络)应该是两个并联支路:
- 一支由 $\overline{A}$ 和 $B$ 控制的串联NMOS
- 另一支由 $A$ 和 $\overline{B}$ 控制的串联NMOS
听起来可行?但问题在于:输入只给了A和B,没有¬A和¬B!
所以我们必须先生成反相信号。这意味着要增加两个反相器来产生 ¬A 和 ¬B。
但这还没完。即使有了这些信号,如果我们想用单一复合门实现XOR,PUN会变得异常复杂——因为它必须实现对偶函数:
$$
\text{PUN should pull up when } A=B \Rightarrow AB + \overline{A}\,\overline{B}
$$
也就是XNOR函数。也就是说,如果你强行做一个“XOR输出”的复合门,它的自然输出其实是 XNOR,你还得再加一级反相器!
于是你会发现:纯互补CMOS下,XOR很难少于12~16个晶体管。
工程实践方案:用NAND门搭建XOR(推荐做法)
既然直接构造困难,那就换个思路:用通用门搭积木。
利用德摩根定律和布尔代数变换,我们可以将XOR改写为全NAND结构:
$$
A \oplus B = \overline{\overline{(A \cdot \overline{B})} \cdot \overline{(\overline{A} \cdot B)}}
$$
换句话说:
- 计算 $U_1 = \overline{A \cdot \overline{B}}$ → NAND(A, ¬B)
- 计算 $U_2 = \overline{\overline{A} \cdot B}$ → NAND(¬A, B)
- Sum = NAND(U₁, U₂)
这就是经典的三NAND XOR结构。
所需模块清单:
| 模块 | 数量 | 晶体管数 | 功能说明 |
|---|---|---|---|
| 反相器(INV) | 2 | 2×2 = 4T | 生成 ¬A, ¬B |
| NAND门 | 3 | 3×4 = 12T | 实现三步逻辑 |
| 总计 | — | 16T | 完整Sum路径 |
虽然用了16个晶体管,但它的好处非常明显:
- 全部使用标准单元(INV、NAND),适合自动化综合;
- 易于布局布线;
- 在标准单元库中可直接调用,无需定制设计。
📌 提示:如果 ¬A 和 ¬B 能被其他模块共享(比如也供给Carry路径),还能进一步节省面积。
整合整体电路:半加器的完整CMOS蓝图
我们现在把两部分拼起来,形成完整的半加器。
最终晶体管构成汇总
| 功能模块 | 类型 | 晶体管数 | 备注 |
|---|---|---|---|
| Carry前级NAND | NAND2 | 4T | 使用A、B输入 |
| Carry后级反相器 | INV | 2T | 输出Carry |
| ¬A生成 | INV | 2T | 共享给Sum路径 |
| ¬B生成 | INV | 2T | 共享给Sum路径 |
| NAND1 (A, ¬B) | NAND2 | 4T | 中间项 |
| NAND2 (¬A, B) | NAND2 | 4T | 中间项 |
| NAND3 (整合) | NAND2 | 4T | 输出Sum |
🔥总晶体管数:4+2+2+2+4+4+4 = 22个MOSFET
所有器件均为标准互补CMOS结构,无动态逻辑、无传输门,完全静态可靠。
电路工作流程简析
- 输入A、B变化 → 同时触发Carry路径和反相器链;
- ¬A、¬B在约一个反相器延迟后建立;
- 两个中间NAND门输出更新;
- 最终NAND门计算出Sum;
- Carry经两级门延迟输出;
- 所有节点稳定后,结果可用于后续逻辑采样。
📌 关键路径分析:
-Carry路径:NAND + INV →2级门延迟
-Sum路径:INV → NAND → NAND →3级门延迟
因此,Sum比Carry慢一级,这在高速加法器设计中需要注意。
Verilog建模:连接抽象与物理世界
虽然我们讲的是晶体管级设计,但现代EDA流程离不开RTL描述。以下是基于上述结构的门级Verilog模型:
module half_adder(input A, B, output Sum, Carry); wire not_A, not_B; wire nand_carry_out; wire term1, term2; // 生成反相信号(可共享) inv u_inv1(not_A, A); inv u_inv2(not_B, B); // Carry = A & B nand u_nand_c(nand_carry_out, A, B); inv u_inv_c(Carry, nand_carry_out); // Sum = A^B nand u_nand1(term1, A, not_B); // NAND(A, ~B) nand u_nand2(term2, not_A, B); // NAND(~A, B) nand u_nand3(Sum, term1, term2); // NAND(term1, term2) endmodule // 标准单元定义(映射到底层晶体管) module inv(input in, output out); pmos (out, VDD, ~in); // PMOS导通当in=0 nmos (out, GND, in); // NMOS导通当in=1 endmodule module nand(input a, b, output out); wire pnode; // PMOS并联 pmos p1(pnode, VDD, ~a); pmos p2(out, pnode, ~b); // NMOS串联 nmos n1(pnode, a); nmos n2(out, b); endmodule💡 说明:
- 这段代码虽未精确模拟寄生参数,但能被综合工具识别为具体门电路;
-pmos/nmos是Verilog中的晶体管原语,用于自定义单元设计;
- 实际流片前还需进行SPICE仿真验证时序与功耗。
设计权衡:速度 vs 面积 vs 功耗
任何电路设计都不是一成不变的,工程师需要根据应用场景做出合理选择:
| 优化方向 | 可行策略 | 效果 |
|---|---|---|
| 提速Sum路径 | 改用传输门XOR(6T)或CPL(互补传输管逻辑) | 减少至2级延迟,但增加设计复杂度 |
| 减小面积 | 共享 ¬A/¬B 反相器;采用8T专用XOR结构 | 可降至12~14T |
| 降低功耗 | 在非关键路径插入时钟门控;使用高阈值器件 | 减少动态翻转能量 |
| 提升驱动能力 | 对输出加缓冲器(buffer) | 增加2~4T,改善负载驱动 |
例如,在低功耗IoT设备中,可能宁愿多花几个晶体管换来更低的泄漏电流;而在高性能CPU中,则优先考虑减少关键路径延迟。
应用场景不止于“教学玩具”
别以为半加器只是教科书里的例子。它其实广泛存在于真实系统中:
- 多位加法器的基础单元:多个半加器可构成行波进位加法器(Ripple Carry Adder);
- 校验码生成:奇偶校验本质上就是一连串异或运算;
- 加密算法中的S-box:部分轻量级密码依赖简单逻辑组合;
- FPGA配置逻辑:查找表内部常驻此类基本结构;
- AI推理加速器:在二值神经网络(BNN)中,乘法退化为异或与计数。
甚至可以说:每一个现代处理器内部,都有成千上万个类似结构在默默运行。
写在最后:从半加器看数字设计哲学
通过这次深入剖析,你应该已经体会到:
数字集成电路设计,从来不只是“实现功能”那么简单。
它是关于结构、效率、折衷的艺术:
- 如何把数学公式翻译成物理开关?
- 如何在速度、面积、功耗之间找到平衡点?
- 如何利用工艺特性优化性能边界?
而这一切,都可以从一个最简单的半加器开始。
当你下次看到“1+1”的时候,不妨想想背后那22个精密协作的MOSFET,是如何在十亿分之一秒内完成这场沉默的舞蹈。
这才是真正的“硬核”浪漫。
如果你正在学习VLSI、准备面试,或是刚踏入IC设计领域,希望这篇文章能帮你打通“逻辑→电路”的任督二脉。欢迎留言交流你的实现思路或遇到的问题,我们一起探讨更多底层之美。