时序逻辑电路
- 1.1 简介
- 1.2 锁存器
- 1.2.1 概念
- 1.2.2 产生
- 1.3 触发器
- 1.3.1 概念
- 1.3.2 分类
- 1.3.2 两种触发方式
- 1.3.3 程序设计与验证
- 1.4 寄存器
- 1.4.1 概念
- 1.4.2 程序设计与验证
- 1.5 计数器
- 1.5.1 概念
- 1.5.2 程序设计与验证
- 1.6 寄存器
- 1.6.1 概念
- 1.6.2 程序设计与验证
1.1 简介
时序逻辑由组合逻辑和存储逻辑构成,组合逻辑完成输入到输出的逻辑处理,处理的结果同时会进入存储逻辑里面存储下来,等到下一刻再和输入信号做逻辑处理,得到最终的处理结构。

时序逻辑示意图
时序逻辑的存储电路一般由锁存器、触发器和寄存器构成。锁存器(latch)是电平出发的存储单元,数据存储的动作取决于输入时钟或者使能信号的电平值,即当锁存器处于使能状态时,输出才会随着数据输入发生变化。触发器(flipflop)是边沿敏感的存储单元,数据的存储动作由某一信号的上升或下降沿进行同步的。寄存器(register)是用来暂时存放参与运算的数据和运算结果。
由于触发器内有记忆功能,因此利用触发器可以方便地构成寄存器,一个触发器能够存储异味二进制码,所以把n个触发器的时钟端口连接起来就能构成一个存储n位二进制的寄存器。
从寄存数据的角度来讲,寄存器和锁存器的功能相同的,他们的主要区别是寄存器是同步时钟控制,而锁存器是电位信号控制。
1.2 锁存器
1.2.1 概念
锁存器对脉冲电平敏感的存储单元电路,它只在输入脉冲的高电平(或低电平)期间对输入信号敏感并改变状态。在数字电路中可以记录二进制数字0和1。锁存器不锁存数据时,输出端的信号随输入信号变化,也被称为透明锁存器。分类:RS锁存器、门控RS锁存器、D锁存器注意:在绝大多数设计中我们要避免产生锁存器,最大的危害在于不能过滤毛刺和影响时序分析,所以只要能用触发器的地方就不用锁存器。

由上图可知,锁存器没有时钟信号,只有数据输入和使能以及输出q端,没有时钟信号也就说明没有办法进行时序分析。
1.2.2 产生
在组合逻辑中,if 或者 case 语句不完整的描述,比如if 少了else分支,case少了default分支。
解决办法:if 必须带else分支,case必须带default分支。
注意:只有不带时钟的always语句的if 或case语句 不完整 才会 产生latch,带时钟的语句if 或case语句 不完整 不会 产生latch。
1.3 触发器
1.3.1 概念
触发器对脉冲边沿敏感的存储单元电路,它只在触发脉冲的上升沿或下降沿
瞬间改变其状态。
1.3.2 分类
一般包括:RS触发器、JK触发器、D触发器、T 触发器、T’触发器
实际使用中,我们一般使用D触发器,下图为其逻辑符号:

有两个相同的D锁存器以及两个非门连接而成。
1.3.2 两种触发方式

与或非门是组合电路的核心,边沿触发是时序电路的核心。
1.3.3 程序设计与验证
下面展示 功能代码。
`timescale 1ns / 1ps
//// Verilog 功能代码如下:module flipflop(
//input
input sys_clk,
input sys_rst_n,
input data,
//output
output reg y);always @ (posedge sys_clk or negedge sys_rst_n) beginif (sys_rst_n == 1'b0)y <= 1'b0;elsey <= data;end
endmodule// Verilog 仿真代码如下:module tb_flipflop();reg sys_clk;reg sys_rst_n;reg data;wire y;initial beginsys_clk = 1'b0;sys_rst_n = 1'b0;data = 1'b0;#100sys_rst_n = 1'b1;#100data = 1'b1;#100data = 1'b0;#100data = 1'b1;#100data = 1'b0;end always #10 sys_clk = ~ sys_clk ;flipflop u_flipflop(
//input.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.data(data),
//output.y(y));endmodule

1.4 寄存器
1.4.1 概念
寄存器是多个触发器构成的,因此可以存储多bit二进制数据。只有时钟上升沿,数据采用变化,其他时候数据保持锁存状态。
1.4.2 程序设计与验证
下面展示 功能代码。
`timescale 1ns / 1ps// Verilog 功能代码如下:module register(
//input
input sys_clk,
input sys_rst_n,
input data,
//output
output wire y);reg data_0;reg data_1;reg data_2;reg data_3;always @ (posedge sys_clk or negedge sys_rst_n) beginif (sys_rst_n == 1'b0)begindata_0 <= 1'b0;data_1 <= 1'b0;data_2 <= 1'b0;data_3 <= 1'b0;endelse begindata_0 <= data;data_1 <= data_0;data_2 <= data_1;data_3 <= data_2;endendassign y = data_3;
endmodule// Verilog 仿真代码如下:module tb_register();reg sys_clk;reg sys_rst_n;reg data;wire y;initial beginsys_clk = 1'b0;sys_rst_n = 1'b0;data = 1'b0;#100sys_rst_n = 1'b1;#100data = 1'b1;#100data = 1'b0;#100data = 1'b1;#100data = 1'b0;end always #10 sys_clk = ~ sys_clk ;register u_register(
//input.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.data(data),
//output.y(y));endmodule

1.5 计数器
1.5.1 概念
计数器由寄存器和加法器组成,使用计数器可以实现精确的计时、分频控制和各种协议的接口时序。
三位计数器电路图:

1.5.2 程序设计与验证
下面展示 功能代码。
`timescale 1ns / 1ps
//// Verilog 功能代码如下:module flipflop(
//input
input sys_clk,
input sys_rst_n,
input data,
//output
output reg y);always @ (posedge sys_clk or negedge sys_rst_n) beginif (sys_rst_n == 1'b0)y <= 1'b0;elsey <= data;end
endmodule// Verilog 仿真代码如下:module tb_flipflop();reg sys_clk;reg sys_rst_n;reg data;wire y;initial beginsys_clk = 1'b0;sys_rst_n = 1'b0;data = 1'b0;#100sys_rst_n = 1'b1;#100data = 1'b1;#100data = 1'b0;#100data = 1'b1;#100data = 1'b0;end always #10 sys_clk = ~ sys_clk ;flipflop u_flipflop(
//input.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.data(data),
//output.y(y));endmodule

1.6 寄存器
1.6.1 概念
寄存器是多个触发器构成的,因此可以存储多bit二进制数据。只有时钟上升沿,数据采用变化,其他时候数据保持锁存状态。
1.6.2 程序设计与验证
下面展示 功能代码。
`timescale 1ns / 1ps// Verilog 功能代码如下:module counter(
//input
input sys_clk,
input sys_rst_n,
//output
output reg [2:0] add);always @ (posedge sys_clk or negedge sys_rst_n) beginif (sys_rst_n == 1'b0)beginadd <= 1'b0;endelse beginadd <= add + 1'b1;endendendmodule// Verilog 仿真代码如下:module tb_counter();reg sys_clk;reg sys_rst_n;wire [2:0] add;initial beginsys_clk = 1'b0;sys_rst_n = 1'b0;#100sys_rst_n = 1'b1; end always #10 sys_clk = ~ sys_clk ;counter u_counter(
//input.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),
//output.add(add));endmodule















