
“计算机如何存储1位二进制数”这个问题看起来简单到不值一问不是0就是1嘛。可真要把这一位二进制数从一个普通的门电路里“存住”你会发现连保持一个稳定状态都需要精心设计。很多刚接触数字逻辑的同学第一章就被各种触发器、锁存器、真值表绕晕了其实它们都围绕着同一个目标让电路记住一个比特。这篇文章我打算从最底层的需求讲起用六个章节把“存储1位数据”这件事彻底拆开涉及与非门的交叉反馈、RS触发器的不定状态、D锁存器的透明窗口、边沿触发器的时序原理最后再看它怎么组合成内存里的一个字节。适合刚学数字电路、正在准备复试或面试、以及想补计算机组成原理底层知识的读者参考。1. 存储的本质为什么“记住一个数”比想象中难1.1 导线和组合逻辑都“记不住”东西先做一个很直接的实验拿一根导线一端接高电平另一端接一个LED灯。你把手松开LED还亮吗当然亮因为电压源还在供电。但这不是“存储”只是输入信号一直保持在那里。只要你把信号撤掉灯立刻熄灭。换句话说导线本身不产生任何状态它只是传递状态。再看最简单的组合逻辑电路比如一个与门。它的输出由当前两个输入决定输入一旦变化输出立刻跟着变。这种“随时随地跟着输入走”的特性决定了组合逻辑没有记忆能力。你想让它记住“刚才输入是多少”门电路自己是办不到的。那么存储需要什么需要电路拥有一种能力输入端撤掉之后输出端仍然维持原来的值。数学上这叫“状态保持”实现它必须引入一个关键机制——反馈。1.2 存储的基本模型是“双稳态”反馈的意思是把电路的输出接回自己的输入让电路自己决定自己的状态。想象一个跷跷板它有两个稳定位置左边压低、右边抬起或者反过来。如果没有外力去推它它会一直停在当前这一侧。这个比喻用来理解存储单元特别贴切——存储单元本质上就是一个“双稳态”系统它有两个稳定状态正好对应二进制里的0和1。数字逻辑里最经典的双稳态结构是把两个反相器或与非门首尾相接。这种结构没有外部输入时能维持状态有外部输入时能改写状态。要理解计算机怎么存1位二进制数核心就是理解这种“交叉反馈”结构是怎么构成、怎么工作、又是怎么被控制的。2. 手搓记忆单元两个与非门的交叉反馈2.1 最小存储结构基本RS触发器我们直接动手搭。找两个二输入与非门命名为G1和G2按下面的方式连接G1的一个输入是S置位信号另一个输入接G2的输出记为/Q。G2的一个输入是R复位信号另一个输入接G1的输出记为Q。也就是说G1的输出Q接到G2的输入G2的输出/Q接到G1的输入形成交叉反馈。这就是数字逻辑教材里最常见的基本RS触发器也叫SR锁存器。光看结构可能有点抽象我换个说法两个门你咬我、我咬你谁的状态都由对方的状态和外部输入共同决定。只要有一个门先确立了输出另一个门会被它带着走整个电路就稳定在一个方向上。这就是双稳态的电路表达。2.2 四个输入组合逐个推演假设一开始让电路处于Q1、/Q0的状态。如果把S和R都置为1会发生什么看G1输入S1、/Q0与非门“有0出1”所以Q保持1。看G2输入R1、Q1两个都是1与非门“全1出0”所以/Q保持0。电路稳稳地停在Q1。反过来如果初始是Q0、/Q1同样在S1、R1的条件下电路也稳稳地停在Q0。结论很关键S1且R1时电路维持原状态不变。现在试着改写状态。要让Q变成1就把S拉低到0G1输入S0、/Q0与非门有0出1Q被强制拉高到1G2输入R1、Q1输出/Q变成0。整个切换完成后即使把S重新拉回1电路已经靠交叉反馈维持住Q1了。这就是“置位”。要让Q变成0就把R拉低G2输入R0、Q0输出/Q被拉高到1G1输入S1、/Q1输出Q被拉到0。即使R释放回1Q0照样保持。这就是“复位”。整理成真值表输入S输入R输出Q输出/Q状态说明11保持保持维持原状态0110置位写入11001复位写入0001或0不确定禁止使用注意这里用的是“低电平有效”S0表示请求写入1R0表示请求写入0。至于最后一个组合为何被禁止下一节专门讲。3. 基本RS触发器的“脾气”不定状态与亚稳态3.1 为什么S和R不能同时为0真值表里最后一行S0且R0时两个与非门的输入里都有一个0所以两个输出都会被强拉到1。这时Q1且/Q1同一个存储单元两个输出端竟然相同这既不符合Q和/Q互补的约定也意味着电路不再处于“双稳态”中的任何一个。真正麻烦的是接下来的释放过程。假设你让S和R同时从0跳回1G1和G2这两个门会同时开始“竞争”G1想根据/Q决定输出G2想根据Q决定输出可此刻Q和/Q都是1两边都在等待对方先变化而实际电路里两个门的传播延迟不可能完全相等。谁先反应过来谁就主导最终状态。结果就是你完全无法预测这次释放后Q到底是1还是0。同样的操作重复100次可能出现50次得1、50次得0甚至出现中间电平的振荡。提示数字逻辑仿真软件里遇到这种不确定状态波形上会显示一个X或一条毛刺这就是“不确定”的直观体现。仿真里能看出来实物电路里更严重。3.2 亚稳态数字系统里最隐蔽的杀手S和R同时为0后释放产生的中间电平行话叫“亚稳态”。它不像正常的高电平或低电平而是徘徊在阈值附近的电压。最要命的是亚稳态会被后续门电路一级一级传递下去导致整个系统行为随机。在实际项目中凡是涉及跨时钟域信号处理的同学对亚稳态三个字肯定不陌生。它的根源和当年这个小小的RS触发器“竞争”是完全同一类物理现象。因此工程上基本RS触发器的使用有一条铁律绝不允许S和R同时有效。但也正因如此两个输入端同时干预的模型太“娇气”使用体验也很差。我们需要一种受控的、不会产生禁态的存储结构这自然引出了增加一个“使能开关”的思路。4. 加一扇门解决问题电平触发D锁存器4.1 用使能信号挡住“禁止组合”思路很直接普通人操作存储单元时希望只告诉它“你要存的是0还是1”再告诉它“什么时候开始存”。前者用一根数据线D后者用一根控制线EN使能。至于S和R怎么生成、怎么保证不会同时为0交给电路内部自动处理。标准做法是在基本RS触发器前面加两个与非门一个门输入接EN和D另一个门输入接EN和D的反相信号。这样EN0时后面两个门各自输出1基本RS触发器进入“保持”状态EN1时如果D1则等效于S有效、R无效往存储单元写入1如果D0则等效于S无效、R有效写入0。真值表非常干净使能EN数据D输出Q0任意保持不变11输出110输出0这种电路就是D锁存器。它解决了禁止组合的问题同时对外只暴露一根数据输入和一根控制输入使用体验好得多。4.2 “透明窗口”带来的新烦恼但D锁存器有一个特性初学者特别容易忽略EN为高电平的整个期间输出Q都会跟着D跑。D变1Q立刻变1D变0Q立刻变0。也就是说D在这个窗口期内的任何抖动都会被Q忠实地复现出来。这个窗口期就叫“透明窗口”所以D锁存器又叫“透明锁存器”。为什么这是个问题在真实系统里数据信号往往在持续变化。CPU内部多个单元并行工作如果某个存储单元在EN高电平期间一直“偷看”输入它就会记录下电压波动过程中的任意中间值而不是我们期望的、在某个确定时刻的稳定值。就像一个学生在老师念答案的全过程中不停涂改答题卡等真正交卷时反而不知道哪一笔才算数。4.3 从锁存到采样的跃迁要想摆脱透明窗口必须让存储单元只在某个瞬间“看一眼”输入其余时间一律保持。这个观念转变是理解同步时序电路的钥匙。我们需要的不再是“电平使能”而是“边沿触发”。用一个很生活化的类比D锁存器像你一直开着录音笔声音全程录边沿触发器像相机快门只在按下瞬间捕捉画面。计算机电路需要的显然是快门不是录音笔。因为所有模块都需要在统一的节拍下、在同一个时间点采样数据否则各模块看到的数据版本不一致整个系统就乱套了。5. 从锁存器到边沿D触发器计算机里的正式“记忆细胞”5.1 主从结构的接力赛边沿触发怎么实现最常见也是最容易理解的方法是用两个D锁存器级联一个当“主锁存器”一个当“从锁存器”它们的时钟信号互为反相。CLK为高电平时主锁存器使能D信号进入主锁存器此时从锁存器的使能为低输出端Q保持原值不动。接着CLK变为低电平主锁存器立刻关闭把它在刚才高电平期间最后采到的D值锁住同时从锁存器打开接收主锁存器输出。最终Q在CLK由高变低的这一刻更新为新值。这就是下降沿触发的D触发器。如果你换一种接法让两个锁存器先选通反转就能得到上升沿触发。但原理完全一致整个电路对外呈现出“只在时钟边沿瞬间采样输入其他时间输出稳定不变”的特性。5.2 建立时间与保持时间既然触发器只在边沿采样那么输入数据就必须满足两个条件建立时间在时钟边沿到来之前数据必须已经稳定并且至少稳定这么长一段时间让主锁存器来得及读取。保持时间在时钟边沿过去之后数据不能立刻变化要再维持一小段时间让内部锁存动作顺利完成。把建立时间和保持时间画在时序图上就是时钟边沿前后各有一个“禁止数据变化”的窗口区。工程里所有时序约束、静态时序分析本质上都是在检查这个窗口是否被满足。我见过不少FPGA初学者功能写对了却跑不出时序最后查下来都是建立时间违例——数据变化太晚触发器采到的已经不是你想要的那个值。提示开发板上调试时如果系统偶尔出现“灵异现象”先把时钟频率降下来试试。频率降低通常能缓解建立时间问题帮助定位是不是时序裕量不足。6. 1位到8位拼出你内存里的一个字节6.1 并行复制8个触发器组成寄存器有了单个边沿D触发器往“一个字节”扩展就只剩下体力活了。拿8个D触发器把所有时钟端短接在一起每个触发器分配一根独立的数据输入线和一根独立的输出线。在某个时钟边沿来临时这8个触发器同时采样自己的输入各自锁存一位数据合在一起就是一个8位的寄存器。这也是为什么寄存器本质上叫“一组触发器”它们共享时钟但每个位单独存储。你往寄存器里写数据时只要把8位数据一次性放到数据线上再给一个时钟脉冲8个触发器会在同一时刻集体完成写入。所以寄存器的位宽、数据总线宽度其实是由触发器数量直接决定的。6.2 双稳态思想在SRAM和DRAM里的延续再往深处走一步现代内存的存储单元本质上也是在玩同样的双稳态游戏。SRAM的一个单元通常用6个晶体管搭成核心部分是两个交叉耦合的反相器负责维持0或1两边各有一个访问管由字线控制是否把这个单元的存储节点连接到外部位线上。你仔细对比就会发现它跟D锁存器的思路高度相似交叉反馈维持状态控制信号决定是否读写。DRAM则换了一套物理机制。它不靠双稳态锁存而是在一个微型电容上存电荷有电荷代表1无电荷代表0。电容会漏电所以DRAM需要周期性刷新来补电荷。这也是为什么DRAM比SRAM便宜但更复杂必须在内存控制器里安排刷新逻辑。把这条线串起来你能看到一条清晰的主线计算机存储1位二进制数从最原始的双稳态电路开始经过RS触发器、D锁存器、边沿D触发器再到SRAM和DRAM一路都在解决三件事——如何保持状态、如何受控改写状态、如何让所有存储单元在同一个节拍下协同动作。我自己在学数字逻辑时最大的教训就是不要死记真值表一定要亲手推一遍两个与非门交叉反馈的状态变化过程。只要理解了Q和/Q互相牵制的逻辑后面锁存器、触发器乃至整个时序电路的知识就全都串联起来了。拿到实验板或仿真软件时也可以先强制把RS触发器的S和R同时拉低再同时释放亲眼看一次那种不确定的输出比读十遍“禁止组合”都印象深刻。