锁存器&触发器&寄存器

一、锁存器(Latch)

  • SR锁存器(基本锁存器):

        由两个或非门或者两个与非门组成,电路结构、图形符号和特性表如下所示。

        此时,输出状态(次态)与输入状态、锁存器初态都有关。

                    锁存器&触发器&寄存器_第1张图片          锁存器&触发器&寄存器_第2张图片

 

  • 电平触发SR触发器(门控SR锁存器):

        当CLK=0时(无效),输出状态(次态)保持不变;只有当CLK=1时(有效),输出状态才随输入、初态的不同而改变,且与SR锁存器的特性一样。

        当门控锁存器的控制信号有效时,锁存器就变成了一个组合电路,若此时输入信号发生多次变化,输出状态也可能发生多次变化,这一现象称为锁存器的空翻。此时,时序逻辑电路的模型就等效为两个各组合电路互为反馈的反馈系统,因此,系统有可能会因为瞬态特性不稳定而产生振荡现象抗干扰能力差。   

锁存器&触发器&寄存器_第3张图片锁存器&触发器&寄存器_第4张图片

 

  • 电平触发D触发器(D型锁存器):

        在CLK的有效电平期间,输出状态始终随输入状态变化,输出与输入状态保持相同,所以这个电路又叫“透明的D型锁存器”。

锁存器&触发器&寄存器_第5张图片锁存器&触发器&寄存器_第6张图片

        

二、触发器(flip-floph

  • 边沿触发D触发器

        由两个D型锁存器组成,次态仅取决时钟有效边沿到达时输入的逻辑状态,且值保持不变到下次触发到达时(保持n个时钟周期)。

        电路抗干扰能力强,工作可靠性更高。

锁存器&触发器&寄存器_第7张图片

锁存器&触发器&寄存器_第8张图片

 

三、寄存器(Register)

        寄存器能够存寄一组二值代码,即由N个触发器组成。

 

四、基于Verilog的锁存器&触发器的分析

        锁存器(Latch)具有如下特点:

        (1)对毛刺敏感(使能信号有效电平时,输出状态可能随输入多次变化,产生空翻,对下一级电路很危险),不能异步复位,因此在上电后处于不确定的状态

        (2)锁存器会使静态时序分析变得非常复杂,不具备可重用性。(首先,锁存器没有时钟参与信号传递,无法做STA;其次,综合工具会将latch优化掉,造成前后仿真结果不一致

        (3)在FPGA中基本的单元是由查找表和触发器组成的,若生成锁存器反而需要更多的资源。根据锁存器的特点可以看出,在电路设计中,要对锁存器特别谨慎,如果设计经过综合后产生出和设计意图不一致的锁存器,则将导致设计错误,包括仿真和综合。因此,在设计中需要避免产生意想不到的锁存器。如果组合逻辑的语句完全不使用 always  语句块,就可以保证综合器不会综合出锁存器。

        (4)但如果锁存器和触发器两者都由与非门搭建的话,锁存器耗用的逻辑资源要比D触发器少(D触发器需要12个MOS管,锁存器只需6个MOS管),锁存器的集成度更高,所以在的ASIC设计中会用到锁存器。但锁存器对毛刺敏感,无异步复位端,不能让芯片在上电时处在确定的状态;另外,锁存器会使静态时序分析变得很复杂,不利于设计的可重用。所以,在ASIC设计中,除了CPU这高速电路,或者RAM这种对面积很敏感的电路,一般不提倡用锁存器。 

 

        锁存器(Latch)的出现及解决办法

        在基于always的组合逻辑描述语句中容易综合出锁存器的地方:

        (1)在赋值表达式右边参与赋值的信号未在always@(敏感电平列表)中列出完整,生成透明锁存器;

        (2)if语句的使用中缺少else语句(前提不是始终时钟触发);

        (3)case语句没有给出全部情况。

 

        举例说明:

        (1)时序电路中if...else不完整不会生出latch,而组合逻辑就会产生latch:

锁存器&触发器&寄存器_第9张图片

        左上的电路是时序逻辑生成触发器,而触发器是有使能端(enable)的,使能端无效时就可以保存数据,无需锁存器。右上的电路是组合逻辑,在enable为低电平时,输出q要保持不变,而组合逻辑没有存储元件只能生成锁存器来保持数据。所以在时序逻辑中,不完整的 if…else… 结构并不会生成锁存器,而组合逻辑中不完整的 if…else… 结构就会生成锁存器。为了避免我们设计的组合逻辑中出现不想要的锁存器,在使用 if…else… 结构时一定要写完整

module ex1(
	// input clk,
	input enable,data,
	output reg q
	);
	
	always @(*)
	// always @(posedge clk)	                // 方法1:将锁存器改为带使能的触发器	
		begin
			// q = 0;			// 方法2:给输出变量赋初始值
			if(enable)
				q = data;
			// else				// 方法3:补全if...else语句
				// q = 0;
		end
		
endmodule

        解决方法

        ①将锁存器改为带使能的触发器(变为时序电路);

        ②给输出变量赋初始值;

        ③补全if...else语句。

 

        感悟

        ①在always模块内被赋值的每一个信号都必须定义成reg型,但不一定就会生成寄存器。

        ②组合逻辑一般使用assign语句。

        ③当组合逻辑使用always模块时,@(*)或敏感信号列表需写完整,都属于电平触发。另外,if...else以及case情况(必要时加上default)需写完整,或者输出状态赋初始值。

        ④时序逻辑中“always @(posedge clk)”属于同步时钟,而“always @(posedge clk,negedge rst)”属于同步时钟,异步复位。

        ⑤“=”阻塞赋值表示组合逻辑,“<=”非阻塞赋值表示时序逻辑。

 

        另外,可以参考FPGA 中的latch 锁存器。

你可能感兴趣的:(FPGA,数电)