news 2026/4/13 20:17:45

用与非门实现8位加法器:零基础也能懂的方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用与非门实现8位加法器:零基础也能懂的方案

从与非门到8位加法器:用最简单的逻辑构建计算核心

你有没有想过,一台计算机是怎么做加法的?
它不像我们列竖式那样进位、相加、写下结果。它的“大脑”里没有数字,只有高电平和低电平——也就是1和0。而实现这一切运算的起点,可能仅仅是一个小小的与非门(NAND)

更惊人的是:只用一种逻辑门,就能造出能算两个8位数之和的电路。听起来像天方夜谭?但这不仅是理论可行,更是数字电路设计中极具教学价值的经典实践。

今天我们就来走一遍这条“从零开始”的路径:如何仅用与非门,一步步搭建出一个完整的8位加法器。即使你刚接触数字电路,也能看懂每一步背后的逻辑。


为什么选与非门?因为它“万能”

在所有逻辑门中,与非门是个特殊的存在——它是“功能完备集”,意味着:任何布尔函数,都可以只用与非门实现

这就像数学中的质数,或者乐高积木里的基础块。只要给你足够的与非门,你就能搭出非门、与门、或门、异或门……甚至整个CPU。

与非门长什么样?

它的逻辑很简单:

只有当所有输入为1时,输出才为0;否则输出为1。

真值表如下:

ABY
001
011
101
110

对应的布尔表达式是:
$$
Y = \overline{A \cdot B}
$$

别小看这个简单规则。正是这种“先与后非”的结构,让它具备了重构一切逻辑的能力。


第一步:把其他逻辑门“变”出来

既然只能用与非门,那我们就得想办法用它模拟出我们需要的所有基本逻辑单元。

非门(NOT)怎么实现?

很简单:把两个输入连在一起

assign Y = ~(A & A); // 等价于 ~A

电路连接上,就是把信号A同时接到与非门的两个输入端。如果A=1,输出就是0;A=0,输出就是1——完美实现取反。

成本:1个NAND门


与门(AND)呢?

我们知道:
$$
A \cdot B = \overline{\overline{A \cdot B}}
$$

所以只要对NAND(A,B)的结果再取一次反,就得到了原始的“与”。

也就是说:
1. 第一个NAND得到 $\overline{A\cdot B}$
2. 第二个NAND当作反相器,将其反转回来

成本:2个NAND门


或门(OR)也能做吗?

可以!利用德摩根定律:
$$
A + B = \overline{\bar{A} \cdot \bar{B}}
$$

步骤如下:
1. 用两个NAND分别生成 $\bar{A}$ 和 $\bar{B}$(各自接成反相器)
2. 把这两个反相信号送入第三个NAND
3. 输出即为 $A+B$

成本:3个NAND门


最关键的:异或门(XOR)

这是加法器的灵魂。因为一位二进制加法的本质就是异或运算。

回忆一下:
- $0+0=0$ → $0⊕0=0$
- $0+1=1$ → $0⊕1=1$
- $1+0=1$ → $1⊕0=1$
- $1+1=0$(进位)→ $1⊕1=0$

所以和(Sum) = $A ⊕ B$,而进位(Carry) = $A·B$

但XOR不能直接由单个NAND实现,需要巧妙构造。

标准NAND-based XOR使用4个门:

wire w1, w2, w3; nand(w1, a, b); // w1 = ~(a & b) nand(w2, a, w1); // w2 = ~(a & ~(a&b)) = ~a when b=1 nand(w3, b, w1); // w3 = ~(b & ~(a&b)) = ~b when a=1 nand(sum, w2, w3); // sum = ~(w2 & w3) = a ^ b

虽然推导略复杂,但你可以把它当成一个“黑盒模板”记住:4个2输入NAND门 = 1个XOR

成本:4个NAND门


第二步:构建最小加法单元——半加器

现在我们有了XOR和AND,就可以做一个最简单的加法器:半加器(Half Adder)

它处理两个1位数相加,输出和(Sum)与进位(Carry):

ABSumCarry
0000
0110
1010
1101

公式清晰:
- Sum = $A ⊕ B$ → 用4个NAND
- Carry = $A·B$ → 用2个NAND(第一个做NAND,第二个做反相)

不过注意!我们在XOR部分已经计算了 $\overline{A·B}$,可以直接拿来作为Carry路径的第一级输入,省去重复计算。

💡优化技巧:共享中间信号 $\overline{A·B}$,可将总门数压缩至5个NAND门


第三步:升级为全加器,支持进位传递

半加器有个致命缺陷:它不知道来自低位的进位。要构成多位加法,必须使用全加器(Full Adder)

全加器有三个输入:A、B、Cin(进位输入),输出Sum和Cout。

其逻辑关系为:
- Sum = $A ⊕ B ⊕ C_{in}$
- Cout = $AB + BC_{in} + AC_{in}$

我们可以用两个半加器来构造:

  1. 先用HA1计算 $A+B$ → 得到局部Sum1 和 Carry1
  2. 再用HA2将Sum1与Cin相加 → 得到最终Sum
  3. 最后用一个或门合并Carry1和新的进位 → 得到Cout

但如果只允许用NAND,就得全部拆解成NAND网络。

下面是推荐的结构化实现方式(基于布尔化简):

module full_adder_nand(input a, input b, input cin, output sum, output cout); wire p, g; // p = A^B, g = A·B wire s1, s2, s3; // 中间信号用于Sum wire c1, c2, c3; // 中间信号用于Carry out // Step 1: 计算 A ^ B → p wire ab_nand, a_ab, b_ab; nand(ab_nand, a, b); nand(a_ab, a, ab_nand); nand(b_ab, b, ab_nand); nand(p, a_ab, b_ab); // Step 2: Sum = p ^ cin wire p_cin_nand, cin_p_nand; nand(p_cin_nand, p, cin); nand(cin_p_nand, cin, p); nand(s1, p, p_cin_nand); nand(s2, cin, cin_p_nand); nand(sum, s1, s2); // Step 3: Carry out = g + (p · cin) // g = A·B wire g_nand; nand(g_nand, a, b); nand(g, g_nand, g_nand); // 取反得 A·B // temp = p · cin wire p_cin_nand_gate, temp; nand(p_cin_nand_gate, p, cin); nand(temp, p_cin_nand_gate, p_cin_nand_gate); // 取反 // Cout = g OR temp wire or_nand1, or_nand2; nand(or_nand1, g, temp); nand(or_nand2, g, temp); nand(cout, or_nand1, or_nand2); endmodule

这段代码完全由nand原语构成,每一行都对应一个物理门连接,适合用于FPGA底层建模或教学演示。

📌总结资源消耗
- Sum路径:约6个NAND
- Carry路径:约4~5个NAND
- 总计:每个全加器约需9~12个2输入NAND门


第四步:拼起来!组成8位加法器

有了全加器,接下来就简单了:串起来就行

采用经典的行波进位结构(Ripple Carry Adder)

FA0 ← FA1 ← FA2 ← ... ← FA7 ↑ ↑ ↑ ↑ A0B0 A1B1 A2B2 A7B7 ↑ ↑ ↑ ↑ Cin=0 C1 C2 C7 → C_out ↓ ↓ ↓ S0 S1 S7

连接规则非常直观:
- 最低位FA0的 Cin 接地(0)
- 每一级的 Cout 连接到下一级的 Cin
- 所有A、B并行输入,所有Sum并行输出
- 最终得到8位和S[7:0]以及最高位进位C8

这就是一个完整的8位加法器!


实际工程考虑:不只是理论游戏

你说:“现在谁还用手动搭门电路?”
确实,现代FPGA用查找表(LUT)几秒钟就能综合出加法器。但我们坚持用NAND实现,并非为了替代工业方案,而是为了理解本质

但在某些真实场景下,这种方法依然有价值:

✅ 教学实验

高校《数字逻辑》课程常用此项目训练学生:
- 理解组合逻辑设计流程
- 掌握门级抽象与模块化思想
- 动手焊接验证真值表

✅ 老旧设备维修 / 自制CPU

如果你在做一个复古风格的分立元件CPU,手上只有74HC00芯片(每片含4个2输入NAND门),那么这个方案就是救命稻草。

按前面估算:
- 每个FA约10个NAND
- 8位共需约80个NAND
- 使用74HC00(每片4门)→ 需要20片IC

虽然看起来很多,但布局合理的话,一块双面板完全可以容纳。


布局与调试建议

PCB设计要点:

  • 按从右到左(低位到高位)排列FA模块,符合进位传播方向
  • 进位线尽量短且直,避免与其他信号交叉
  • 每片IC旁放置0.1μF陶瓷电容,抑制电源噪声
  • 底层铺完整地平面,提升抗干扰能力

测试方法:

  • 输入:用拨码开关设置A[7:0]和B[7:0]
  • 输出:用8个LED显示Sum,1个LED显示Cout
  • 验证典型情况:
  • 0 + 0 → 0
  • 255 + 1 → 0(溢出,Cout=1)
  • 85 + 85 = 170(0x55 + 0x55 = 0xAA)

局限性与进阶思路

当然,行波进位结构也有明显缺点:速度慢

因为进位要一级一级传递,第7位的结果必须等第6位的Cout稳定后才能计算。对于8位系统,延迟尚可接受;但位数再多就不现实了。

如何提速?试试超前进位加法器(CLA)

CLA的核心思想是:提前预测每一位的进位,而不必等待前一级。

它引入两个新信号:
-Generate(G):本位自己产生进位(如A=B=1)
-Propagate(P):本位会传递进位(如A≠B)

然后通过并行逻辑直接计算各级Cin,大幅缩短延迟。

有趣的是:这些PG逻辑同样可以用NAND门实现。只不过结构更复杂,需要更多门和布线。

但对于追求性能的设计来说,这是必经之路。


回到初心:简单规则如何造就复杂智能

当你站在今天的高度看计算机,它似乎无比复杂:多核CPU、GPU、AI加速器……但追根溯源,它们的算术核心,依然是由一个个最基本的逻辑门组成的加法器。

而这一切,都可以从一个小小的与非门开始。

这个项目的意义,从来不是为了取代现代芯片设计方法,而是提醒我们:

复杂的计算能力,本质上源于最简单的规则重复组合。

掌握这一点,你就掌握了通往现代计算机体系结构的大门钥匙。

无论你是初学者还是资深工程师,亲手走过这一趟“从NAND到Adder”的旅程,都会让你对“硬件如何执行指令”这件事,有更深的理解。


如果你正在学习数字电路、准备电子竞赛,或者只是好奇计算机内部是如何工作的,不妨试着在面包板上搭一个半加器,再一步步扩展到8位。你会发现,那些闪烁的LED背后,藏着人类智慧最纯粹的光芒。

欢迎在评论区分享你的实现过程或遇到的问题,我们一起探讨!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/24 4:24:47

共射极放大电路教学:multisim仿真电路图操作指南

共射极放大电路实战教学:从零搭建高增益仿真系统(Multisim全流程指南)你有没有遇到过这样的情况?理论课上听得头头是道——“基极电流微小变化,引起集电极大电流”“Q点要设在负载线中间”……可一到实验台前&#xff…

作者头像 李华
网站建设 2026/4/10 18:30:13

Unity命令行:自动化构建的神器

文章摘要 本文介绍了Unity命令行的核心概念与实际应用。命令行模式允许开发者通过脚本控制Unity,无需手动操作界面,适用于自动化构建、CI/CD流程和批量处理任务。文章通过典型场景(如多渠道打包、自动化测试)说明命令行的必要性,并详细解析了关键参数:-batchmode(无界面…

作者头像 李华
网站建设 2026/4/8 18:04:18

工业环境部署vivado安装教程操作指南

工业级Vivado部署实战:从零搭建稳定可靠的FPGA开发环境 你有没有遇到过这种情况?在工厂测试台上准备调试一块Zynq核心板,结果打开Vivado时界面卡死、许可证报错,甚至安装过程直接中断——而背后可能只是一行缺失的库依赖或一个未…

作者头像 李华
网站建设 2026/4/1 4:11:19

SiFive平台移植RISC-V裸机程序从零实现指南

从零开始在 SiFive 平台运行 RISC-V 裸机程序:不只是“点灯”,而是真正理解底层启动机制你有没有试过,在一块全新的开发板上连一个 LED 都点不亮?不是代码写错了,也不是接线问题——而是程序根本没跑起来。这种情况在裸…

作者头像 李华
网站建设 2026/4/10 20:28:22

驱动程序安装方式对比:图形化vs命令行通俗解释

驱动安装的两种“语言”:图形界面 vs 命令行,你该用哪一种?你有没有遇到过这种情况——新买了一台打印机,插上电脑却提示“未识别设备”,于是你打开厂商官网,下载了一个.exe文件,双击运行&#…

作者头像 李华