时序逻辑最基本的单元就是寄存器,寄存器具有存储功能,一般是由D触发器构成,由时钟脉冲控制,每个D触发器可以存储一位二进制码。
D触发器的工作原理:在一个脉冲信号的上升沿或者下降沿的作用下,将信号从输入端D送到输出端Q,如果时钟脉冲的边沿信号未出现,即使输入信号改变,输出信号仍然保持原值,且寄存器拥有复位清零功能,其复位又分为同步复位和异步复位。
背景:使用按键key1控制led灯2,按键未按下处于熄灭状态,按键按下灯被点亮。
同步复位的D触发器
“同步”指的是和工作时钟同步,也就是说当时钟的上升沿(或下降沿)来到时检测到的复位操作才有效,否则无效。
如图,我们假设输出始终为高电平,如同图中所示虚线,复位信号拉低之后,led_out并没有立刻变为0,而是当时钟上升沿到来的时候led_out才复位成功,在复位释放的时候也是基于相同的原因。
异步复位的D触发器
“异步”指的是和工作时钟不同步的意思,也就是说,寄存器的复位不关心时钟的上升沿来不来,只要检测到按键被按下,就立刻执行复位操作。如图中最下面的变量所示:
当复位信号拉低之后,led_out立刻变为0,而不是等待时钟上升沿到来时才复位,而在复位释放时led_out不会立刻变为key_in的值,因为还要等待时钟上升沿到来时才能检测到key_in的值,此时才会将key_in的值赋给led_out。
相比于组合逻辑电路来讲,对于电路中产生的毛刺有较好的屏蔽作用。时序电路还有一个特点就是“延一拍”(默认采集的是该时钟前一时刻的值)。
一、Visio画图
二、代码编写
module flip_flop(
input wire sys_clk,//50Mhz
input wire sys_rst_n,//低电平有效
input wire key_in,
output reg led_out
);
//同步复位
always @(posedge sys_clk) begin
if(sys_rst_n==1'b0)
led_out <= 1'b0;
else
led_out<=key_in;
end
endmodule
对应的同步复位rtl视图如图:
module flip_flop(
input wire sys_clk,//50Mhz
input wire sys_rst_n,//低电平有效
input wire key_in,
output reg led_out
);
//同步复位
always @(posedge sys_clk or negedge sys_rst_n) begin
if(sys_rst_n==1'b0)
led_out <= 1'b0;
else
led_out<=key_in;
end
endmodule
对应的异步复位rtl视图如下:
三、仿真
1、对同步复位代码进行仿真验证
`timescale 1ns/1ns
module tb_flip_flop();
reg sys_clk;
reg sys_rst_n;
reg key_in;
wire led_out;
initial
begin
sys_clk=1'b1;
sys_rst_n<=1'b0;
key_in<=1'b0;
#20
sys_rst_n<=1'b1;//复位信号是低电平有效
#210
sys_rst_n<=1'b0;
#40
sys_rst_n<=1'b1;
end
always #10 sys_clk=~sys_clk;//一个时钟周期20ns
always #20 key_in<={$random}%2;
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("@time %t:key_in=%b,led_out=%b",$time,key_in,led_out);
end
flip_flop flip_flop_inst(
.sys_clk (sys_clk),//50Mhz
.sys_rst_n(sys_rst_n),//低电平有效
.key_in (key_in),
.led_out (led_out)
);
endmodule
同步复位仿真波形如图:
2、对异步复位代码进行仿真验证
仿真波形图如图:
因为此处和前面的点亮led灯是同样的效果,所以此处就不再进行上板验证。