在ASIC中使用许多local rst来避免过长的复位信号路径延时。但在FPGA中,全局网络为复位信号提供了低skew的路径,并且贯穿整个器件。
0、同步复位与异步复位
- 同步复位是指在时钟的上升沿去检查复位信号,如果复位信号有效则复位寄存器。
如下图所示,时钟上升沿时,若复位信号有效时(高电平),s_cnt寄存器组被赋值11’h400,否则赋值取决于其他组合逻辑。
优点:同步复位信号可进行静态时序分析,若无时序违例则可以确保系统可以稳定复位。由于复位有效必须大于一个时钟周期,因此可以过滤掉信号噪声。
缺点:根据网上多数说法:由上图可见,寄存器组的复位端口SCLR悬空,没有充分利用寄存器本身独立复位的优势,而额外地引入了选择器进行复位。浪费资源。但是根据我的实验,即使RTL图中使用选择器来进行复位,但是在布局布线后的map图中,复位信号直接连接到了SCLR端口。对比之下同步复位与异步复位消耗掉的LUT数目相同。这是依靠Intel FPGA 中LAB的特殊架构保证的:The method relies on dedicated routing in the LAB to each register, but this is slower than an asynchronous reset to the same register. - 异步复位是指,寄存器的复位与时钟边沿无关,当复位信号有效时无条件复位寄存器,用到了寄存器的专用复位端口。特点与同步复位相反,无法进行时序分析。
1、异步复位信号亚稳态的原因:
复位结束也就是释放的时刻恰在时钟上升沿的建立时间和保持时间之间时无法决定现在的复位状态是1还是0,造成亚稳态。会导致FPGA诸多寄存器中有的成功复位了,有的没有复位,从而导致复位失败。
下面是具体解释:
在带有复位端的D触发器中,当reset信号“复位”有效时,它可以直接驱动最后一级的与非门,令Q端“异步”置位为“1”or“0”。这就是异步复位。当这个复位信号释放时,Q的输出由前一级的内部输出决定。
然而,由于复位信号不仅直接作用于最后一级门,而且也会做为前级电路的一个输入信号,因此这个前一级的内部输出也受到复位信号的影响。前一级的内部电路实际上是实现了一个“保持”的功能,即在时钟沿跳变附近锁住当时的输入值,使得在时钟变为高电平时不再受输入信号的影响。对于这一个“维持”电路,在时钟沿变化附近,如果“reset”信号有效,那么,就会锁存住“reset”的值;如果reset信号释放,那么这个“维持”电路会去锁当时的D输入端的数据。因此,如果reset信号的“释放”发生在靠时钟沿很近的时间点,那么这个“维持”电路就可能既没有足够时间“维持”住reset值,也没有足够时间“维持”住D输入端的值,因此造成亚稳态,并通过最后一级与非门传到Q端输出。如果reset信号的“释放”时间能够晚一点点,也就是说,让“维持”电路有足够的时间去锁住“reset”的值,那么,我们就可以肯定输出为稳定的“reset”状态了。这一小段锁住“reset”值所需要的时间,就是寄存器的removal time要求。
2、实例解释:
如图第一个方框内是异步复位和同步释放电路。有两个D触发器构成。第一级D触发器的输入时VCC,第二级触发器输出是可以异步复位,同步释放后的复位信号。
-
1)电路目的:防止复位信号撤除时产生亚稳态事件。
-
2)什么是异步复位和同步释放:是指复位信号是异步有效的,即复位的发生与clk无关。后半句“同步释放”是指复位信号的撤除也与clk无关,但是复位信号是在下一个clk来到后起的作用(释放)。
-
下面说明一下如何实现异步复位和同步释放的。
异步复位:显而易见,rst_async_n异步复位后,rst_sync_n将拉低,即实现异步复位。
同步释放:即当复位信号rst_async_n撤除时,由于双缓冲电路(双寄存器)的作用,rst_sync_n复位信号不会随着rst_async_n的撤除而撤除。
假设rst_async_n撤除时发生在clk上升沿,如果不加此电路则可能发生亚稳态导致复位失败事件。但是加上此电路以后:假设rst_async_n撤除时机在clk上升沿附近,则D触发器1输出高电平“1”,此时第二级触发器也会更新输出,但是输出值为前一级触发器clk来之前时的Q1输出状态。显然Q1之前为低电平,故第二级触发器输出保持复位低电平,直到下一个clk来之后,才随着变为高电平。即同步释放。
3、实现代码
module reset_gen ( output rst_sync_n, input clk, rst_async_n);
reg rst_s1, rst_s2;
wire rst_sync_n ;
always @ (posedge clk, posedge 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; //注意这里的rst_sync_n才是我们真正对系统输出的复位信号
endmodule
4、时序约束
- 为了最小化亚稳态对异步复位信号同步器的影响,同步器中的两个DFF应该被放置的足够近,可以采用逻辑锁将他们锁定在一个LAB中,FPGA输入的异步复位信号必须进行时序约束:
set_false_path -from [get_ports {rst_sync_n}] -to [all_registers]
- 该电路确保异步复位同步后的长度至少为一个完整的时钟周期。 要将这个时间延长到n个时钟周期,必须将同步寄存器的数量增加到n +1。必须将异步输入复位(rst_sync_n)连接到所有同步寄存器的CLRN引脚。
- 经过同步的复位信号不能再set_false_path,其需要进行recovery and removal的分析。
- xilinx的例程对复位信号做如下时序约束
# To keep the synchronizer registers near each other
set_max_delay -from [get_cells rst_gen_i0/reset_bridge_clk_rx_i0/rst_meta_reg] -to [get_cells rst_gen_i0/reset_bridge_clk_rx_i0/rst_dst_reg] 2.000
set_max_delay -from [get_cells rst_gen_i0/reset_bridge_clk_tx_i0/rst_meta_reg] -to [get_cells rst_gen_i0/reset_bridge_clk_tx_i0/rst_dst_reg] 2.000
set_max_delay -from [get_cells rst_gen_i0/reset_bridge_clk_samp_i0/rst_meta_reg] -to [get_cells rst_gen_i0/reset_bridge_clk_samp_i0/rst_dst_reg] 2.000
set_false_path -from [get_ports rst_pin]
参考:
https://www.cnblogs.com/qidaiymm/p/4959445.html
Quartus handbook