当前位置:   article > 正文

FPGA结构:LATCH(锁存器)和 FF(触发器)介绍_ff en触发器

ff en触发器

FPGA 系列文章



一、LATCH(锁存器)是什么

一句话概括,能够存储一个状态的数字电路叫做锁存器。

以下是最为基本的一个RS锁存器的具体结构:

请添加图片描述

以下是它的真值表,其中X表示不确定/无效:

R {R} R(清零) S {S} S(置位) Q ( t ) {Q(t)} Q(t) (上一时刻的输出 ) Q ( t + 1 ) {Q(t+1)} Q(t+1) (这一时刻的输出A) Q ‾ \overline{Q} Q(这一时刻的输出B)
00QQ!Q
10Q01
01Q10
11XXX

这张真值表的前三行如下图所示,能够使得输出的结果和定义一致。
第一种情况,电路能够维持输出为Q:
第一种情况
第二种情况,上面的NOR门输出一定为0,进而使得整个电路达到稳态:

请添加图片描述
第三种情况,下面的NOR门输出一定为0,进而使得整个电路达到稳态:
请添加图片描述
唯独这张真值表的第四行输出结果和定义不一致:
请添加图片描述
看起来这张电路图是一个稳定的状态,但当我们把这个状态切换到S=R=0的状态时,就会产生两种可能的稳态:

1.上面R对应的或非门电路延迟较低,这时候Q先被置为1:

请添加图片描述

2.下面S对应的或非门电路延迟较低,这时候!Q先被置为1:

请添加图片描述

在这种情况下,输出结果完全随机(与电路延迟相关),由于这种现象很玄学。因此我们在使用RS锁存器时,一般不会将R和S同时置1。

为了解决RS锁存器带来的问题(RS不能同时为1),我们需要在它的输入之前添加一些逻辑电路,进化版本的RS锁存器被叫做D锁存器。

D锁存器的具体结构如下:

请添加图片描述

D锁存器在RS锁存器的输入之前添加了一个非门,排除了RS同时为1的情况。同时,上图中的D锁存器将使能输入(E)设置为clock,使得该电路只有在时钟信号为1的时候才能够工作(设置为时钟信号为0时工作也很简单)

D锁存器的真值表如下:

D {D} D(置位) E {E} E(使能) Q ( t ) {Q(t)} Q(t) (上一时刻的输出 ) Q ( t + 1 ) {Q(t+1)} Q(t+1) (这一时刻的输出A) Q ‾ ( t + 1 ) \overline{Q}(t+1) Q(t+1)(这一时刻的输出B)
00QQ!Q
10QQ!Q
01Q10
11Q01

D锁存器足够完美了吗?

当然不,D锁存器同样存在问题,那就是无法去除输入的毛刺/抖动。当E为1的时候,D 和 !Q 的值永远是相等的 (哪怕输入存在毛刺/抖动)。为了进一步的改进,人们在D锁存器的基础上提出了触发器的概念。触发器的具体结构会在第二章进行介绍。

二、FF(触发器)是什么

一句话概括:触发器是能在指定的事件发生时存储状态的数字电路。

触发器是时序逻辑电路的基本单元,用来存储1位2进制信息,具有记忆和存储功能。常见的触发器包括D触发器,J-K触发器等。

D触发器

D触发器可以由两个D锁存器级联构成,它的具体结构如下,其中FF1和FF2都代表上文提到的D锁存器:
请添加图片描述
以下是两个D锁存器级联构成的D触发器的真值表:

D {D} D C L K {CLK} CLK Q ( t ) {Q(t)} Q(t) (上一时刻的输出 ) Q ( t + 1 ) {Q(t+1)} Q(t+1) (这一时刻的输出A) Q ‾ ( t + 1 ) \overline{Q}(t+1) Q(t+1)(这一时刻的输出B)
00QQ!Q
10QQ!Q
00->1Q01
10->1Q10
01QQ!Q
11QQ!Q
01->0QQ!Q
11->0QQ!Q

从真值表中可以看出,输出的改变只可能发生在时钟信号的上升沿。接下来让我们按CLK依次分析这四种情况:

  • 第一种情况,CLK为0,这时候FF2的CLK输入为0,因此电路的输出保持不变。

  • 第二种情况,CLK处于上升沿(0->1)到达的瞬间,由于电路内部的延迟,这时候FF1会先取上升沿到达之前瞬间D的状态,之后将该状态保存。

  • 第三种情况,CLK为1,这时候FF1的CLK输入为0,因此Q1的输出保持不变,进而使整个电路的输出保持不变。

  • 第四种情况,CLK处于下降沿(1->0)到达的瞬间,由于电路内部的延迟,这时候FF2会先取下降沿到达之前瞬间Q1的状态,之后将该状态保存。

JK触发器

JK触发器弥补了RS锁存器的缺陷,能够在输入为1时将状态翻转。JK触发器的具体结构如下图:

请添加图片描述

蓝框中的电路结构将或非门换为了与非门,同样也是RS锁存器的一种表现方式。感兴趣的同学可以自己推导一下真值表。

这里先直接给出与非门实现RS锁存器的真值表:

S {S} S(置位) R {R} R(清零) Q ( t ) {Q(t)} Q(t) (上一时刻的输出 ) Q ( t + 1 ) {Q(t+1)} Q(t+1) (这一时刻的输出A) Q ‾ \overline{Q} Q(这一时刻的输出B)
00XXX
01Q10
10Q01
11QQ!Q

JK触发器通过红框实现上升沿读取数据。当CLK处于上升沿(0->1)时,由于非门的延迟,会有一瞬间出现CLK变为1的情况,这时候读取数据,剩下的时候CLK均为0。

在时钟上升沿信号未到来时,与非门G3和G4将J与K端的输入信号屏蔽,触发器状态不受输入信号的影响,维持不变。在时钟上升沿信号到来时,触发器的状态将会随着J与K的输入产生相应的变化。

  • 时钟上升沿信号到来时,J=0,K=0,触发器状态维持不变。

  • 时钟上升沿信号到来时,J=1,K=0,这时候S和R的值分别为Q和1,JK触发器会将这一时刻的输出A置为1。(无论Q为0或1,根据上面的真值表,这一时刻的输出A都一定为1)

  • 时钟上升沿信号到来时,J=0,K=1,这时候S和R的值分别为1和!Q,JK触发器会将这一时刻的输出A置为0。(无论Q为0或1,根据上面的真值表,这一时刻的输出A都一定为0)

  • 时钟上升沿信号到来时,J=K=1,这时候S和R的值分别为Q和!Q,根据上面的真值表,这一时刻的输出A与这一时刻的输出B一定为!Q和Q,实现翻转。

JK触发器的真值表如下图:

J {J} J K {K} K C L K {CLK} CLK Q ( t ) {Q(t)} Q(t) (上一时刻的输出 ) Q ( t + 1 ) {Q(t+1)} Q(t+1) (这一时刻的输出1) Q ‾ ( t + 1 ) \overline{Q}(t+1) Q(t+1)(这一时刻的输出2)
000QQ!Q
010QQ!Q
100QQ!Q
110QQ!Q
000->1QQ!Q
010->1Q01
100->1Q10
110->1Q!QQ
001QQ!Q
011QQ!Q
101QQ!Q
111QQ!Q
001->0QQ!Q
011->0QQ!Q
101->0QQ!Q
111->0QQ!Q

将J和K合并成一个信号,它就有了一个新名称:T触发器。

三、牛刀小试:避免使用Verilog综合出LATCH

因为LATCH的种种缺点,它是我们在写Verilog代码的时候唯恐避之不及的。然而,我们常常会遇到由于逻辑定义不完整综合出LATCH的情况。在代码包含always@(*)时,一般情况下会综合出LUT,但假如没有将if/else中所有case的赋值情况写完整,编译器就会综合出LATCH,以下是一段综合出LATCH的Verilog代码:

module top_module (
    input [15:0] scancode,
    output reg left,
    output reg down,
    output reg right,
    output reg up  ); 
    always @(*) begin 
       case(scancode)
           16'he06b:
                left=1;
           16'he072:
                down=1;
           16'he074:
                right=1;
           16'he075:
                up=1;
       endcase
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这段代码与人物上下左右移动有关。例如16’he06b这个case,如果我们在其中没有指定down,right和up的值,那么它就会自动保存原来的值(信号接收之前的值),综合出锁存器。

如何让上面的电路不综合出LATCH呢?

非常简单,只要在每一次 always @(*) begin 的最开始指定left,down,right和up的值就可以了,更改后的代码如下所示:

module top_module (
    input [15:0] scancode,
    output reg left,
    output reg down,
    output reg right,
    output reg up  ); 
    always @(*) begin 
    left=0;down=0;right=0;up=0;// 给up,down,left,right赋初始值
       case(scancode)
           16'he06b:
                left=1;
           16'he072:
                down=1;
           16'he074:
                right=1;
           16'he075:
                up=1;
       endcase
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

需要注意的是,对于always@(posedge clk),即使case不完整,也不会综合出LATCH,综合器会将这些不执行的情况视为不需要进行任何操作。

参考文档

FPGA中LUT、LATCH、FF的概念

RS锁存器,D锁存器、D触发器简介

数字电路学习笔记(九):初识锁存器

D触发器 (D-FF)详解

数字电路中的锁存器(latch)和各种触发器(flip-flop)

从CMOS到触发器(二)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/440999
推荐阅读
相关标签
  

闽ICP备14008679号