作为一名数字电路设计者,你是否思考过这样一个问题:在纷繁复杂的逻辑芯片中,如果我们手头只有一种被称为“通用门”的组件,能否构建出所有需要的逻辑功能?
在数字电子技术的世界中,这不仅仅是一个假设,而是一种被称为“逻辑完备性”的强大特性。今天,我们将深入探讨这一核心概念中的经典案例:如何仅使用 NOR(或非)门来实现 OR(或)门的功能。
这篇文章不仅会带你重温基础,更会通过实际的分析、代码模拟和电路构建,向你展示底层逻辑是如何运作的。无论你是正在准备考试的学生,还是希望优化芯片面积的硬件工程师,理解这种“门级转换”都是必备的技能。
目录
核心概念回顾:OR 门与 NOR 门
在开始动手实现之前,让我们先快速确认一下这两位“主角”的身份和行为。这是构建复杂大厦前的地基。
什么是 OR 门(或门)?
OR 门是数字逻辑中最直观的门之一。它的逻辑就像我们在生活中的“或者”——只要满足其中一个条件,结果就成立。
在布尔代数中,它由加号(+)表示。
逻辑行为:
- 只要有一个输入为高电平(1/True),输出就为高电平。
- 只有当所有输入都为低电平(0/False)时,输出才为低电平。
2输入 OR 门方程:
$$Y = A + B$$
(视觉参考:标准的 OR 门符号,呈弯曲的 D 形,尖头指向右侧。)
什么是 NOR 门(或非门)?
NOR 门,全称为“Not OR”,本质上就是一个 OR 门后面紧跟一个 NOT 门(反相器)。它是 OR 门逻辑的否定。
逻辑行为:
- 如果任意输入为高电平,输出为低电平。
- 只有当所有输入都为低电平时,输出才为高电平。
2输入 NOR 门方程:
$$Y = \overline{A + B}$$
(视觉参考:标准的 OR 门符号,但在输出端有一个小圆圈,代表反相。)
为什么我们要用 NOR 门来实现 OR 门?
你可能会问:“既然已经有现成的 OR 门芯片,为什么还要多此一举用 NOR 门去搭建它?”
这是一个非常好的实战问题。在实际工程中,我们倾向于减少芯片库存的种类。NOR 门和 NAND 门被称为通用逻辑门,这意味着你可以用它们来构建任何逻辑功能(AND、OR、NOT、XOR 等)。
如果你在设计电路时,发现库存里只有 NOR 门,或者你的 ASIC 设计库为了优化面积只提供了 NOR 单元,你就必须掌握如何用 NOR 门“变”出其他逻辑。这正是我们今天要解决的问题。
理论分析:实现原理
要实现从 NOR 到 OR 的转换,我们需要运用布尔代数中的双重否定律。
让我们看看数学是如何推导的:
- 目标: 我们想要得到输出 $A + B$ (OR 门)。
- 现状: 我们有 NOR 门,其输出为 $\overline{A + B}$。
- 桥梁: 我们知道 $\overline{\overline{X}} = X$。这意味着,如果你对一个信号取反两次,它就变回了原来的信号。
- 推导:
$$Output = \overline{\overline{A + B}}$$
这里,第一层 $\overline{A + B}$ 是第一个 NOR 门的输出。
为了实现 OR 门的功能,我们需要对这个结果再次取反。
关键点: 我们如何用一个 NOR 门来充当反相器(NOT 门)?
请看 NOR 门的一个特性:如果我们将两个输入端连接在一起(A = B),输出就变成了 $\overline{A + A} = \overline{A}$。这就是 NOT 门!
结论: 我们需要两个 NOR 门。
- 第一个 NOR 门用于处理输入信号,产生中间结果(这里实际上是作为 OR + NOT 的第一步,但在纯 NOR 实现中,为了最简电路,其实有更简单的直接结构,见下文“直接并行法”的修正思路)。
- 修正:实际上,为了从 NOR 得到 OR,最简单的方法不是级联两个 2 输入 NOR 去做 Double Negation(那样太浪费),而是利用 De Morgan 定律 或者直接定义:
$A + B = \overline{\overline{A + B}}$
右边的 $\overline{A + B}$ 是一个 NOR 门。然后我们需要对整个 NOR 门的结果再取反。
如前所述,一个 NOR 门在输入短路时就是 NOT 门。
所以,电路结构是:
1. 第一个 NOR 门接收输入 A 和 B。输出 $Temp = \overline{A + B}$。
2. 第二个 NOR 门将 Temp 连接到它的两个输入端。输出 $Final = \overline{Temp + Temp} = \overline{Temp}$。
3. 结果:$\overline{\overline{A + B}} = A + B$。
这样我们就通过两个 NOR 门实现了 OR 门的功能。
代码实现与验证
作为现代开发者,我们在实际焊接电路之前,通常会用软件来验证我们的逻辑。下面我们用 Python 来模拟这个电路的行为。
示例 1:基础逻辑模拟
这个脚本模拟了我们刚刚设计的两级电路:第一级计算 NOR,第二级进行反转。
def nor_gate(a, b):
"""
模拟 2 输入 NOR 门
逻辑:只有两个输入都为 0 时,输出才为 1
"""
return int(not (a or b))
def nor_used_as_not(input_val):
"""
将 NOR 门配置为 NOT 门(反相器)
方法:将两个输入端连接在一起
"""
# 这等同于 nor_gate(input_val, input_val)
return nor_gate(input_val, input_val)
def implementation_of_or_using_nor(a, b):
"""
使用两个 NOR 门实现 OR 门
第一级:计算 (A NOR B)
第二级:将第一级的结果取反
"""
# 第一步:使用第一个 NOR 门处理原始输入 A 和 B
first_stage_output = nor_gate(a, b)
# 第二步:使用第二个 NOR 门作为反相器,恢复 OR 逻辑
# 我们需要 NOT (first_stage_output)
final_output = nor_used_as_not(first_stage_output)
return final_output
# --- 测试验证 ---
# 我们将测试真值表中的所有 4 种情况
inputs = [(0, 0), (0, 1), (1, 0), (1, 1)]
print(f"{‘A‘:<5} {'B':<5} {'Output (OR)':<10}")
print("-" * 25)
for a, b in inputs:
result = implementation_of_or_using_nor(a, b)
print(f"{a:<5} {b:<5} {result:<10}")
代码解析:
在上述代码中,你可以看到我们首先定义了一个原始的 INLINECODE213f5e61 函数。接着,我们利用“将输入短接”的技巧创建了 INLINECODE95c9c9ad。最后,在主函数中,我们将它们串联起来。当你运行这段代码时,你会发现输出结果完全符合标准 OR 门的真值表:只有当两个输入都是 0 时,输出才是 0;否则输出为 1。
真值表对比验证
为了确保万无一失,让我们从逻辑层面对比一下标准 OR 门和我们的“NOR 组合”门的真值表。
输入 B
最终输出 (NOT 中间状态)
:—:
:—:
0
0
1
1
0
1
1
1
可以看到,“最终输出”列与“标准 OR 门”列完全一致。这证明了我们的实现方案是正确的。
常见误区与最佳实践
在处理这种底层逻辑转换时,我见过许多初学者(甚至是一些资深开发者)犯下特定的错误。让我们来看看如何避免它们。
1. 混淆反相器的连接方式
在使用 NOR 门作为 NOT 门时,最大的错误是将未使用的输入端悬空。在实际硬件电路中,悬空的输入端会像天线一样捕获噪声,导致不可预测的行为。
最佳实践:
一定要将不用的输入端连接到已使用的输入端(如我们代码中所做),或者连接到确定的逻辑电平(具体取决于你是想实现 NOR 还是 NOT 逻辑)。对于 NOR 门做 NOT 门,必须将两个引脚短接。
2. 忽略传播延迟
虽然我们的模拟代码是瞬间完成的,但在真实世界的硬件中,每一个门都会造成微小的延迟(称为 Propagation Delay)。
在我们的实现中,信号通过了两级门电路。如果原始信号变化非常快,输出端会出现短暂的脉冲。虽然对于简单的 OR 门实现来说这通常不是问题,但在高频时钟电路设计中,这种累积的延迟是必须计算在内的。
3. Verilog 实现中的陷阱
如果你正在使用 Verilog 或 VHDL 进行 FPGA 设计,你可能会想直接用原语来实现这个功能。虽然这有助于理解,但通常综合工具会自动优化你的代码。
然而,如果你必须手动实例化门电路,请确保你的赋值语法正确。下面是一个使用 Verilog 数据流建模的示例,展示了如何从结构上描述这个电路:
// Verilog 数据流建模示例
module nor_to_or_impl (
input wire a,
input wire b,
output wire y
);
// 定义中间连线
wire nor_out;
// 第一个 NOR 门
nor g1 (nor_out, a, b);
// 第二个 NOR 门作为反相器
// 注意:nor 原语的实例化顺序通常是,其中 是输出
nor g2 (y, nor_out, nor_out);
/*
* 解释:
* g1 计算 ~(a | b)
* g2 接收 g1 的输出作为两个输入,计算 ~(g1_out | g1_out)
* 最终 y = ~(~(a|b)) = a | b
*/
endmodule
多输入 OR 门的实现
现实世界中的逻辑往往不止两个输入。如果我们需要实现一个 3 输入的 OR 门 ($A+B+C$),该如何仅使用 NOR 门实现呢?
逻辑是一样的:$Y = \overline{\overline{A + B + C}}$。
你需要:
- 一个 3输入 NOR 门(或者通过级联 2 输入 NOR 门构建)。它输出 $\overline{A+B+C}$。
- 将其结果连接到一个配置为反相器的 NOR 门上(将两个输入短接)。
这种模块化的思维方式是硬件描述语言(HDL)的核心。
总结与进阶思考
在这篇文章中,我们从理论推导到代码模拟,详细拆解了如何仅使用 NOR 门来实现 OR 门。这不仅是一个数学练习,更是理解数字电路设计“乐高积木”属性的关键一步。
关键要点回顾:
- 双重否定律是核心:$\overline{\overline{A}} = A$。
- NOR 门可以通过短接输入端变成 NOT 门。
- 电路结构:输入 -> NOR 门 -> (连接到 NOT 门/NOR 反相器) -> 输出。
下一步建议:
为了进一步磨练你的技能,我建议你尝试逆向思考:如何仅使用 NOR 门实现 AND 门?提示:你需要使用 De Morgan 定律 ($A \cdot B = \overline{\overline{A} + \overline{B}}$),这意味着你需要先用 NOR 门得到 NOT A 和 NOT B,然后再处理它们。
希望这篇指南能帮助你建立更坚实的逻辑电路基础。当你下次在原理图中看到这些基础门电路时,你会知道它们背后蕴含的无限可能性。