锁存器(Latch)是数字电子中常用的一种基本元件,用于在特定的时间点或条件下“锁存”或保存输入的数据值。锁存器对脉冲电平敏感,它只在输入脉冲的高电平(或低电平)期间对输入信号敏感并改变状态。在数字电路中可以记录二进制数字信号“ 0”和 1”。
锁存器的主要作用:
- 缓存数据。
- 解决高速控制器与慢速外设之间的不同步问题。
- 解决驱动问题。
- 解决一个I/O口既能输出也能输入的问题。
锁存器的工作原理:
- 锁存器的工作是基于电平控制数据的输入,包括不带使能控制的锁存器和带使能控制的锁存器。
- 在没有锁存信号时,锁存器的输出随输入信号变化,就像信号通过一个缓冲器一样。
- 一旦锁存信号起作用,数据被锁住,输入信号不再影响输出。这意味着在有锁存信号时,输入的状态被保存到输出,直到下一个锁存信号。
锁存器不同于触发器,锁存器在不锁存数据时,输出端的信号随输入信号变化,就像信号通过一个缓存器一样;一旦锁存信号起锁存作用,则数据被锁住,输入信号不起作用。因此锁存器也称为透明锁存器,指的是不锁存时输出对输入是透明的。
锁存器的类型:
- 常见的锁存器类型包括RS锁存器(Reset-Set Latch)、D锁存器(Data Latch)等。
- RS锁存器:当S(Set)输入为高电平且R(Reset)输入为低电平时,输出Q被置位为高电平;当S为低电平且R为高电平时,输出Q被复位为低电平。
- D锁存器:有一个数据输入端(D)和一个使能端(E)。当使能信号有效时,D锁存器捕获D端的信号并保存在输出Q上;当使能信号无效时,输出Q保持不变,直到下一个使能脉冲到来。
1 RS锁存器
从RS锁存器的电路结构图我们可以看出,该电路主要是由两个部分组成,第一个部分是由两个与门组成的RS锁存器,第二个部分是由两个或非门组成的控制电路。R为复位信号,S为置位信号,C为控制信号,用来控制前两个与门的激励输入。
下面我们来分析下RS锁存器的工作原理,当控制信号C=0时,根据与门的逻辑定律,无论R和S输入什么信号, RD和 SD信号同时为 0。 根据由或门组成的 RS锁存器的逻辑定律, RD和 SD都同时
等于 0的话,锁存器的输出端 Q将维持原状态不变,即处于保持状态。
当控制端 C=0时:电路处于保持状态,RS锁存器不起作用。
当控制端 C=1时:
- 若R=0,S=0,即无激励信号时,有以下两种情况:
锁存器输出结果为:Qn+1 = Qn
其中 Qn是指触发器当前逻辑状态(即触发前的状态), Qn+1是指触发后的状态。
- 若R=1,S=0,即置位信号为0
锁存器输出结果为:Qn+1 = 0
- 若R=0,S=1,即置位信号为1
锁存器输出结果为:Qn+1 = 1
- 若R=1,S=1,即置位、复位信号同时为1
当激励信号由11变为00时,锁存器的输出既可以稳定在1状态,也可以稳定在0状态。 这时的状态是不稳定的,所以我们要禁止使用11这一组激励信号。
根据上面的描述,可以推断出RS锁存器的特性表,其中 Qn是指触发器当前逻辑状态(即触发前的状态), Qn+1是指触发后的状态。
从上表可以看出,只有在置位或复位信号为1时,RS锁存器才起作用的,都为0时不起作用。
RS锁存器的工作波形图如下:
2 D锁存器
从D锁存器的电路结构图我们可以看出,该电路主要是由两个部分组成,第一个部分是由两个与非门组成的RS锁存器,第二个部分是由两个与非门组成的控制电路。C为控制信号,用来控制前两个与非门的激励输入。
下面我们来分析下D锁存器的工作原理,当控制信号C=0时,根据与非门的逻辑定律,无论D输入什么信号, RD和 SD信号同时为 1。 根据由与非门组成的 RS锁存器的逻辑定律, RD和 SD都同时
等于 1的话,锁存器的输出端 Q将维持原状态不变,即处于保持状态。
当控制端 C=1时,如果此时 D= 0, SD就等于1, RD就等于 0,根据 RS锁存器的逻辑规律,电路的结果就为 0状态;如果 D = 1,那么 RD就等于 1,SD也就等于 0,锁存器的结果就为 1状态,也就是说,此时锁存器的状态是由激励输入端 D来确定的,并且 D等于什么,锁存器的状态就是什么,电路不再保持原来的状态,将处于一个新状态D。这就是将单路数据 D存入到锁存器之中。
根据上面的描述,可以推断出D锁存器的特性表,其中 Qn是指触发器当前逻辑状态(即触发前的状态), Qn+1是指触发后的状态。
通过这个表格,我们可以看出,当C为 1时, D的状态和 Qn+1的状态完全一样,当 D=0时, Qn+1=0,当 D=1时, Qn+1=1。
还可以进一步画出D锁存器的工作波形图。
从D锁存器的工作波形图图中我们可以看出, D是锁存器的输入信号, C是锁存器的控制信号,
Q是锁存器的输出信号。
当控制信号 C为高电平时:
- 输出信号 Q将跟随输入信号 D的变化而变化。
- 虚线内, Q的波形等于 D的波形。
当控制信号 C从高电平变为低电平时,输入信号 D的状态将会决定锁存器将要锁存的状态。
C由高变低时:
- 若所对应的输入信号 D为低电平,那么输出信号 Q也将会锁存低电平。
- 若所对应的输入信号 D为高电平,那么输出信号 Q也将会锁存高电平。
3 锁存器的缺点
在绝大多数FPGA设计中,要避免产生锁存器。它会让您设计的时序出问题,并且它的隐蔽性很强,新人很难查出问题。锁存器最大的危害在于不能过滤毛刺和影响工具进行时序分析。这对于下一级电路是极其危险的。所以,只要能用触发器的地方,就不用锁存器。
锁存器的示意图如上,它没有时钟信号,只有数据输入和使能以及输出q端,没有时钟信号也就说明我们没有办法对这种器件进行时序分析,这个在时序电路里面是非常危险的行为,因为可能引起时序不满足导致电路功能实现有问题。
4 FPGA设计中使用锁存器的注意事项
一般出现下面两种情况时,组合逻辑代码在综合过程中会出现锁存器:
- if语句中缺少else分支;
- case语句中缺少default分支。
解决办法:
就是if必须带else分支,case必须带default分支。
注意:
只有不带时钟的always语句中if或者case语句不完整才会产生latch,带时钟的语句if或者case语句不完整描述不会产生latch。
5 在FPGA中使用锁存器
5.1 不带else的always语句(没有clk)
module latch(
input clk, // system clock 6
input a,
input b,
output reg y
);
always @ (*)
begin
if (a == 1)
y = b ;
end
endmodule
使用vivado中RTL ANALYSIS的Schematic来看综合后的电路结构,
从上图可以看出,这个寄存器没有clk输入信号,图上标识出latch的名字,可以看出这个电路就是latch。
5.2 else的always语句(没有clk)
下面我们把else补充完整再来看下电路结构, 代码如下:
module latch(
input clk, // system clock 6
input a,
input b,
output reg y
);
always @ (*)
begin
if (a == 1)
y = b ;
else
y = 0;
end
endmodule
使用vivado中RTL ANALYSIS的Schematic来看综合后的电路结构,
上图所示的电路结构是一个mux选择电路,可以看出,加了else分支的电路就不会有latch电路。
5.3 不带default的case语句
module latch(
input clk, // system clock 6
input a,
input b,
output reg y
);
always @ (*)
begin
case ( a )
0 : y = b ;
endcase
end
endmodule
使用vivado中RTL ANALYSIS的Schematic来看综合后的电路结构,
从上图可以看出,这个寄存器没有clk输入信号,图上标识出latch的名字,可以看出综合出的这个电路就是latch。
5.4 带default的case语句
module latch(
input clk, // system clock 6
input a,
input b,
output reg y
);
always @ (*)
begin
case ( a )
0 : y = b ;
default : y = 0 ;
endcase
end
endmodule
使用vivado中RTL ANALYSIS的Schematic来看综合后的电路结构,
综合后产生的是一个mux选择电路,因此,加了case的default分支的电路就不会有latch电路。