项目场景:
提示:对于FPGA触发器而言,采用异步复位无需增加额外的资源开销。但是异步复位有个致使的缺点:复位信号的释放。
例如:
异步复位:
它是指无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。用Verilog描述如下
module rst(
input clk,
input rst_n,
input data_in,
output reg out
);
always @ (posedge clk or negedge rst_n)
if(!rst_n) out <= 1'b0;
else out <= data_in;
endmodule
异步复位带来的问题:
如下图所示二级触发器,在正常情况下,一旦复位信号有效,b、c都会清零,但是复位信号的释放时间是不确定的:
如果复位的释放发生在系统时钟的{setup_time,hold_time}之外,那么复位的释放就一切正常;但如果发生在之内,那么时钟信号检测到rst_n就是亚稳态信号,也就不确定是0还是1,此时两个触发器如果对rst_n的值判断不一致(比如b认为是0而继续保持复位而c认为是1释放复位),则系统必然会出问题。两个触发器尚且可能会出现问题,对于较大的系统设计中的千千万万个触发器,其后果会不堪设想。
同步复位:
顾名思义,同步复位就是指复位信号只有在时钟上升沿到来时,才能有效。否则,无法完成对系统的复位工作。。
module rst(
input clk,
input rst_n,
input data_in,
output reg out
);
always @ (posedge clk )
if(!rst_n) out <= 1'b0;
else out <= data_in;
endmodule
异步复位,同步释放:
提示:一般来说,同步系统,都使用异步复位。这是因为同步复位的电路实现,比异步复位的电路实现,要浪费更多电路资源。
未在本模块时钟域做过“异步复位,同步释放”处理的复位信号,提供给本模块做异步复位使用时,都需要做“异步复位,同步释放”处理。常见于系统内两部件不在同一时钟域的情况下。
always @ (posedge clk, negedge rst_async_n)
if (!rst_async_n) begin
rst_s1 <= 1'b0;
rst_s2 <= 1'b0;
end
else begin
rst_s1 <= 1'b1;
rst_s2 <= rst_s1;
end
assign rst_sync_n = rst_s2;
endmodule
的时候容易出现问题。具体就是说:倘若复位释放时恰恰在时钟有效沿附近,就很容易使寄存器输出出现亚稳态,从而导致亚稳态。
b、复位信号容易受到毛刺的影响。