数字电路基础---触发器
触发器(Flip-Flop)也是数字电路中的一种具有记忆功能的逻辑元件。触发器对脉冲边沿敏感的存储单元电路,它只在触发脉冲的上升沿(或下降沿)瞬间改变其状态。在数字电路中可以记录二进制数字信号“0”和“1”。
1、简介
根据逻辑功能,触发器一般包括 RS 触发器、JK 触发器、D 触发器、T 触发器和 T’触发器。
实际使用中,我们一般使用 D 触发器,下面我们就以 D 触发器为例,先讲解 D 触发器是如何构成的。在给出 D 触发器的电路图之前,我们先来看下 D 锁存器的逻辑符号,如下图所示。
D 锁存器的电路结构还是比较复杂的,为了简化起见,我们一般使用右面的图示作为 D 锁存器的逻辑符号。
下面我们来看下 D 触发器的构成。
从 D 触发器的电路图中我们可以看出,该电路是由两个相同的 D 锁存器以及两个非门连接而成的,图中的 F1 和 F2 就是 D 锁存器的电路符号,F1 为主锁存器,F2 为从锁存器,由于主锁存器的输出信号 Q1 就是从锁存器的输入信号,因而造成了两个锁存器的主从关系,这两个锁存器的控制信号都由外部时钟信号 CLK 提供。
1.1、D 触发器是如何工作的
下面我们来分析 D 触发器是如何工作的。当 CLK=0 时,CLK 经过非门后直接作为 F1 的控制信号,那么此时 F1 的控制信号为 1,F1 被选通,处于工作状态,如果现在输入信号 D 为 1 的话,它经过 F1,F1 的输出 Q1 将为 1,这里的 Q1,不仅是 F1 的输出信号,也同时是 F2 的输入信号,不过现在 F2 的控制信号为 0,F2 被锁存了,处于保持状态,输入信号 D 没有办法直接改变输出 Q 的状态,这是前半拍的工作情况,也就是说,输入信号先存入主锁存器中,而不直接影响输出 Q 的状态。下面我们再来看后半拍,外部的控制信号 CLK 由 0 变为 1 了,这个 1,经过非门后直接作为 F1 的控制信号,那么此时 F1 的控制信号为 0,主锁存器 F1 就被封锁了,它的输出 Q1 将保持在当前的状态,即使现在输入信号 D 再发生改变,Q1 的值也不再受影响了。而 F2 的控制信号 CLK 此时为 1,F2 处于工作状态,Q1 将会作为 F2 这个从锁存器的输入信号,直接影响到输出信号 Q 的状态。Q1 为 1,那么根据 D 锁存器的逻辑规律,输出的 Q 将为 1,Q 非将为 0。这就是后半拍的工作情况,在后半拍里我们才能实现整个电路状态的改变,因此从上面的分析中我们就可以看出,在 CLK 信号由 0 变为 1 这样的一个变化周期内,触发器的输出状态只可能改变一次。
通过 D 锁存器和 D 触发器的学习,可能有些同学已经发现了,D 锁存器与 D 触发器的逻辑功能其实是相同的,只不过它们的触发方式有所不同。接下来我们通过将 D 触发器的波形图与前面 D 锁存器的波形图进行比较,来看一看,它们的触发方式不同在哪里。
大家先看 D 触发器的波形图,D 触发器是在控制信号 CLK 为 0 时,才会接收输入信号 D 的值,并将这个值锁存起来,当控制信号 CLK 变为 1 时,输出信号 Q 才会被改变。那么 D 触发器,其实就是在 CLK 这个时钟信号由 0 变为 1 的这个边沿进行触发的,通常我们就将这种触发方式称为边沿触发,通过这种边沿触发方式的 D 触发器我们也将它称为边沿 D 触发器。
D 锁存器的触发方式是电平触发,和我们刚刚讲的边沿触发是有所不同的。这种不同是由于锁存器和触发器的电路结构不同造成的。这里需要注意的是,由于 D 锁存器的功能和 D 触发器的功能是一 样的,所以在编写代码时很容易把 D 锁存器当成 D 触发器来使用,这种情况我们是要避免的,锁存器对电路的危害我们在锁存器章节已有过描述。
D 触发器的基础知识已经讲完了,我们前面讲的所有内容其实都是为边沿触发器做铺垫。在组合电路中我们知道,与或非门是组合电路的核心知识,没有搞清楚与或非,就看不懂组合逻辑电路,在时序电路中,边沿触发器就是时序电路的核心知识,如果不懂边沿触发器,那么也就看不懂时序电路,后续讲解的寄存器和计数器都是用这些边沿触发器组合而成的。
2、实验任务
使用 Verilog 语言设计一个触发器电路。(只要能用触发器的地方, 就不用锁存器。)
3、程序设计
触发器电路一般需要有时钟,复位信号,输入和输出,由此我们写出如下代码。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/06/19 10:43:55
// Design Name:
// Module Name: flip_flop
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
//实验任务
//使用 Verilog 语言设计一个触发器电路。(只要能用触发器的地方, 就不用锁存器。)
//触发器电路一般需要有时钟,复位信号,输入和输出.
module flip_flop(
input clk, // system clock 50Mhz on board
input rst_n, // system rst, low active
input a,
output reg y // output signal
);
//******************************************************
//** main code
//******************************************************
always @ (posedge clk or negedge rst_n) begin
if (rst_n == 1'b0)
y <= 1'b0 ;
else
y <= a ;
end
endmodule
我们使用 Vivado 的 RTL ANALYSIS 中的 Schematic(Quartus II 综合后也可以看到电路结构)来看下综合的电路结构。
从上图可以看出,这个触发器有 clk 输入信号,图上标识出 reg 的名字,可以看出这个电路就是一个触发器。
下面我们编写一个 testbech 测试电路,通过仿真来看下触发器的波形。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/06/19 10:56:16
// Design Name:
// Module Name: tb_flip_flop
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tb_flip_flop();
reg sys_clk;
reg sys_rst_n;
reg a;
wire y;
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
// 初始化 a 为 0
a = 1'b0;
#200
sys_rst_n = 1'b1;
#100
// 让 a 为 1
a = 1'b1;
#60
// 让 a 为 0
a = 1'b0;
end
always #10 sys_clk = ~sys_clk;
flip_flop u_flip_flop(
.clk (sys_clk ),
.rst_n (sys_rst_n ),
.a (a ),
.y (y )
);
endmodule
4、仿真验证
测试程序在 Modelsim 或者其他仿真工具(Xilinx 的 Vivado 软件也有仿真功能)运行后的波形如下显示,可以看出,当复位撤销(复位信号低有效)之后,当 a 为 1 之后,在下一个时钟上升沿之后,y 就输出为 1,当 a 为 0 之后,下一个时钟上升沿之后,y 就输出为 0,可以看出寄触发器的采样都是在时钟上升沿进行的,其他时候触发器是保持之前采样的信号。