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)就是干这个的。它本质上是一种特殊的真值表,把相邻的输入组合排在一起,让你能直观地看出哪些项可以合并。
画卡诺图的步骤:
- 确定变量数:比如两个变量A、B,就画2x2的格子。三个变量A、B、C,就画2x4的格子。四个变量,画4x4。
- 标坐标:行和列分别代表不同的变量。注意,坐标的排列顺序必须是格雷码,即相邻两个数只有一位不同。比如00, 01, 11, 10。
- 填值:根据真值表,把对应的输出值(0或1)填到格子里。
- 画圈:把相邻的1圈起来。圈可以重叠,但必须圈成矩形,且大小必须是2的幂次方(1, 2, 4, 8...)。圈越大,化简后的项越简单。
- 读表达式:每个圈对应一个乘积项。看圈里哪些变量是固定的(既是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)。结果圈出来的项全是错的,仿真怎么都不对。记住,一定是格雷码顺序!
好了,这一章的内容就这些。二进制是基础,布尔代数是工具,逻辑门是积木,真值表和卡诺图是分析和化简的手段。把这些搞明白,后面学组合逻辑、时序逻辑,你会觉得顺风顺水。下一章,咱们就开始用这些知识,设计第一个真正的逻辑电路。