Reset信号如何同步?

首先来复习一个更加基础的概念:同步reset和异步reset。

同步reset(synchronous reset)是说,当reset信号为active的时候,寄存器在下一个时钟沿到来后被复位,时钟沿到来之前寄存器还是保持其之前的值。

异步reset(asynchronous reset)是说,当reset信号为active的时候,寄存器立刻被复位,与时钟沿到来与否没有关系。

注意这里作者没有说reset信号为1的时候,而是说active,因为有的时候是为1能够使寄存器复位,这个时候我们说high active,而有的时候是0能够使得寄存器复位,这个时候我们说low active。

同步reset和异步reset的区别算是数字芯片设计的入门知识点,一般第一轮面试就会考察,如果这个问题回答的不好,那么大概率会被面试官认为一般,无论是初学还是工作几年的工程师,很有可能不注意这些基本功,但是基本功在数字芯片设计中的非常重要的。

首先同步reset和异步reset最主要的区别,从定义上就可以看出来,同步reset需要时钟,而异步reset不需要时钟,如果说你的模块需要在没有时钟的时候复位,那只有异步reset能够做到,这也是绝大多数芯片的上电复位信号(Power Reset)以及一些PHY比如USB的内部需要异步reset的原因,而在一些IP中,如果你可以等到时钟开始反转之后再复位,时钟开始翻转之前内部即使没有复位也没有关系的话,那么就可以用同步reset。

其次一个差别,即同步reset信号在综合后,reset信号和其他的datapath信号一样,时一起算在两个寄存器之间的logic深度里,D寄存器本身时没有复位的pin的,而异步reset信号通常会综合出一个带有 复位pin的D寄存器,一般来说工艺厂家的standard cell library都会提供两种不同的寄存器,只要你的coding style正确,综合工具会选择适当的flop。

上图是同步reset综合出来之后的netlist,可以看出reset_n使得两级寄存器之间的组合逻辑多加了一个AND门。

always_ff @(posedge clk) begin
  if (!reset_n) begin
     q2 <= 1'b0;
  end
  else begin
    // q2 <= ...
  end
end

对于异步reset,综合出来的flop自带reset pin,所以reset不参与中间的组合逻辑,如下图D2所示。

always_ff @(posedge clk or negedge reset_n) begin
  if(!reset_n) begin
    q2 <= 1'b0;
  end
  else begin
    //q2 <= ...
  end
end

同步reset劣势】从综合出来的逻辑可以看出,异步reset由于对寄存器之间的datapath没有贡献,所以在timing上面能够略微比同步reset好一些,特别是reset信号作为一个负载很大的信号,如果reset tree做得不好可能使得reset path的combo delay变得很大,反而限制了performance的提高,所以在对logic depth抠得很细的设计中,可以使用异步reset来避免引入更多的combo delay。

但是同步reset还有一个优势,由于reset信号会最终起作用在寄存器的D输入端,那么通过reset的组合逻辑都会被STA所约束,也就是说reset信号和其他datapath的信号一起要满足寄存器的setup time,hold time,min pulse等一系列check,在timing close的情况下我们可以拍着胸脯保证:寄存器不会因为reset的变化产生metastable(所以同步reset信号的跨时钟域咱们就不废话了)可是对于异步reset就没有那么简单了,既然是异步,那就是在任何时候都可能变化,现在STA所以叫static timing anslysis,是因为工具是静态分析电路的:给定一个时钟沿的起始点,然后后面每一级的delay都是纯粹的累加,晚到就是violation,可是如果一个信号什么时候来都无法确定,那么就无法判断这个信号的datapath上最后能否满足required time,换句话说,纯粹的异步reset在当前STA check中是没有办法检查的。

那么怎么办呢?难道对于异步reset信号就听之任之放任不管吗?当然不是,我们做IC设计的,当然要对每一个细节都要研究清楚,我们这里要分两种情况:1:reset assertion;2:reset release。好,直接上结论!

如果使用异步reset,reset assertion是异步的,但是reset release一定是和时钟同步的 

因为对于reset assertion,reset active之后flop的值是稳定在reset value的,只要reset急促active,来多少个clcok,其他datapath上的信号怎么变,flop的值都不会变化,所以reset在什么时候assertion都没有关系,但是reset release就不一样了,一旦reset从active de-assertion,在STA里有两个专门的参数来check,叫做recovery time和removal time。

recovery time和removal time的意义请异步:

什么是寄存器的recovery time和removal time?_recover time-CSDN博客

换句话说,reset release必须在recovery time和removal time加起来这个窗口之外就保持稳定,这样才能保证寄存器不会产生metastable。

好,下面的问题就变成了,我们如何设计可以使得异步reset信号是异步assertion,同步 release呢?终于要引出本文的主题了,将一个异步的reset信号同步到一个时钟域,并且还要保证assertion是异步的,但是release是同步于这个时钟的,我们把这样的电路叫做reset synchronizer,如下图所示。

可以看到,当src_reset_n asset时,两个flop被异步reset,他们的Q会经过reset-to-q的延时之后立刻发生变化,使得dst_reset_n assert。

而当src_reset_n release 后,dst_reset_n并不是立刻发生变化,而是要等dst_clk的时钟沿,并且打两拍之后才能将1传递到dst_reset_n,因为dst_reset_n是来自flop的Q,而Q是经过dst_clk上的同步信号,那么为什么要两级flop,还是为了减小产生metastable的概率。

这里还要注意一点就是上述只是对reset_n release做了到dst_clk的同步,如果dst_clk 的频率很高,recovery time和removal time不能meet怎么办呢?

一般的处理是对高频时钟抹沿——把高频在复位时降为低频。用低频时钟的同步复位信号去对DFF进行异步复位,那么就要对该复位DFF的CP端到 DATA_PATH上DFF的CD端进行约束。同时对复位DFF本身进行约束。

约束方法为对DFF进行MCP约束。

#set mcp from the reset register
set_multicycle_path x -setup -from {get_pins DFF/CP}
set_multicycle_path x-1 -hold  -from {get_pins DFF/CP}
#remove mcp from the reset flop to itself
set_multicycle_path 1 -setup -from {get_pins DFF/CP} -to {get_pins DFF/D}
set_multicycle_path 0 -setup -hold {get_pins DFF/CP} -to {get_pins DFF/D}

上面两句是对从reset DFF的CP端之后的所有pins进行约束,下面两句是把reset DFF自身的path单独拿出来要按照正常的1 clk period约束。 

文章前面借鉴了:Reset信号 如何同步? 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值