FPGA设计的是数字逻辑,在开始用HDL设计之前,需要先了解一下基本的数字逻辑设计—— 一门抽象的艺术。
通过对模拟信号进行约束,我们就会抽象出来高电平和低电平,也就是0和1,用来构建整个数字逻辑世界,这个约束就是电平规则约束,比如常见的有以下几种:
电平约束 | VDD/VCC | 0 | 1 |
CMOS | 3~8V | 0~0.3VDD | 0.7~1VDD |
TTL | 5V±5% | 0~0.7 | 2.4~5 |
LVCMOS | 3.3 | 0~0.9 | 2.7~3.3 |
LVTTL | 3.3 | 0~0.8 | 2.4~3.3 |
用晶体管实现数字世界的0和1:
接下来我们用0和1进行最基本的组合,构成一个只有两个晶体管的最简单的门电路 —— 非门:
再稍微复杂一下,我们可以用4个晶体管构成与非门、或非门、三态门:
这个时候可以进一步抽象,不再利用晶体管构建电路,而是用非门、与非门、或非门构建更复杂的门电路,比如非门、或门、异或、同或等等······
有了这些基本的门电路,我们可以用这些门电路搭建各种各样的功能电路,比如用一个异或门和一个非门构成半加器(HalfAdder):
这个时候再次进行抽象,将功能模块用一个带有输入输出表示的小方块表示,然后用这些小方块去搭建更复杂的电路,比如将半加器抽象成一个功能模块,然后用两个半加器搭建一个全加器(Adder):
全加器设计出来之后,也被抽象成了如上图所示的功能模块,我们依然可以用这个功能模块去搭建更复杂的功能,比如将四个全加器级联起来构成四位加法器:
用基本的逻辑门电路构建半加器,再用半加器构建全加器,再将1bit全加器级联构成4bit加法器,这种设计体现了数字逻辑设计中最基本的思想 —— 层次化和模块化;
常见的组合逻辑电路多路选择器、译码器(地址译码器、显示译码器、2-4译码器等等),这些电路有一个最大的特点就是输出只取决于当前输入:
上述功能电路都是组合逻辑电路,输出只取决于当前输入,那么,如何将0和1锁存起来不要变化呢?我们可以用门电路搭建一个D锁存器,当控制端C为1时,输出 = 输入,当控制端C为0时,输出保持上一状态的值不变,这样就成功的将0和1锁存起来;
时序逻辑电路,时序逻辑电路的特点是输出不仅与输入有关,还与上一状态也有关,同样的,这个用门电路搭建的电路也可以抽象成一个带有输入和输出的方块,如图所示:
对于D锁存器而言,当控制端C为高电平时,输出一直保持与输入同步,这样的功能还不能够满足应用,我们希望它可以只在某个特定时刻发生变化,上升沿或者下降沿触发,也叫边沿触发,所以,我们用两个D锁存器构成D触发器来实现这个功能:在时钟CLK上升沿将输入刷新到输出,其它时刻均保持不变:
同样的,我们可以将D触发器抽象成一个带有输入输出的小方块(注意:CLK信号带有三角形表示边沿触发),当4个小方块共享一个CLK信号时,就构成了一个4bit寄存器;当4个小方块一级一级进行级联时,就构成了一个4bit移位寄存器,在数字逻辑世界中,左移1bit和右移1bit就表示了乘法和除法;
抽象出来D锁存器和D触发器的小方块后,我们构建了寄存器,然后我们可以用寄存器来构建一些简单的时序逻辑电路,比如计数器;也可以用来构建同步时序逻辑电路,主要为状态机和流水线;设计这些越来越复杂的系统时,用原理图的方式会变得越来越繁琐,实现起来用74系列数字逻辑元件会更加复杂,幸好我们有硬件描述语言,有FPGA,可以帮我们更加方便的设计复杂数字逻辑系统,接下来的几篇会讲解用硬件描述语言verilog去描述逻辑门,描述组合逻辑功能模块,描述时序逻辑电路功能模块,然后进一步描述最重要的数字逻辑设计 —— FSM有限状态机的设计,最后,用两张图了解一下数字逻辑系统设计的巅峰之作 —— CPU(Center Peocess Uint),燃烧对数字逻辑设计的激情!