马上注册,看完整文章,学更多FPGA知识。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
--作者:造就狂野青春
本文为明德扬原创及录用文章,转载请注明出处!
一、 什么是组合逻辑电路?
在数字电路中,根据逻辑功能的不同,我们可以将数字电路分成两大类,一类叫做组合逻辑电路、另一类叫做时序逻辑电路。本次主要讲解组合逻辑电路的原理、应用和Verilog实现。
组合逻辑电路在逻辑功能上的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原来的状态无关。而时序逻辑电路在逻辑功能上的特点是任意时刻的输出不仅取决于当时的输入信号,而且还取决于电路原来的状态,或者说,还与以前的输入有关。
我们从图中可以看出,左侧的X是表示它的输入变量,右侧的Y是表示它的输出变量,对于这种电路,它的输出Y仅仅与当时的相应输入X有关系,而与之前的输入X是没有关系的,像这种电路,我们就称它为组合逻辑电路。
二、 如何分析组合逻辑电路?
了解了什么是组合逻辑电路之后, 我们应该如何去分析电路?如果有了电路图,我们用什么方法可以快速准确知道它所实现的逻辑功能?
上图给出了组合逻辑电路的分析方法和流程,具体每一步如何实现,不记得的同学可以复习数电基础,温习一下公式化简、卡诺图化简、真值表等内容。
三、 如何设计组合逻辑电路?
由上面我们可以知道,分析组合逻辑电路是根据给定的组合电路逻辑图,分析出其逻辑功能。那么设计组合逻辑电路是分析组合逻辑电路的逆过程,我们要根据给定的逻辑功能要求,设计出一个能实现这种功能的最简逻辑电路。
首先要根据逻辑功能建立真值表,通过真值表写出逻辑函数表达式,再进行表达式化简,再根据化简后的函数表达式画出逻辑电路图。
四、 竞争与冒险
4.1 竞争冒险的产生 当一个逻辑门的两个输入端的信号同时向相反方向变化时,从变化开始到达稳定状态所需的时间不同,称为竞争。
逻辑门因输入端的竞争而导致输出产生不应有的尖峰干扰脉冲(又称过渡干扰脉冲)的现象,称为冒险。
在实际电路中,输入信号通过每一个门电路然后输出,它总是要有传输时间的,那么这个就做门电路的传输时间或是延迟时间。在一个组合电路当中,当某一个变量经过两条以上的路径到达输出端的时候,由于每条路径上的延迟时间的不同到达终点的时间就会有先有后,就会产生竞争。
4.2 竞争冒险的消除方法
1)加封锁脉冲。在输入信号产生竞争冒险的时间内,引入一个脉冲将可能产生尖峰干扰脉冲的门封锁住。封锁脉冲应在输入信号转换前到来,转换结束后消失。 2)加选通脉冲。对输出可能产生尖峰干扰脉冲的门电路增加一个接选通信号的输入端,只有在输入信号转换完成并稳定后,才引入选通脉冲将它打开,此时才允许有输出。在转换过程中,由于没有加选通脉冲,因此,输出不会出现尖峰干扰脉冲。 3)接入滤波电容。由于尖峰干扰脉冲的宽度一般都很窄,在可能产生尖峰干扰脉冲的门电路输出端与地之间接入一个容量为几十皮法的电容就可吸收掉尖峰干扰脉冲。 4)修改逻辑设计。
五、 组合逻辑电路的应用
5.1 编码器
逻辑功能:上图是8-3编码器的真值表,有8个输入信号和3个输出信号。I7输入为1时,对应的3个输出为110,当I6输入为1时,对应的3个输出为101,以此类推直至到I0的输入为1的时候。对应的三个输出为000。
变量表达式:依照前面设计组合逻辑电路的方法流程,我们根据逻辑功能真值表写出函数表达式如下所示: 电路图:再根据表达式画出电路图:
Verilog实现:
上述case语句是多分支选择语句,是不带优先级的,要实现优先编码器,要使用elseif语句。如下图:
如果输入I7等于1,那么便会执行A=3’b000,如果I7不等于1,那么就不会执行A=3’b000,而会执行下面else if语句。如果I6同样也不等于1,那么将会依次往下执行直至判断I0等不等于1, 如果I0也不等于1,那么执行else中的A=3’b000语句。我们从这个过程中可以看出, I7的优先级最高,我们先判断的I7,依次I6,直至I0。
5.2 译码器
逻辑功能:上图是3-8译码器的真值表,有3个输入信号和8个输出信号。逻辑公牛和编码器相反。
变量表达式:依照前面设计组合逻辑电路的方法流程,我们根据逻辑功能真值表写出函数表达式如下所示:
电路图:再根据表达式画出电路图:
Verilog实现:
译码器的应用:
数码管,就是将七个发光二极管,按一定的方式排列起来,利用不同发光段的组合,显示出0-9十个十进制数,这就是应用了译码器原理。
5.3 数据选择器
8-1数据选择器
逻辑功能:上图是8-1数据选择器的真值表,我们从真值表中可以看出,当A=000时,输出I0为高电平,其余为低电平,对应高电平的开关闭合,而对应低电平的开关则仍保持断开,因此,Y的输出为D0,,当D0=0时,Y=0,当D0=1时, Y=1,下面我们可以根据真值表来写出它的函数表达式:
变量表达式:依照前面设计组合逻辑电路的方法流程,我们根据逻辑功能真值表写出函数表达式如下所示:
电路图:再根据表达式画出电路图:
Verilog实现:
5.4 数值比较器
逻辑功能:上图是一位数值比较器的真值表,我们从真值表中可以看出,有A>B,A<B,A=B三种情况。下面我们可以根据真值表来写出它的函数表达式:
变量表达式:依照前面设计组合逻辑电路的方法流程,我们根据逻辑功能真值表写出函数表达式如下所示:
电路图:再根据表达式画出电路图:
Verilog实现:
明白了数值比较器的原理,下面我们用Verilog实现4位二进制数值比较器:
5.5 加法器
逻辑功能:上图是全加器的真值表,可以根据真值表来写出它的函数表达式:
变量表达式:依照前面设计组合逻辑电路的方法流程,我们根据逻辑功能真值表写出函数表达式如下所示:
电路图:再根据表达式画出电路图:
要进行多位数相加,最简单的方法是将多个全加器进行级联:
Verilog实现:
5.6 组合逻辑的两种赋值方式
由于数字电路由与导线连接的逻辑门组成,因此任何电路都可以表示为模块和分配语句的某种组合。但是,有时这不是描述电路的最方便的方法。过程(始终以块为例)为描述电路提供了另一种语法。 对于综合硬件,两种类型的始终块是相关的:
· 组合:always@(*) · 时序:always@(posegeclk)
组合总是块等同于赋值语句,因此总有一种方法可以用两种方式表示组合电路。使用哪种选择主要是哪种语法更方便的问题。程序块内部代码的语法与外部代码不同。过程块具有更丰富的语句集(例如,if-then,case),不能包含连续的赋值*,但是还引入了许多新的非直观的错误处理方式。 (* 过程上的连续分配确实存在,但是与连续分配有些不同,并且不能综合。)
例如,分配和组合始终块描述了同一电路。两者都创建相同的组合逻辑块。每当任何输入(右侧)更改值时,两者都将重新计算输出。
assign out1 = a & b | c ^ d; always @(*) out2 = a & b | c ^ d;
对于组合always@块,请始终使用(*)的灵敏度列表。明确列出信号很容易出错(如果您错过了一个信号),并且在硬件综合中会被忽略。如果您明确指定了灵敏度列表并错过了信号,则合成的硬件仍会像指定了(*)一样运行,但是模拟不会且与硬件的行为也不匹配。(在SystemVerilog中,使用always_comb)
关于wire 和reg:assign语句的左侧必须为net类型(例如,wire),而过程赋值的左侧(在Always块中)必须为变量类型(例如reg)。这些类型(wire与reg)与合成的硬件无关,而仅仅是Verilog用作硬件仿真语言而留下的语法。
以上介绍了组合逻辑电路的原理,以及一些典型的组合逻辑电路的一些应用,并用Verilog实现这些电路,看起来很简单的电路,却是很经典很基础的,有助于我们从硬件层面去理解和设计FPGA。有机会的话,再总结时序逻辑电路的原理和典型应用。
|