康华光《电子技术基础 数字部分》(第六版)书中关于时序逻辑的介绍十分详尽,仅在原书的基础上增加一部分注释,并省去一部分器件特性相关的内容。
目录
1.锁存器
1.1基本SR锁存器
1.2用与非门构成的基本SR锁存器
1.3时序电路的描述方法(以或非门构成的RS锁存器为例)
1.3.1特性表
1.3.2特性方程
1.3.3状态图
1.3.4波形图
1.4门控SR锁存器
1.5 D锁存器
1.5.1CMOS传输门
1.5.2传输门控D锁存器
1.5.3逻辑门控D锁存器
1.6空翻现象
2.触发器
2.1主从D触发器
2.1.1主从D触发器的电路结构和工作原理
2.1.2 D锁存器与D触发器的比较
2.1.3利用Verilog描述触发器
3.寄存器
三态输出门
3.1寄存器的原理
3.2移位寄存器
3.2.1单向移位寄存器
3.2.2多功能双向移位寄存器
3.2.3利用Verilog描述移位寄存器
4.计数器
4.1 4位同步二进制计数器
4.2基本环形计数器
4.3计数器的应用
4.4利用Verilog描述计数器
组合逻辑电路是没有记忆的,也就是说在任何时刻产生的输出信号都仅仅取决于该时刻电路的输入信号,而与它以前的输入信号是无关的。而有的时候,外面需要电路具有一定的记忆功能,比如自动售货机,当需要买一瓶水,需要三块钱,当你依次投入三个硬币时,之后当三个硬币都投入之后,自动售货机才会掉出你想要的东西,这样的功能就是依靠内部的时序电路实现的。时序电路与组合逻辑电路相反,它具有记忆功能,它在任何时刻的输出,不仅与该时刻的输入信号有关,而且还与该时刻以前的输入信号有关。时序逻辑电路的示意图如下图所示:
根据上图可以知道,一个完整的时序电路,由两部分构成,分别是组合逻辑电路和时序逻辑电路(用来保存输入信息的存储电路)。 常用的存储电路有两类,一类是锁存器,而另一种是触发器。它们两者所采用的电路结构形式不同,信号的触发方式也不同,其中,采用电平触发方式的叫做锁存器,而采用脉冲边沿触发方式的叫做触发器。
在详细介绍锁存器和触发器之前,先简要介绍一下基本双稳态电路。
将两个非门和接成如下图所示的交叉耦合形式,则构成最基本的双稳态电流。
由上述基本双稳态电路的逻辑关系可知,若,经非门反相,则。反馈到输入端,又保证了。由于两个非门首尾相接的逻辑锁定,因而电路能自行保持在、的状态,形成第一种稳定状态。同理,若,则,形成第二种稳定状态。在两种稳定状态中,输出端和总是逻辑互补的。可以定义为整个电路的0状态,则是1状态。电路进入其中任意一种逻辑状态都能长期保持下去,并可以通过端电平检测出来,因此,它具有存储1位二进制数据的功能。
像上述图示电路一样,具有0、1两种逻辑状态,一旦进入其中一种状态,就能长期保持不变的单元电路,称为双稳态存储电路,简称双稳态电路。但是,上述双稳态电路的功能极不完备。在接通电源后,它可能随机进入0状态或1状态,因为没有控制机构,所以也无法在运行中改变和控制它的状态,从而不能作为存储电路使用。但,基本在双稳态电路是锁存器和触发器等存储单元的基础。
锁存器是一种对脉冲电平敏感的双稳态电路,它具有0和1两个稳定状态,一旦状态被确定,就能自行保持,直到有外部特定输入脉冲电平作用在电路一定位置时,才有可能改变状态。这种特性可以用于置入和存储1位二进制数据。
将基本双稳态电路中的非门换成或非门,则构成下图所示的基本SR锁存器,它是一种具有最简单控制功能的双稳态电路。
图中,和是两个输入端, 和是两个输出端。定义、为整个锁存器的0状态;、则是锁存器的1状态。下面根据、的四种输入状态分析SR锁存器的工作原理。
(1)
根据逻辑电路列出,,。显然,、两种信号对输出和不起作用,电路状态保持不变,功能与前述的基本双稳态电路一致,因此可存储1位二进制数据。
(2)、
对于或非门而言,不会影响的输出状态;而作用于则不然,所以必须首先确定输出端的状态(虽然一直强调电路是并行的,但是由于的输出不受控制,但是可以决定的输出状态,即,进而决定,也就是说,逻辑关系仍然存在主次关系)。根据电路可得:。该信号再反馈到输入端,得到。根据定义,锁存器这时的状态为0。
如果从电路的动态变化分析,假设上述SR锁存器此时的状态为1,即、,在端出现逻辑1电平瞬间,将使端输出电压下降并作用于的的输入端,随即引发端电压上升。一旦和端均跨越逻辑阈值电平,便迅速转换为、,电路状态由1翻转到0;反之,如果此前电路状态为0,即、,则的出现不改变其状态。
综上所述,、将使锁存器置0,因此将端称为复位(或置0)输入端。当信号消失(即回到0),电路进入前述(1)的状态,使锁存器的0状态得以保持。
(3)、
由于电路是对称的,因而此时的电路状况与状态(2)完全相反,、将首先使,继而,锁存器置1。端称为置位(或置1)输入端。当信号消失,同样可使锁存器的1状态得以保持。
(4)
无论和原来是什么状态,将强制,,锁存器处在既非1,又非0的非定义状态。若和同时回到0,则无法确定孙存其将落入1状态还是0状态(先变为1的话,变为0,锁存器进入1状态;先变为1的话,变为0,锁存器进入0状态。因此,属于不确定状态)。由于电路存在制造误差,、的延迟时间总是有微小差别,若的延迟时间稍短,在和同时跳变到0时,端会抢先跳变为1,迫使;反之,若的延迟时间稍短,锁存器则进入0状态。所以,实际的电路在这种情况下总是倒向电路设计者无法预知的一个固定状态。为保证锁存器始终工作于定义状态,输入信号应遵守的约束条件,也就是说不允许。
根据上述分析得到基本SR锁存器的功能表如下图所示(4行内容分别对应前述4种状态):
下图为基本SR锁存器的逻辑符号:
和分别为置位端和复位端,和为互补的两个输出端,其中输出锁存器的非状态,所以用小圆圈示之。这样,不通过逻辑门电路,仅从抽象的逻辑符号也可以理解基本SR锁存器各输入、输出信号之间的逻辑关系。
基本SR锁存器的数据保持、置0和置1功能,是一个可实际应用的存储单元的逻辑功能,基本SR锁存器的典型工作波形如下图所示:
除了可以用或非门构成基本SR锁存器,还可以用与非门构成基本SR锁存器,其逻辑原理图和逻辑符号如下所示:
由上图分析可以得到、 为不同组合输入状态时锁存器的状态(非表示低电平有效,也就是说,当或为0时,表示有激励信号;为1时,表示无激励信号)。用与非门构成的基本SR锁存器的功能表如下所示:
观察上表可知,与非门构成的基本SR锁存器工作时应当受到的约束条件,即同样应遵守的约束条件。由于功能与前述或非门构成的基本SR锁存器类似,这里不再赘述。
特性表是反应输入变量和原状态以及新状态关系的一种真值表,也被称为状态转换真值表。原状态,用表示,新状态用表示。RS锁存器的特性表如下表所示:
根据特性表可以较清楚地看出RS锁存器的逻辑功能,比如当时,也就是说,两个输入端均无激励信号,,即锁存器的原状态和新状态保持不变。
特征方程是锁存器新状态的逻辑函数表达式。根据RS锁存器的特性表写出它的特性方程(将输出等于1的项提出后组成一个与或式),得到其函数式:,另有两个无关项,根据卡诺图化简得:。
状态图可以更加形象地表示是时序逻辑电路的功能。SR锁存器的状态图如下图所示:
从RS锁存器的状态图可以看出,,该状态图是由两个圆圈和四个箭头组成,两个圆圈中的0和1表示的是RS 锁存器的两个状态(也就是或非门构成的SR锁存器的输出值),而四个箭头表示的是四个转换过程,箭头的末端是原状态 ,箭头的前端是新状态(箭头由原状态指向新状态,即),在箭头旁边的和是状态改变的条件, X代表任意状态。由此,我们就可以根据RS 锁存器的状态图来看出RS 锁存器的状态是如何变化的。
假设SR锁存器的初始状态为1,其、端输入和输出、波形如下图所示。
虽然图中1、2两处输入信号越出了SR锁存器的约束条件,出现了使得的情况,但是,只要和的1电平不同时撤销,此后的输出状态仍让是可以确定的,如上图3、4处所示。而在5处,由于和的1电平同时撤销,所以锁存器以后的状态将无法确定,从而失去对它的控制。
实际工作中,希望有一个控制信号控制锁存器状态的转换,因此在SR锁存器的基础上增加一个控制端,只有控制端的信号变为有效电平后,SR锁存器才能按照输入的置1 或置0 信号改变相应的状态,称之为门控SR锁存器。通过控制E端电平,可以实现多个锁存器同步的数据锁存。下图是门控SR锁存器的逻辑电路及其对应逻辑符号:
根据其逻辑电路可知,当时,,、 端的逻辑状态不会影响到锁存器的状态;当时,、 端的信号被传送到基本SR锁存器的输入端,从而确定和端的状态,其功能表与用或非门构成的基本SR锁存器的功能表一致。若时输入信号,则,锁存器将处于非定义的逻辑状态。当恢复到0时,由于、同时回到0,将不能确定锁存器的状态。因此,应用这种锁存器必须更严格地遵守地约束条件。由于约束条件造成地应用限制,因而很少有独立的门控SR锁存器产品。但是,在许多大、中规模集成电路种时常应用这种锁存器,或用它构成触发器或存储器。所以,SR锁存器仍是重要的基本逻辑单元。
门控SR锁存器的逻辑符号中,方框内用和、表达内部逻辑之间的关联关系。表示这种关联属于控制类型,其后缀用序号“1”表示该输入的逻辑状态对所有以“1”作用前缀的输出起控制作用。这里由于置位和复位输入均受控制,故和之前分别以表示序号“1”作为前缀。
D锁存器就是能将输入端的单路数据D存入到锁存器中的电路。
不同于SR锁存器,D锁存器在工作中不存在非定义状态,因而得到广泛应用。目前,CMOS集成电路主要采用传输门控D锁存器和逻辑门控D锁存器两种电路结构形式,特别是前者电路结构简单,在芯片中占用面积小而更受青睐。
CMOS传输门由一个P沟道和一个N沟道增强型MOS管并联而成,传输门的电路结构及逻辑符号如下所示:
和的源极和漏极可以互换,因而传输门的输入输出端可以互换使用,即为双向器件。 工作特性为:时,TG断开;时,TG导通。
传输门控D锁存器是在基本双稳态电路中插入两个传输门和构成的,下图是其逻辑电路及其对应逻辑符号:
D锁存器有两个输入端:使能端E和数据输入端D。当时,,导通,断开,如下图所示:
输入数据D经、两个非门,使,,这时输出端跟随输入信号D的变化,因此又被称作透明锁存器。当时,,,断开,导通,如下图所示:
这种情况下与基本双稳态电路一致。由于、输入端存在的分布电容对逻辑电平有短暂的保持作用,在两个传输门状态转换瞬间并不影响电路的输出状态。之后,电路被锁定在信号由1变0前瞬间信号所确定的状态,在的条件下可保持锁存器状态不变,使1位二进制数据得以存储。
D锁存器的特性表如下表所示:
D锁存器的功能表如下表所示:
D锁存器的状态图如下图所示:
从状态图可以看出,当状态时,输出将保持0状态;当输入时,输出将从0变为1。以下是D触发器的波形图:
逻辑门控D锁存器是由门控SR锁存器在输入端和之间连接一个非门得到的,从而保证了的约束条件,消除了可能出现的非定义状态。其逻辑功能与传输门控D锁存器完全相同,因此逻辑符号也相同。逻辑门控D锁存器的逻辑电路如下所示:
空翻现象指当控制信号有效时,激励信号的任何变化,都将直接引起锁存器输出状态的改变,若输入信号若发生多次变化,输出状态也跟着发生多次变化(由于干扰导致输入电平突变引起锁存器逻辑值发生变化),这一现象就被称为锁存器的空翻。下图是D锁存器发生空翻现象的波形图:
从波形图中可以看出,蓝色虚线内,由于控制信号为高电平, ,可以得出。蓝色虚线和黄色虚线之间,由于,那么;同理,两条黄色虚线之间,,。空翻是一种有害的现象,它使得时序电路不能按时钟节拍工作,造成系统的误动作。我们前面学习的锁存器都存在空翻现象,而引起空翻现象是由锁存器的结构导致的,为了能够解决锁存器的空翻现象,人们便在锁存器的基础上进行了修改,因此人们便设计出了触发器,触发器按照逻辑功能的不同可分为RS 触发器、D 触发器、JK 触发器、T 触发器。
由于在FPGA 设计中我们更多的是利用D 触发器来设计电路,基本上每一个时序电路模块都能看到D 触发器的身影,所以下面将重点放在D 触发器上,其他的触发器我们这里就不再进行详细讲解,可参考《电子技术基础 数字部分》(第六版)。
触发器(Flip-Flop)也是数字电路中的一种具有记忆功能地逻辑器件。触发器是一种对脉冲边沿敏感的双稳态电路,它只能在触发脉冲的上升沿(或下降沿)瞬间改变状态,在数字电路中可以记录数字信号“0”和“1”。D锁存器在使能信号为逻辑1期间更新状态。在下图所示的波形中以加粗部分表示这个敏感时期。
在此期间,它的输出会随输入信号变化。而很多时序电路要求存储电路只对时钟信号的上升沿或下降沿敏感,而在其他时刻保持状态不变,如移位寄存器和计数器。这种对时钟脉冲边沿敏感的状态更新称为触发,具有触发工作特性的存储单元称为触发器。电路结构不同的触发器对时钟脉冲的敏感边沿可能不同,分为上升沿触发和下降沿触发。以(Clock Pulse)命名上升沿触发的时钟信号,触发边沿如下图波形中的箭头所示:
以命名下降沿触发的时钟信号,触发边沿如下图波形中的箭头所示:
在Verilog HDL中,对脉冲电平敏感的锁存器和脉冲边沿的触发器的描述语句是不同的。
目前应用的触发器主要有三种电路结构:主从触发器、维持阻塞触发器和利用传输延迟的触发器。由于CMOS主从结构的D触发器在芯片上占用的面积最小,逻辑设计方法比较简单,在大规模CMOS集成电路,特别是可编程逻辑器件(如CPLD、FPGA)和专用集成电路(ASIC)中得到普遍应用,因而在目前的工程实践中更多地应用到D触发器。
下图将两个CMOS传输门控D触发器级联构成典型的CMOS主从D触发器。图中左边的锁存器称为主锁存器,右边的称为从锁存器。主锁存器与从锁存器的使能信号相位相反,利用两个锁存器的交互锁存,则可实现存储数据和输入信号之间的隔离。
主从D触发器的工作过程分为以下两个节拍:
(1)当时钟信号时,,,使得导通, 断开,端输入信号进入主锁存器,这时跟随端的状态变化,即。例如,时,经传送到的输入端,使,。同时由于断开,切断了从锁存器与主锁存器之间的连接,而导通,使的输入端和的输出端经过联通,构成最基本的双稳态电路,使从锁存器维持原来的状态,即触发器的输出状态不变。
(2)当CP由0跳变为1后,,,使得断开,从而切断端与主锁存器的联系,同时导通,将的输入端和的输出端连通,主锁存器锁存跳变前端的数据(主锁存器维持原来的状态)。这时,导通,断开,端信号传送到端。若,,经传送到的输入端,于是,。
在一个变化周期内,触发器的输出状态只可能改变一次,克服了锁存器存在的空翻现象。
可见,从锁存器在工作中是跟随主锁存其的状态变化的,触发器因之冠名为主从(Master-Slave)。它的状态转换发生在CP信号上升沿到来后的状态,输出信号由信号上升沿到达前瞬间的数据信号所决定,从功能上考虑为触发器。如果以表示上升沿到达后触发器的状态,则触发器的特性可以用下式来表达:。
(1)D触发器的特性表
已输入信号和触发器的现态为变量,以次态为函数,描述它们之间逻辑关系的真值表称为触发器的特性表。D触发器的特性表如下图所示,表中对触发器的输入信号和现态的每种组合都列出了相应的次态。
(2)D触发器的特性方程
触发器的逻辑功能也可以用逻辑表达式来描述,称为触发器的特性方程。根据D触发器的特性表可以列出D触发器的特性方程:
(3)D触发器的状态图
D触发器的状态图由D触发器的特性表导出。圆圈内为触发器的状态,分别标示为0和1的两个圆圈代表了触发器的两个状态;4跟带箭头的方向线表示状态转换的方向,分别对应特性表中的四行,方向线的起点为触发器的现态,箭头指向相应的次态;方向线旁边标出了状态转换的条件,即输入信号的逻辑值。D触发器的状态图如下图:
由特性表、特征方程或状态图均可以看出,当时,触发器的下一状态将被置0() ;当时,将被置1()。在时钟脉冲的两个触发沿之间,触发器状态保持不变,即存储1位二进制数据。
D锁存器与D触发器的逻辑功能其实是相同的,只不过它们的触发方式有所不同。下图是D锁存器与D触发器的波形图:
从上面的波形图可以看出, D触发器是在时钟信号为0时,才会接收输入信号D的值,并将这个值锁存起来,当控制信号CLK 变为1 时,输出信号Q 才会被改变。那么D 触发器,其实就是在CLK 这个时钟信号由0 变为1 的这个边沿进行触发的,通常我们就将这种触发方式称为边沿触发,通过这种边沿触发方式的D 触发器我们也将它称为边沿D 触发器。
D 锁存器的触发方式是电平触发,和我们刚刚讲的边沿触发是有所不同的。这种不同是由于锁存器和触发器的电路结构不同,而造成的。这里需要注意的是,由于D 锁存器的功能和D 触发器的功能是一样的,所以在编写代码时很容易把D 锁存器当成D 触发器来使用,这种情况应该是极力避免的。
1 module Digital_Data_Flip_Flop
2 (
3 CLK_50M,RST_N,D,Q
4 );
5
6 input CLK_50M;
7 input RST_N;
8 input D;
9 output reg Q; //可以分开写output Q;reg Q;也可以合并在一起
10
11 always @ (posedge CLK_50M or negedge RST_N)
12 begin
13 if(!RST_N)
14 Q <= 1'b0;
15 else
16 Q <= D;
17 end
18
19 endmodule
相较于之前描述组合逻辑电路的Veriliog代码,在长度上并没有什么差别,但是该代码所描述的功能与之前代码所描述的功能是有很大区别的,之前我们所描述的功能是没有时钟信号的,即之前描述的都是组合逻辑电路,而现在描述的是一个货真价实的时序电路。以下是对D触发器Verilog代码的分析:
该代码的第11 行至第17 行,是本程序中最核心的,也是用法相对比较多的always 模块。always 模块敏感表可以为电平、沿信号(上升沿)posedge、(下降沿)negedge。前面已经将always 模块用在组合逻辑电路中,其基本代码结构如下所示:
1 always @ (*) //always @ (A,B) 也可以always @ (A or B)
2 begin
3 //具体逻辑
4 end
always 后若有沿信号(上升沿posedge,下降沿negedge)声明,则多为时序逻辑,其基本代码结构如下所示:
1 always @ (posedge CLK_50M) //单个沿触发的时序逻辑
2 begin
3 //具体逻辑
4 end
5
6 always @ (posedge CLK_50M or negedge RST_N) //多个沿触发的时序逻辑
7 begin
8 //具体逻辑
9 end
组合逻辑电路中always@(A,B)意义为:@为事件等待语句,意思是一直等待A和B两个敏感变量,不管A和B是从高变低,还是从低变高,都将会执行always下面的begin...end中的语句。如果A和B都没有变化,那么always 也将不往下执行,将一直循环等待。新标准下也可以写作:always@(*),解释如下:always @ (*)是个组合逻辑电路的描述方式;是为了防止在设计时考虑不周全带来一些操作失误,所以敏感表用*(表示全部的敏感变量,这里表示A 和B),只要有任何输入信号变化,其输出立即发生变化。
时序逻辑电路中always @ (posedge CLK_50M or negedge RST_N):@也同样是事件等待语句,只是这里一直等待的是CLK_50M 和RST_N 二个敏感变量的上升沿和下降沿的变化,如果有一个CLK_50M 的上升沿到来,那么便会执行always下面的begin…end 中的语句。同样的如果有一个RST_N 的下降沿到来,也同样会执行always下面的begin……end 中的语句。如果两个信号都没有到来,那么将不会执行begin……end 中的语句,一直等待信号的到来。
注:时序电路中的赋值是”<=“(非阻塞赋值);而组合逻辑电路中的赋值是”=“(阻塞赋值)
接下来再来看always模块中的代码,首先看到的是第13 行的if 语句,该语句判断复位信号是否有效,从变量命名规则中我们可以看出RST_N是一个低电平有效的复位信号,也就是说,当RST_N=0时,if为真,Q<=1’b0 会被执行,D触发器将会被复位输出0;当RST_N=1 时,if为假,就要执行else 中的Q<=D 这条语句,D触发器将会正常工作。
由前面可知,能够存储一位二进制码的时序电路叫做触发器,寄存器就是能够存储多位二进制数码的时序电路。
三态输出门除了具有一般门电路的两种状态,即输出高、低电平外,还具有高输出阻抗的第三状态,称为高阻态,又称为禁止态。下图是三态输出缓冲电路及其逻辑符号,其中是输入端,位输出端,是控制信号输入端,也成为使能端。
当使能端时,如果,则,,使得导通,同时截至,输出端;如果,则,,使得截至,同时导通,输出端。
当使能端时,不论A的取值如何,都使得、,则和均截至,电路的输出既不是低电平,又不是高电平,而是开路,这就是第三种高阻工作状态。
因此,当为有效的高电平时,电路处于正常逻辑工作状态,;而当为低电平时,电路处于高阻状态。下图是三态输出门电路的真值表。
三态输出们电路主要用于总线传输,如计算机或微处理器系统,其连接形式如下所示:
任意时刻只有一个门电路的使能端为1,该门电路的信号被传送到总线上,而其他三态输出电路处于高阻状态。这样就可以按一定顺序将各个门电路的输出信号分时送到总线上。
寄存器是数字系统中用来存储二进制数据的逻辑器件。1个触发器可存储1位二进制数据,存储N位二进制数据的寄存器需要用N个触发器组成。
由8个触发器构成的8位寄存器的逻辑图如下图所示:
图中,~是8位数据输入端,在脉冲上升沿作用下,~端的数据同时存入相应的触发器,直到下一个时钟信号的上升沿到来之前,无论怎么改变输入信号的值,输出信号的值也不会改变,是一种极为简单的同步时序电路。当输出使能信号时,触发器存储的数据通过三态门输出端~并行输出。下图是典型的中规模继承8位寄存器74HC/HCT374的功能表(和的下标表示第位触发器,和表示脉冲上升沿之前瞬间的电平)。
移位寄存器有可以分为单向移位寄存器和双向移位寄存器,单向移位寄存器指的就是右移位寄存器和左移位寄存器,而双向移位寄存器就是既能向左也能向右移位。
如果将若干个触发器级联成下图所示电路,则构成基本的移位寄存器。这里以右移位寄存器为例,如下图所示:
上图是一个4位移位寄存器,串行二进制数据从输入端输入,左边触发器的输出作为右邻触发器的数据输入。若将串行数码从高位()至低位()按时钟间隔依次送到端,经过第一个时钟脉冲后,。由于跟随后面的是,因此经过第二个时钟脉冲后,触发器的状态移入触发器,而转变为新的状态,即,。以此类推,该寄存器的功能如下表所示:
由表可知,输入数码依次由左边触发器移到右侧触发器。经过4个时钟脉冲后,4个触发器的输出状态与输入数码相对应。下图是数码1101(即,,,)在移位寄存器中移位的波形,经过4个时钟脉冲后,1101出现在触发器的输出端。这样,就将串行输入数据转换为并行输出。
这里还画出了第5到第8个时钟脉冲作用下,输入数码在寄存器中移位的波形。可上图可知,在第8个时钟脉冲后,脉冲已从串行数据输出端(即端)全部移出寄存器。也就是说,随着时钟信号的推移,从输出端可得到1101的串行输出。
从上述操作可知,移位寄存器中能用脉冲边沿敏感的触发器,而不能用电平敏感的锁存器来构成,因为在时钟脉冲高电平期间,锁存器输出跟随输入变化的特性将使移位操作失去控制。显然,移位寄存器属于同步时序电路。
有时需要对移位寄存器的数据流向加以控制,实现数据的双向移动,其中一个方向称为右移,另一个方向称为左移,这种移位寄存器称为双向移位寄存器。规定逻辑图中最低有效位(LSB)到最高有效位(MSB)的电路排列顺序位从上到下,从左到右。因此,定义移位寄存器中的数据从低位触发器移向高位为右移,反之为左移。这一点与通常计算机程序中的规定相反,后者从自然二进制数的排列考虑,将数据移向高位定义为左移,反之为右移。
为了扩展逻辑功能和增加使用的灵活性,在双向移位基础上,还可以增加并行输入、并行输出等功能,构成多功能移位寄存器,其工作模式的简化示意图如下所示:
1 module Digital_Shift_Reg
2 (
3 CLK_50M,RST_N,DATA_EN,DATA_IN,DATA_OUT
4 );
5
6 input CLK_50M;
7 input RST_N;
8 input DATA_EN;
9 input DATA_IN;
10 output DATA_OUT;
11
12 reg [3:0] DATA_OUT;
13 reg [3:0] DATA_OUT_N;
14
15 //时序电路
16 always @ (posedge CLK_50M or negedge RST_N)
17 begin
18 if(!RST_N)
19 DATA_OUT <= 4'b0;
20 else
21 DATA_OUT <= DATA_OUT_N;
22 end
23
24 //组合电路
25 always @ (*)
26 begin
27 if(DATA_EN)
28 DATA_OUT_N = {DATA_OUT[2:0] , DATA_IN};
29 else
30 DATA_OUT_N = DATA_OUT;
31 end
32
33 endmodule
上述代码是一个典型的组合逻辑电路和时序逻辑电路分开写的风格。。模块名、端口声明、数据类型定义三部分这里不再赘述。代码的16到22行代码主要完成的功能是一个4位的寄存器(即4位的D触发器),其中RST_N是一个低电平有效的复位信号;第25行到31行的代码主要完成的功能是判断DATA_EN使能位,并进行移位操作。这里详细解释一下第28行中的“{”和“}”,这里是拼接运算符。举例说明,A=2'b10,B=4'1111,则{A,B}=6'b101111。接下来详细讲解一下移位操作是如何实现的,假设DATA_OUT为0000,DATA_IN为1,DATA_EN为1,当DATA_EN为1时,程序会自动运行第28行,由于DATA_OUT=4'b0000,所以DATA_OUT的低三位为3'b000,又因为DATA_IN=1'b1,所以DATA_OUT_N={3'b000,1'b1}=4'b0001;当程序运行第二次的时候,DATA_OUT为0001,此时假设DATA_IN为0,当DATA_IN为1时,DATA_OUT_N={3'b001,1'b0}=4'b0010。依次类推,这就是移位寄存器实现的过程。
有时要求在移位过程中,数据仍保持在寄存器中不丢失。此时,只要将移位寄存器最高位的输出接至最低位的输入,或将最低位的输出接至最高位的输出,便可实现这个功能,称为环形移位寄存器。亦可作计数器使用,称为环形计数器。
计数器是最常用的时序电路之一,它们不仅可用于对脉冲进行计数,还可用于分频、定时、产生节拍脉冲以及其他时序信号。计算器的种类不胜枚举,按触发器动作分类,可分为同步计数器和异步计数器;按编码数值增减分类,可分为递增计数器、递减计数器和可逆计数器;按编码分类,又可分为二进制计数器、BCD计数器、循环码计数器等。计数器运行时,从某一状态开始依次遍历不重复的各个状态后完成一次循环,所经过的转台总数称为计数器的模(Module),并用M表示。若某个计数器在个状态下循环计数,通常则称之为模计数器,或计数器。例如一个在60个不同状态中循环转换的计数器,就可称为模60,或计数器。有时也把模计数器称为进制计数器。这里以4位同步二进制计数器和基本环形计数器为例。
由四位D触发器组成的计数器电路图如下所示:
上述计数器是由4个边沿D触发器、、和,再加上三个异或门和两个与门构成的。电路计数的过程详述如下:
假设电路的初始状态为000(即初始输出),接下来看四个触发器的输入信号分别是什么,先看,的输入信号,是由反馈回来的,已知此时,因此,这个1反馈给输入信号,此时的输入信号就是1;接下来看,的输入信号是和经过一个异或门之后得到的,已知此时,,因此的输入信号为0;接着看,的输入信号信号是由和经过一个与或门之后的输出与异或得到的,因此的输出为0;最后看,的输入是由、和相与之后的输出与异或得到的,因此的输出为0。
分析完、、和此时的输出值后,就可以根据D触发器的逻辑规律知道下一刻电路的输出值了,当端口出现一个上升沿,即由0变1,四个边沿触发器同时触发,当这个时钟信号的上升沿到来时,触发器的输入值将会被锁存,下一刻4个触发器的输出为,,,(为二进制最低位,为二进制最高位)。因此现在计数器输出的值为二进制数0001,也就是十进制的1。依此类推,当第二个时钟信号的上升沿到来时,计数器会输出二进制数0010,也就是十进制的2。每当电路多来一个时钟上升沿,计数器就会加1。当电路计数到第十六个脉冲时,电路状态将由1111变为0000,完成一个循环周期,因此该电路也称为模16计数器。所谓同步是指该电路中的四个边沿触发器共用一个时钟脉冲,当时钟上升沿到来时,它们能同时触发,这就叫同步。所谓异步就是这些触发器不是共用同一个时钟脉冲,且触发不是同时发生的。
模16加法计数器的特性表如下所示:
下图是模16加法计数器的状态图。
将前述的移位寄存器的()与相连,则构成环形计数器,如下图所示。
若事先通过端施加低电平脉冲,在4个触发器内置入数据,那么环形计数器在脉冲作用下,将会有如下所示的4个状态,于是,电路成为模4计数器。
下图是在4个脉冲作用下的波形。
可以看出,这种计数器不必译码就能直接输出4个状态的译码信号,亦不存在普通译码电路输出易出现的竞争-冒险现象。
了解完计数器的工作原理,接下来就是计数器的应用,首先想到的就是秒表,秒表就是一个典型的计数器。这里暂不考虑秒表的暂停和计时功能,主要了解一下秒表的基本工作原理。
一个两位数的秒表可以从0一直累加到59,然后再返回0循环进行累加,前述的是一个模16计数器,这里从0到59循环累加,因此是一个模60计数器。模60计数器的电路结构相对模16是更加复杂的,如果直接选择用门电路进行搭建是十分麻烦的,因此这里不直接用模60计数器来实现,而是选择用模6计数器加上模10计数器的方法实现,原因在于一个两位的秒表是分各位和十位的,个位显示0-9这十个数,十位显示0-5这留个数,可以将十位和各位分开来进行技术。下图中的计数器开始计数,它的个位数字每隔一秒变化一次,变化到9的时候,它的下一刻将会归零,然后重新计数;而十位的数字每隔10秒变化一次,变化到5的时候,它的下一刻也将会归0,然后重新计数。这就是两位数秒表的实现方法,下图是秒表的电路示意图。
从电路示意图中可以看出,先将个位的数码管和十位的数码管分别与模10 和模6计数器对应,然后,将这两个计数器的输出信号引出,连接到相应的译码器上,再通过译码器译码,将最终的数字显示在数码管上。这就是一个两位数秒表的电路结构了,这里要注意的是,图中的两个计数器,它们的时钟信号不是共用的,模10 计数器的时钟端,信号的上升沿是需要间隔1 秒来一次,而模6 计数器的时钟端,信号的上升沿是需要间隔10 秒来一次的,具体怎么产生需要的时钟信号,这里就不再赘述。
1 module Digital_Counter
2 (
3 CLK_50M,RST_N
4 );
5
6 input CLK_50M;
7 input RST_N;
8
9 reg [3:0] time_cnt;
10 reg [3:0] time_cnt_n;
11
12 //时序电路
13 always @ (posedge CLK_50M or negedge RST_N)
14 begin
15 if(!RST_N)
16 time_cnt <= 4'b0;
17 else
18 time_cnt <= time_cnt_n;
19 end
20
21 //组合电路
22 always @ (*)
23 begin
24 if(time_cnt == 4'hf)
25 time_cnt_n = 4'b0;
26 else
27 time_cnt_n = time_cnt + 1'b1;
28 end
29
30 endmodule
References:
1.康华光《 电子技术基础 数字部分》(第六版);
2.锆石科技《HELLO FPGA数字部分》