新闻详情

新闻详情

首页 / 资讯中心 / 详情

两个元件搭建CPU:从与非门到逻辑运算的完整路径

发布时间:2026/9/17 6:01:19来源:尧图网络
两个元件搭建CPU:从与非门到逻辑运算的完整路径
开篇先说个反直觉的结论CPU 内部没有任何智能可言也没有藏在某个角落里的灵魂芯片。你去拆一颗现代 CPU用显微镜看它的硅片看到的只有几十亿个极其规则的微小结构它们全都是由同一种东西堆出来的——逻辑门。而逻辑门继续往下拆能拆到两个最底层的万能元件与非门NAND和或非门NOR。标题里说的2个元件构成了非常巧妙的逻辑在我理解就是指这一对数字电路里的万能积木。这篇文章就把这个从两个门到一颗 CPU 的完整链条讲清楚适合正在学数字逻辑、计算机组成原理或者准备做单周期 CPU 课程设计的同学看完你会对CPU 为什么能算、能记、能执行指令有一个从底层到顶层的通透认识。1. 为什么偏偏是这两个元件——万能门的底牌1.1 先看懂与非门和或非门到底是什么与非门NAND说白了就是先与、再非输入 A 和 B 都为 1 时输出为 0其他任何情况输出都是 1。或非门NOR则是先或、再非输入 A 和 B 只要有一个为 1输出就是 0只有当两个输入都为 0 时输出才为 1。两张真值表摆出来一切就清楚了ABA NAND BA NOR B0011011010101100很多初学者看到这两张表的第一反应是这不就是两个普通逻辑门吗有什么神奇的真正神奇的地方在于任何逻辑电路大到 CPU 里的一个 64 位加法器小到一个指示灯开关电路都可以只用与非门、或者只用或非门搭出来。这种性质在数字逻辑里叫功能完备性Functional Completeness。也就是说你不需要准备与门、或门、非门、异或门一大堆门电路只需要 NAND 一种门就能把它们全部变出来同样NOR 一种门也能做到。1.2 为什么功能完备性对 CPU 如此重要这里要理解一个工程层面上的逻辑芯片工厂生产逻辑门不是像写代码那样需要什么就现写什么。在硅片上每多一种门电路类型就意味着多一套掩膜版、多一组工艺验证、多一批潜在缺陷点。假如 CPU 里同时要使用与门、或门、非门、异或门、同或门等十几种门制造复杂度会直线上升。而一旦确认只需要 NAND 和 NOR 两种基础单元就能表达任何逻辑整个芯片后端设计就变得极其规整——标准单元库里用这两种门做骨架EDA 工具自动化地完成几十亿晶体管的布局布线。我当年第一次在 Logisim 里做单总线 CPU 设计时老师给了一个硬性要求基础门只能用 NAND 和 NOR。当时还觉得是故意刁难做到一半才明白这个限制反而逼你理解了逻辑化简的本质用最少的门类型、最少的总门数完成同样的功能这正是工业界芯片设计的常规操作。1.3 一个容易踩的误区与非门不是先与后非两步很多人画电路图时潜意识里把 NAND 当成了一个与门后面挂一个非门想当然地以为它有时序上的先后。实际上在组合逻辑里NAND 就是一个独立的完整逻辑单元不存在先与后非的中间节点。这一点在做门级延迟分析时特别关键一个 NAND 门的传播延迟是固定的而不是与门延迟 非门延迟。如果在 Logisim 里用分立的与门和非门去搭仿真波形看起来差不多但到了真实电路里时序预算完全对不上。2. 从两个门变出全套逻辑——只用手头这两张牌2.1 用与非门搭出非门、与门、或门先动手做最基础的三件事。把 NAND 的两个输入端短接在一起输入 A输出就是 NOT A。原因很简单当 A0 时NAND(0,0)1当 A1 时NAND(1,1)0。这就是一个标准的反相器。搭与门也不难先用 NAND 得到 NOT(A AND B)后面再接一级输入短接的 NAND也就是非门双重取反就回到 A AND B。表达式写出来就是AND(A,B) NAND(NAND(A,B), NAND(A,B))搭或门稍微绕一下但这里恰好是理解德摩根定律的最佳现场。德摩根定律说NOT(A OR B) (NOT A) AND (NOT B)反过来 NOT(A AND B) (NOT A) OR (NOT B)。利用它可以得到OR(A,B) NAND(NOT A, NOT B) NAND(NAND(A,A), NAND(B,B))也就是说先把 A、B 各自取反再对两个反相信号做 NAND。你可以逐行代入真值表验证A0、B1 时NAND(A,A)1NAND(B,B)0再 NAND(1,0)1结果确实等于 0 OR 1 1。2.2 再接再厉用与非门搭出异或门比与或非再进一步的是异或门XOR它才是计算器里真正的主角——因为二进制加法的本质就是异或。用 NAND 搭 XOR常见做法是先构造中间信号S1 NAND(A,B) XOR(A,B) NAND( NAND(A,S1), NAND(B,S1) )这个结构很多教材直接给结论但你要真正理解它的逻辑当 A、B 都为 1 时S10导致 NAND(A,S1)NAND(1,0)1、NAND(B,S1)1最终输出 0符合异或相同为 0的定义当 A、B 都为 0 时S11NAND(A,S1)1最终 NAND(1,1)0也符合相同为 0。剩下两种一真一假的情况你代进去会发现输出都是 1。折腾这一圈你已经证明了一件事只用一种 NAND 门就能表达完整的布尔逻辑。NOR 门也能完成同样的推导只是中间信号的具体搭法略有差别。2.3 异或门在 Logisim 仿真里的一个坑很多同学在 Logisim 里搭上述异或门时会遇到输出总是 1或者偶尔是 0的怪现象。排查后发现大多数情况是因为连线没有画到门的同一个输入引脚上或者把 NAND 的输入顺序接反了。还有一类问题是为了省事直接调用 Logisim 自带的 XOR 元件然后手动尝试用真值表去对齐自定义电路忽略了 NAND 搭建的 XOR 可能存在输出阻抗不匹配的问题——这在实际晶体管级电路里更明显但在 Logisim 这种纯逻辑仿真工具里通常看不出来等以后做版图设计时你才会碰壁。所以建议初学者养成习惯每个中间节点都命名并在 Logisim 里贴上标签总线Label方便逐点查波形。3. 会算数了——用门电路搭出二进制加法器3.1 半加器的门级实现加法是 CPU 运算能力的起点。先看一位二进制加法A 加 B输出两个量一个是本位和Sum一个是进位Carry。真值表很简单0000010110011110。对照这个表你会发现Sum 恰好就是 A XOR B而 Carry 恰好就是 A AND B。上一节刚搭好 XOR 门现在把它连接一个 AND 门就得到了半加器Half AdderSum A ⊕ B Carry A · B在 Logisim 里测试时把 A、B 接到两个输入引脚Sum 和 Carry 各接一个 LED拨动开关你会看到 LED 的亮灭完全符合真值表。这一步虽然简单但它揭示了 CPU 运算背后的核心思想一切算术运算归根到底都是逻辑运算的组合。CPU 里没有乘法器芯片那种神秘的东西只有一堆异或门、与门、或门按特定方式连在一起。3.2 全加器处理进位才是难点半加器只能处理两个一位数相加但多位加法里每一位都要考虑来自低位的进位。于是需要全加器Full Adder它有三个输入 A、B、Cin来自低位的进位两个输出 Sum 和 Cout向高位的进位。逻辑表达式是Sum A ⊕ B ⊕ Cin Cout A·B Cin·(A⊕B) 或者等价地 Cout A·B A·Cin B·Cin用上一章搭好的 XOR 和 AND、OR 门可以比较直观地搭出全加器先用一个 XOR 得到 A⊕B再和 Cin 做第二次 XOR 得到 Sum进位部分用一个与门计算 A·B再用一个与门计算 Cin·(A⊕B)最后用或门把两路进位合并。这里有一个常见的理解误区用两个半加器拼一个全加器是可行方案但不是唯一方案。你完全可以直接做卡诺图化简得出更紧凑的表达式。比如 Cin·(A⊕B) 这个中间信号在门级实现时可以和 Sum 共用一部分电路从而节省门数。我在做单总线 CPU 课程设计时对比过两种做法直接教科书式搭法用了 19 个 NAND 门化简后的紧凑实现只要 14 个 NAND 门。别小看这 5 个门的差距一个 8 位加法器就是 40 个门放到 64 位 ALU 里就是几百个门的差别功耗和延迟都跟着变化。3.3 进位链的延迟为什么 CPU 不能无限提高频率全加器串联成多位加法器时低位进位要一级一级往上传递这就是行波进位加法器Ripple Carry Adder。它的最大问题是最坏情况下进位要从最低位一直滚到最高位每一位全加器都有固定的门延迟所以位数越多整个加法器的延迟就越长。这直接限制了 CPU 主频的提升——一条加法指令的执行时间被最长路径的延迟卡死。为了解决这个问题芯片里用到了超前进位加法器Carry Look-ahead Adder核心思想是提前计算每个位置的进位生成信号GenerateG A·B和进位传播信号PropagateP A⊕B再用并行逻辑一次性算出各级进位。这是一个典型的用面积换速度的工程权衡更复杂的逻辑、更多的门换来更短的延迟。理解了这个取舍你再看 CPU 里的整数加法器、浮点运算器就能明白那些看似复杂的结构本质上都是在时间和面积之间做妥协。4. 会记忆了——从两个门到触发器时序逻辑的诞生4.1 反馈回路两个与非门组成 SR 锁存器组合逻辑只能根据当前输入产生输出它没有记忆。但 CPU 必须记住状态程序计数器 PC 要记住下一跳指令地址寄存器要暂存运算中间结果。怎么让电路记住东西答案是反馈Feedback——把输出接回输入。拿两个 NAND 门做一个最简单的 SR 锁存器第一个 NAND 的输出接到第二个 NAND 的一个输入第二个 NAND 的输出再接回第一个 NAND 的另一个输入。外部输入是 S置位和 R复位。这个交叉耦合的结构非常巧妙当 S1、R1 时电路保持原来的状态S0、R1 时输出 Q1完成置位S1、R0 时输出 Q0完成复位而 S0、R0 是禁止态因为两个输出会同时为 1破坏 Q 和 !Q 互补的关系。我在 Logisim 里第一次搭这个电路时盯着波形看了半天才真正理解所谓的记忆不过是有两个信号互为对方的输入互相维持对方的电平。没有魔法就是最基本的 0 和 1 相互顶住。4.2 加入时钟从锁存器到 D 触发器SR 锁存器的最大问题是输入一变输出立刻跟着变而且有禁止态。实际 CPU 需要的是在某个精确的时间点把输入值锁存住于是引入了时钟信号。先做 D 锁存器在 SR 锁存器前面加两个与门把 S 和 R 统一成一路输入 D 和时钟 CLK当 CLK1 时输出跟随 D 变化CLK0 时输出保持。但这还不够——CPU 是同步时序系统它要求在时钟边沿上升沿或下降沿这个瞬间采集数据而不是整个高电平期间都透传。这就引出了边沿触发的 D 触发器Flip-Flop也就是需要两级锁存器串联形成主从结构。第一级为主触发器第二级为从触发器。时钟上升沿到来前主触发器采样输入沿到达后主触发器把数据传给从触发器同时自己与输入隔离。这个边缘采样的行为让整个 CPU 可以有一个统一的节拍所有寄存器在同一时刻同时更新互不干扰。4.3 时序预算建立时间和保持时间CPU 稳定性的命门真正做 CPU 设计时有两个参数几乎天天挂在嘴边建立时间Setup Time和保持时间Hold Time。建立时间要求数据必须在时钟沿到来之前提前一段稳定时间到达触发器输入保持时间要求时钟沿过后数据还要继续稳定一小段。如果违反了这两个要求触发器输出就会出现亚稳态——既不是确定的 0 也不是确定的 1而是悬在中间的不稳定状态可能把后续电路全部带乱。这解释了为什么 CPU 有最高主频限制两个触发器之间的组合逻辑延迟如果太长超过了时钟周期减去建立时间数据就来不及在下一个沿之前稳定下来。同时它也解释了为什么超频到极限后系统会随机出错——不是所有门都扛不住而是某个最差路径的时序已经崩溃了。当年我在 Logisim 里做单周期 CPU仿真环境下高速时钟永远不会出错但同样的设计换到真实 FPGA 上跑高频就频繁出问题原因就在这里。5. 串起来——从寄存器、ALU 到一条指令的完整旅程5.1 CPU 的器官寄存器堆与 ALU有了 D 触发器下一步就是抠出 CPU 的骨架。寄存器堆Register File就是一组D触发器加上读写译码逻辑用于暂存操作数和运算结果。在 MIPS 单周期 CPU 中寄存器堆有 32 个 32 位寄存器读两个、写一个需要设计独立的读端口和写端口还需要考虑写冲突处理——同一周期内写入和读出同一个寄存器到底是以旧值还是新值为准这是课程设计里很容易忽略的细节。ALU算术逻辑单元则是把所有运算逻辑集中在一起加法、减法、与、或、异或、比较等。它的本质就是一张大的真值表——根据控制信号 3 位或 4 位从多个运算结果中选择一个输出。关键点在于ALU 里的各种运算单元是并行计算的比如加法器和比较器同时都在跑最后用多路选择器MUX根据控制信号选出结果。这种并行计算 选择输出的模式和软件里的 if-else 完全不同是理解 CPU 高性能的基础。5.2 控制信号CPU 的指挥中心如果说 ALU 是 CPU 的肌肉寄存器堆是记忆那控制器就是大脑。控制器接收指令的操作码和功能码通过译码逻辑产生一堆控制信号告诉 ALU这次做加法告诉寄存器堆这个周期要写回结果告诉 PC下一条指令要不要跳转。在单周期 CPU 设计里控制器通常用 ROM 或者组合逻辑实现把每条指令需要的控制信号做成一张表。我做了 MIPS 单周期 CPU 课程设计后最直观的感受是每条指令本质上就是一个状态字。比如add rd, rs, rt这条指令控制表里 RegDst1、ALUSrc0、MemtoReg0、RegWrite1、ALUSelect0010。这些 0 和 1 不是随便填的它们直接驱动硬件电路完成一连串动作。写控制表的时候建议边写边画数据通路对着图核对每一个信号流向不然很容易漏信号。此前见过很多同学在这里翻车原因都是只看指令名字不看数据通路。5.3 单总线 CPU 的独有难点总线的竞争与仲裁热搜里反复出现单总线 CPU 设计这里单独说一下。单总线结构意味着所有部件都挂在一组 32 位数据总线上同一时刻只能有一个部件向总线写数据。这就产生了一个核心问题输出控制——每个部件的总线输出端都要加三态门缓冲器只有被控制信号选中的那个部件才开通三态门把数据送上总线其余部件的输出都处于高阻态。高阻态Z在 Logisim 仿真里经常被忽略因为默认状态下未连接的网络可能被当成普通未接状态处理但实际做总线模拟时会遇到多个输出同时驱动总线的冲突报错。我的教训是搭单总线 CPU 前先把每个部件的输出使能信号列成一个矩阵表格横轴是部件纵轴是控制信号确保任何一拍只有一个使能位为 1。设计完成后使用 Logisim 的分步时钟逐步验证每条指令的取指、译码、执行过程避免一次性跑整体导致出错后根本不知道问题在哪个环节。5.4 一条指令的完整旅程以加载指令为例拿lw rt, offset(rs)从内存读数据到寄存器这条指令来走一遍。第一步PC 寄存器输出当前指令地址送往指令存储器同时 PC 要经过加法器加 4 得到下一条指令地址分支处理这里简化不做展开。第二步读出的指令被拆分成字段opcode 告诉控制器这是lwrs 字段送到寄存器堆作为读地址之一rt 字段作为目标寄存器地址offset 低位部分经过符号扩展成为 16 位到 32 位的立即数。第三步ALU 将寄存器堆读出的 rs 值和扩展后的立即数相加得到内存地址送往数据存储器。第四步数据存储器在控制信号的驱动下把对应地址的数据读出到总线上。最后一步数据总线上的值经写回通路进入寄存器堆的写端口在时钟沿写入 rt 寄存器。整个流程就是这么一环扣一环。这整个过程里你会在每一步都看到前面章节提到的门电路的影子PC 加 4 用的是加法器里面全是 NAND 搭的 XOR控制译码用的是逻辑门阵列寄存器堆的写入里面是 D 触发器。可以说CPU 的灵魂不是什么玄学就是这些基础逻辑单元按一个精妙的时序组织在一起。6. 落到硅片——CMOS 工艺下两个元件的真正身份6.1 物理层面看两个晶体管搭出一个基础门从数字逻辑层面看万能元件是 NAND 和 NOR 两个门但再往下钻一层到了芯片物理实现你会发现硅片上的基本积木其实是两种晶体管NMOS 管和 PMOS 管。一个 NAND 门用 4 个晶体管就能搭出来两个 PMOS 并联在上拉网络两个 NMOS 串联在下拉网络一个 NOR 门则反过来两个 PMOS 串联两个 NMOS 并联。这个结构的巧妙之处在于它完美实现了互补任何时刻从电源到输出的上拉通路和从输出到地的下拉通路保证只有一条导通。这保证了逻辑正确性同时静态功耗几乎为零——只有在翻转瞬间两条通路短暂同时导通才会产生电流。现代 CPU 几十亿晶体管绝大多数时间待在待机状态低压低功耗设计正是依赖这种互补特性。我曾经对照教科书把 NAND 门在晶体管级搭了一遍看到 PMOS 和 NMOS 的位置关系后才明白为什么 NAND 门比 NOR 门在工艺上更受青睐NMOS 的导通能力通常强于 PMOSNAND 结构里下拉网络是 NMOS 串联本质上对下降沿更友好而 NOR 结构里上拉网络是 PMOS 串联充电速度较慢。所以业界标准单元库里 NAND 门的占比往往高于 NOR 门。这也是为什么很多教材说多用 NAND少用 NOR。6.2 从门到核几十亿晶体管的层级组织你用 4 个晶体管得到一个 NAND 门用 14 个 NAND 门得到一个全加器用 64 个全加器得到一个 64 位加法器用加法器、乘法器、移位器组成 ALU用寄存器堆和数据通路组成一个核心再把核心、缓存、总线接口组合成一颗完整的 CPU。这是一个标准的自顶向下逐层封装过程。每一层都只对上层暴露接口对下层隐藏细节——这和软件工程里函数、模块、系统的分层思想惊人地一致。从这个角度看两个元件的内涵就更有意思了无论从逻辑门层面还是晶体管层面所有复杂度的根源都极其简单。说 CPU 可怕它确实有上百亿个晶体管说 CPU 可爱它的出发点真的就是两个基本单元加一堆连线。我在带学弟学妹做课程设计时经常说你要是觉得 CPU 难那就是还没把全加器 → ALU → 数据通路这条线打通真打通了后面就是水到渠成的事。6.3 懂门电路在工程里还有用吗有人可能会问现在写代码用 C、做设计用 Verilog谁还手工搭门电路我的回答是用不用是一回事懂不懂是另一回事。写 Verilog 时综合工具会把你写的a b映射成某个标准单元但如果你不理解门级结构就理解不了为什么同样的逻辑用不同的写法综合出来的面积和延迟差别巨大。做时序约束时不了解建立时间和保持时间的概念面对的时序报告就是天书。更直白点说芯片后端要做功耗优化、要修 hold violation、要做时钟树综合每一个环节都建立在我知道电路最终会变成一堆 NAND、NOR 门这个认知之上。到现在我自己调试电路时有两条实用经验值得分享第一遇到复杂逻辑先画真值表真值表能穷举所有情况比直觉可靠得多第二在 Logisim/FPGA 上做仿真时永远从最小子模块验证起全加器单独测通过了再连成加法器测加法器通过了再接到 ALU 里测。那种一口气把整个 CPU 画完再统一仿真、出了问题满头雾水的做法我至少见过二十个同学踩过坑。CPU 的灵魂不是某个部件而是这套从两个最简单元件出发通过分层组合逼近任意复杂功能的方法论。你能拿两个 NAND 门搭出一颗能跑指令的 CPU这本身就是整个计算机工程最迷人的地方。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

Uniapp跨平台开发实战:从零到发布全流程指南 2026/9/17 6:49:28

Uniapp跨平台开发实战:从零到发布全流程指南

1. 项目概述与核心价值作为一个长期混迹于前端开发领域的"老司机",我见证过太多新手在跨平台应用开发中踩坑。Uniapp作为目前最成熟的"一次开发,多端发布"解决方案,确实能大幅提升开发效率。但很多初学者从创建项目到最终…

阅读更多 →
计算机网络面试易错题精讲:分层模型、全双工与IP地址换算 2026/9/17 6:49:28

计算机网络面试易错题精讲:分层模型、全双工与IP地址换算

简介:这份资源是一份面向南方电网面试备考、聚焦计算机网络与通信基础知识的试题合集PDF,适合求职网络、通信、运维等岗位的应届生或职场人士复习使用。文件共1个PDF,整包约224KB,内容以判断题和单选题形式呈现,覆盖计…

阅读更多 →
手写迷你SpringBoot:启动流程、自动装配与内嵌Web服务器核心原理 2026/9/17 6:49:28

手写迷你SpringBoot:启动流程、自动装配与内嵌Web服务器核心原理

手写SpringBoot核心流程这件事,我其实惦记了很久。用了好几年的SpringBoot,每次看到那个SpringBoot的启动图标刷出来,心里总有个声音在问:它到底在main方法那一行里做了多少事?为什么一个空的Spring Boot项目就能把内嵌…

阅读更多 →
10bit SAR ADC设计实战:从架构原理到Virtuoso仿真验证 2026/9/17 6:49:28

10bit SAR ADC设计实战:从架构原理到Virtuoso仿真验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
Servlet+JSP协作开发实操:从Maven建项目到JSP编译原理 2026/9/17 6:49:28

Servlet+JSP协作开发实操:从Maven建项目到JSP编译原理

《Head First Servlet & JSP》这本经典的入门书,第三章正好是从“纯Servlet输出HTML”过渡到“Servlet JSP 分工协作”的关键节点。这篇笔记03,我打算换个玩法,不按目录一章章念,而是直接把这一阶段最常碰到的实操场景串起来…

阅读更多 →
CAN总线热失控检测模块设计与J1939工程实践 2026/9/17 6:46:27

CAN总线热失控检测模块设计与J1939工程实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞