2. 数字逻辑基础:二进制与布尔代数、逻辑门、真值表与卡诺图

好,咱们正式开始啃数字逻辑这块硬骨头。说实话,很多刚入门的同学觉得这章太理论,没啥意思。但我跟你说,这恰恰是后面所有设计的根基。我在项目里见过太多人,写代码一时爽,综合出来一堆bug,追根溯源都是逻辑化简没做好。所以,这一章咱们慢点来,把底子打扎实。

2.1 二进制:机器最朴实的语言

我们人类习惯用十进制,0到9,逢十进一。但数字电路里,晶体管只有两个状态:导通和截止。说白了,就是开关。所以,机器只认两种电平:高电平(通常叫‘1’)和低电平(通常叫‘0’)。这就是二进制,逢二进一。

你想想看,一个开关,要么开要么关,多简单。但就是这简单的0和1,组合起来能表示一切。从最简单的数字,到复杂的指令,再到你现在看到的这段文字,底层全是0和1的洪流。

二进制与十进制的转换,这个必须得会,就像吃饭喝水一样自然。

  • 二进制转十进制:按权展开相加。比如 1011,从右往左,每一位的权值是2的0次方、2的1次方、2的2次方、2的3次方。所以 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 = 8 + 0 + 2 + 1 = 11
  • 十进制转二进制:除2取余,倒序排列。比如11,除以2得5余1,5除以2得2余1,2除以2得1余0,1除以2得0余1。把余数从下往上写:1011

我个人习惯:在纸上多练几组数字,比如 13、25、37。练熟了,以后看波形图、看数据手册里的寄存器配置,一眼就能看出门道。

2.2 布尔代数:逻辑运算的数学工具

有了0和1,我们怎么用它们来“思考”呢?这就轮到布尔代数登场了。它是由英国数学家乔治·布尔发明的,专门用来处理逻辑关系。在数字电路里,布尔代数就是我们的数学语言。

最基本的运算就三种:与、或、非。别小看这三个,所有复杂的逻辑,包括CPU里的加法器、乘法器,都是它们组合出来的。

  • 与运算(AND):符号是 &·。口诀:全1出1,有0出0。用电路理解,就是两个开关串联,必须两个都闭合,灯才亮。
  • 或运算(OR):符号是 |+。口诀:有1出1,全0出0。用电路理解,就是两个开关并联,只要有一个闭合,灯就亮。
  • 非运算(NOT):符号是 ~ 或上面加一横。口诀:0变1,1变0。就是取反,一个开关控制一个常闭触点。

除了这三个,还有一个在CPLD里用得特别多的:异或运算(XOR)。符号是 ^。口诀:相同为0,不同为1。这个在加法器、奇偶校验里是核心。

避坑指南:我曾经在写一个状态机时,把或运算和异或运算搞混了。结果仿真怎么都对,上板子就乱跳。查了两天才发现,一个条件判断里应该用 ^ 的地方我写成了 |。所以,这几个符号一定要刻在脑子里。

2.3 逻辑门:电路里的积木块

布尔代数是理论,逻辑门就是实现。在CPLD内部,这些逻辑门就是最基本的硬件单元。我们写Verilog代码,最终综合工具会把它映射到这些门电路上。

常见的逻辑门有:

门类型 逻辑符号(IEEE) 布尔表达式 功能描述
与门 & Y = A & B 输入全1,输出1
或门 >=1 Y = A | B 输入有1,输出1
非门 1 Y = ~A 输出与输入相反
与非门 & 带圈 Y = ~(A & B) 与运算后取反
或非门 >=1 带圈 Y = ~(A | B) 或运算后取反
异或门 =1 Y = A ^ B 输入不同,输出1
同或门 = 带圈 Y = ~(A ^ B) 输入相同,输出1

嗯,这里要注意,实际CPLD里用的最多的其实是与非门或非门。为什么呢?因为用与非门可以搭出任何逻辑门,这叫“通用门”。这在芯片设计里能节省很多面积。

2.4 真值表:逻辑功能的“户口本”

真值表,就是把所有输入组合都列出来,然后写出对应的输出。它是描述逻辑功能最直观的方式,没有之一。

比如一个两输入的与门,真值表就是:

A B Y (A & B)
0 0 0
0 1 0
1 0 0
1 1 1

你看,一目了然。在项目里,我经常用真值表来跟同事对需求。比如一个译码器,功能对不对,把真值表一列,大家一看就明白,比看几百行代码快多了。

从真值表推导布尔表达式,方法很简单:找到所有输出为1的行,把输入条件用与运算组合起来,最后再用或运算连起来。这就是“最小项之和”的形式。

2.5 卡诺图:逻辑化简的“神器”

直接从真值表写出来的表达式,往往不是最简的。比如 Y = A·B + A·~B,化简后就是 Y = A。在CPLD里,逻辑越简单,占用的资源越少,速度越快,功耗也越低。所以,化简是必须的。

卡诺图(Karnaugh Map)就是干这个的。它本质上是一种特殊的真值表,把相邻的输入组合排在一起,让你能直观地看出哪些项可以合并。

画卡诺图的步骤:

  1. 确定变量数:比如两个变量A、B,就画2x2的格子。三个变量A、B、C,就画2x4的格子。四个变量,画4x4。
  2. 标坐标:行和列分别代表不同的变量。注意,坐标的排列顺序必须是格雷码,即相邻两个数只有一位不同。比如00, 01, 11, 10。
  3. 填值:根据真值表,把对应的输出值(0或1)填到格子里。
  4. 画圈:把相邻的1圈起来。圈可以重叠,但必须圈成矩形,且大小必须是2的幂次方(1, 2, 4, 8...)。圈越大,化简后的项越简单。
  5. 读表达式:每个圈对应一个乘积项。看圈里哪些变量是固定的(既是0又是1的变量被消去),把固定的变量写出来,最后用或运算连起来。

举个例子:一个三变量逻辑,真值表如下:

A B C Y
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 1
1 0 0 1
1 0 1 1
1 1 0 0
1 1 1 0

画卡诺图,圈出相邻的1。你会发现,可以圈出两个圈:一个圈包含 A=0, C=1(B被消去),另一个圈包含 A=1, B=0(C被消去)。所以化简结果是:Y = (~A & C) | (A & ~B)

我曾经犯过一个低级错误:画四变量卡诺图时,把坐标顺序写成了二进制顺序(00, 01, 10, 11)。结果圈出来的项全是错的,仿真怎么都不对。记住,一定是格雷码顺序!

好了,这一章的内容就这些。二进制是基础,布尔代数是工具,逻辑门是积木,真值表和卡诺图是分析和化简的手段。把这些搞明白,后面学组合逻辑、时序逻辑,你会觉得顺风顺水。下一章,咱们就开始用这些知识,设计第一个真正的逻辑电路。