同步、异步复位、异步复位同步释放

同步、异步复位、异步复位同步释放


1、同步复位

  同步复位,顾名思义是复位信号和时钟同步,当时钟上升沿检测到复位信号,执行复位操作。同步复位没有用到寄存器的异步复位CLR端口,综合出来的实际电路只是把复位信号rst_n作为逻辑输入的使能信号。

同步复位代码:

//同步复位
module top
(
	input	clk,
	input	rst_n,
	input	a,
	
	output	reg	b
	
);


always@(posedge	clk)
begin
	if(!rst_n)
		b <= 1'b0;
	else
		b <= a;
end

endmodule

同步复位RTL视图:
在这里插入图片描述
  同步复位增加了FPGA内部的资源消耗,同步复位在时钟信号clk的上升沿触发时进行系统是否复位判断,这降低了亚稳态出现概率(只是降低,不可能完全避免),它的缺点在于需要消耗更多的器件资源,无法充分利用专用的复位端口CLR。

2、异步复位

  异步复位,无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。
异步复位代码:

//异步复位
module top
(
	input	clk,
	input	rst_n,
	input	a,
	
	output	reg	b
	
);


always@(posedge	clk or negedge rst_n)
begin
	if(!rst_n)
		b <= 1'b0;
	else
		b <= a;
end

endmodule

异步复位RTL视图:
在这里插入图片描述
  FPGA的寄存器都有一个异步清零端(CLR),在这个端口一般接低电平有效的复位信号rst_n,即使设计中是高电平复位,实际综合后也会把异步复位信号反向后接到CLR端。
异步复位无需增加器件的额外资源,但是存在隐患,异步时钟域的亚稳态问题同样存在于异步复位信号和系统时钟 信号之间。

2.1、异步复位的隐患

通过一下实例分析异步复位存在的隐患:

//异步复位存在的隐患实例
module top
(
	input	clk,
	input	rst_n,
	input	a,
	
	output	reg	b,
	output	reg	c
	
);


always@(posedge	clk or negedge rst_n)
begin
	if(!rst_n)
		b <= 1'b0;
	else
		b <= a;
end
always@(posedge	clk or negedge rst_n)
begin
	if(!rst_n)
		c <= 1'b0;
	else
		c <= b;
end

endmodule

在这里插入图片描述
  正常情况下,在clk 的上升沿将c的值更新为b,b的值更新为a。一但进入复位,b,c都清零,但是并不能确定复位信号rst_n会在什么时候结束。
涉及到 建立时间和保持时间 参考博客:建立时间和保持时间
在这里插入图片描述

在这里插入图片描述
  如果结束于b_reg和c_reg的{latch edge-setup,latch edge+hold time}时间之外,那么一切都会正常。如果出现在之内,复位信号的撤销(由低变高)出现在clk锁存数据的建立时间或者保持时间之内,此时clk检测到rst_n的状态就会是一个亚稳态(不确定是0还是1),就会导致输出数据的错误。
  也有可能一个reg处于复位,另一个reg跳出了复位,均会影响系统的正常工作,如果更大的项目隐患就更大了。

3、异步复位、同步释放

  为了消除亚稳态的产生,利用两个同一时钟沿触发的层叠寄存器,将异步信号同步化:

//异步复位、同步释放
module top
(
	input	clk,
	input	rst_n,
	input	a,
	
	output	reg	b
	
);
reg	rst_n_r;
reg	rst_n_rr;

always@(posedge	clk)
begin
	{
    
    rst_n_rr,rst_n_r} <= {
    
    rst_n_r,rst_n};
end

always@(posedge	clk or negedge rst_n_rr)
begin
	if(!rst_n_rr)
		b <= 1'b0;
	else
		b <= a;
end

endmodule

在这里插入图片描述

★★★如有错误,欢迎指导!!!

猜你喜欢

转载自blog.csdn.net/qq_40147893/article/details/117066887