verilog语法实例学习(7)
常用的时序电路介绍
组合电路:这类电路的输出信号值仅却决于输入端信号值。
时序电路:时序电路的输出值不仅取决于当前的输入值,还取决于电路的历史状态,所以时序逻辑电路中包含保存逻辑信号值的存储元件,存储元件中的值代表了当前电路的状态。当电路的的输入信号值发生改变时,新输入的信号值可能使电路保持同样的状态,也可能使电路进入另一种状态,随着时间推移,输入信号值的变化导致电路状态发生一系列的改变,这种电路称为时序电路。
同步时序电路:大部分情况下,由一个时钟信号控制的时序电路称为同步时序电路。在同步时序电路中,状态变量是同一时钟控制的触发器表征,这个时钟是由脉冲组成的周期信号,状态变化可发生在时钟脉冲的上升沿或者下降沿。
异步时序电路:没有时钟控制信号的时序电路称为异步时序电路。
组合逻辑电路既能用连续赋值语句描述,也能用过程赋值语句描述,但时序电路只能用过程赋值语句描述。下面是一些时序电路的典型例子。
同步时序电路的一般形式
时序电路由组合逻辑以及一个或多个触发器实现。一般的架构如下图所示:W为输入,Z为输出,触发器中存储的状态为Q。在时钟信号的控制下,触发器通过加在其输入端的组合逻辑输入,使得电路从一个状态变成另一个状态。
基本锁存器
基本锁存器通常如下图所示,由两个或非门用交叉耦合的方式相连。它的输入包括复位端R(reset)和置位端S(set),输出为Qa和Qb,Qa和Qb在这儿互为反相。
假设Qa=1,Qb=0,当R=0,S=0时,可知Qa=1,Qb=0保持不变。 //锁存器保持原态
假设Qa=0,Qb=1,当R=0,S=0时,可知Qa=0,Qb=1保持不变。 //锁存器保持原态
当R=1,S=0时,Qa=0,Qb=1 //锁存器复位
当R=0,S=1时,Qa=1,Qb=0 //锁存器置位
当R=1,S=1时,Qa=0,Qb=0
所以基本锁存器的特性表(不是真值表,输出不仅仅和输入相关)为:
S | R | Qa | Qb | 备注 |
0 | 0 | 0/1 | 1/0 | 保持不变 |
0 | 1 | 0 | 1 | |
1 | 0 | 1 | 0 | |
1 | 1 | 0 | 0 |
我们来看基本锁存器震荡的情况:在t0时刻,R=1,S=1,所以Qa,Qb都为0,在t1时刻,R=0,S=0,Qa和Qb立即变为1,随后又变为0,反复震荡,如果两个或非门的延迟严格相等,则这种震荡会反复持续下去,但实际情况下,延迟总有差别,所以最终会停留在两个状态中的某一个,但不能确定时哪一个,这种不确定性在波形中用虚线标出。通常来说,只要电路中包含一条或多条反馈电路,其状态便于逻辑门的传输延迟有关,设计这类电路必须十分小心。
门控SR锁存器
对基本锁存器进行一点改动,加入时钟信号(Clk)作为控制信号,形成如下图所示的锁存器称为门控SR锁存器。
当Clk为1时,该电路功能和基本锁存器一样,在Clk为0时,无论S,R信号为何值,输出状态保持不变。
若S=R=1,时钟信号Clk从1变为0时候,将会引起震荡,所以我们要尽量避免S,R都为1的状态。
因为S,R不能同时为1,所以输出端我们用Q和~Q表示
Clk | S | R | Q(t+1) | 备注 |
0 | x | x | Q(t) | 保持不变 |
1 | 0 | 0 | Q(t) | 保持不变 |
1 | 0 | 1 | 0 | |
1 | 1 | 0 | 1 | |
1 | 1 | 1 | x | 要避免SR同时为1 |
下面是与非门实现的门控SR锁存器,与或门实现的门控SR锁存器相比,Clk信号是由与非门选通的,而且,S和R正好位置相反。
但它们的特性表是一样的。
Clk | S | R | S‘ | R’ | Q(t+1) | 备注 |
0 | x | x | 1 | 1 | Q(t) | 保持不变 |
1 | 0 | 0 | 1 | 1 | Q(t) | 保持不变 |
1 | 0 | 1 | 1 | 0 | 0 | |
1 | 1 | 0 | 0 | 1 | 1 | |
1 | 1 | 1 | 0 | 0 | x | 要避免SR同时为1 |
门控D锁存器
实际应用中更常用的是门控D锁存器,它在SR锁存器的基础上进行了小小的改动。和SR锁存器不同,D锁存器只有一个输入端D,如下图所示:
D为1,则Q置位为1,D为0,则Q复位为0。相比SR锁存器,D锁存器不会出现S,R都为1的麻烦状态。
D锁存器的输出受到时钟电平高低的控制,所以这种锁存器又被称作电平敏感型信号锁存器。与之对应的是在时钟边沿触发的存储元件,通常称作触发器。
Clk | D | Q(t+1) |
0 | x | Q(t) |
1 | 0 | 0 |
1 | 1 | 1 |
D锁存器的图形符号为:
门控D锁存器的代码如下:
在时钟为高电平时,Q=D,否则Q保持原来的值,所以锁存器可以当作存储元件考虑。
verilog中D锁存器的代码如下:
/*门限D锁存器*/ module dqlatch(D, clk, Q); input D; input clk; output reg Q; always @(D,clk) if(clk) Q = D; //没有else,在clk低电平,Q锁存之前的值。 endmodule
使用下面的testbench代码,可以验证D锁存器。
`timescale 1ns/1ns `define clock_period 20 module dqlatch_tb; reg D; wire Q; reg clk; dqlatch dqlatch0(.D(D),.clk(clk),.Q(Q)); always # (`clock_period/2) clk = ~clk; initial begin D = 1'b0; clk = 1'b0; #(`clock_period) D = 1'b1; #(`clock_period*2) D = 1'b0; #(`clock_period*4) D = 1'b1; #(`clock_period*10) $stop; end endmodule
从波形中,可以看出在时钟信号clk高电平时候,Q=D,否则Q保持之前的值。
在下面的连接中,我们讨论了触发器的传输延时的影响。对于锁存器是一样的分析方法,在时钟边沿到来时,也要考虑信号D的建立时间和保持时间。