我是靠谱客的博主 爱笑电灯胆,最近开发中收集的这篇文章主要介绍复位策略:同步复位与异步复位,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

在IC设计种,复位策略分为同步复位和异步复位两种设计,根据不同的设计,会采用不同的复位方式。

复位的文章已有很多文章讲解了,这里只讨论实现策略。

 一、异步复位

1、优点:

1)无需额外的逻辑资源,实现简单,可以保证复位引脚到各个寄存器的时钟偏移最小;

2)复位信号不依赖时钟;

2、缺点:

1)复位信号易受到外界干扰,并且对电路内部的毛刺敏感;

2)复位信号的随机性,可能产生时序违规并导致电路处于亚稳态;

3、代码设计:

假设外部复位时钟信号为clk_o,复位信号为rst_n_hw。这个复位信号,我们不能直接应用于异步复位寄存器中。需要对其进行处理后,再进行使用。分析如下:

1)先对rst_n_hw进行第一次处理,产生“异步复位、同步释放”复位信号rst_n_sync;

这样方式,是在异步复位中,为了避免时序问题,必然要使用的。

其实,这种策略就是利用了同步复位和异步复位折中的方式。复位电路中的寄存器同步异步复位,全部功能寄存器同时复位,与时钟异步发生;当复位信号释放,位于这个区域的时钟在功能触发器脱离复位前必须连续触发两次以上,以避免亚稳态问题。

reg rst_sync0_n ,rst_sync1_n ,rst_sync1_n ;

asisgn rst_n_sync = rst_sync2_n ;

always @(posedge clk_o or negedge rst_n_hw)
    if(~rst_n_hw) begin
        rst_sync0_n <= 1'b0;
        rst_sync1_n <= 1'b0;
        rst_sync2_n <= 1'b0;
    end
    else begin
        rst_sync0_n <= 1'b1;
        rst_sync1_n <= rst_sync0_n ;
        rst_sync2_n <= rst_sync1_n ;
    end

2、将处理后的reset信号,再作用于各个寄存器,如:

reg [3:0] data_out1 ,data_out2 ;


always @(posedge clk_o or negedge rst_n_sync)
begin
    if(~rst_n_sync )
        data_out1 <= 4'h0;
    else
        data_out1 <= data_in1[3:0];
end

always @(posedge clk_o  or negedge rst_n_sync)
begin
    if(~rst_n_sync )
        data_out2 <= 4'h0;
    else
        data_out2 <= data_in2[3:0];
end

二、同步复位

1、优点:

1)抗干扰性强,可以剔除复位信号种周期短于时钟周期的毛刺;

2)所有的功能触发器的复位信号完全同步于时钟源;从而确保了该时钟和reset作用下的逻辑电路的启动工作的一致性,避免因为复位和时钟的关系异步,造成的启动不一致(例如:错位一个时钟周期。如果都是控制计数器工作,这些计数器工作是同时的;如果为异步复位,这些计数器工作可能会不同时工作,这样就需要利用其它逻辑来保证其同时工作)

3)有利于静态时序分析工具的分析;

4)有利于基于周期的仿真工具的仿真。

2、缺点:

1)占用更多的逻辑资源;

2)对复位信号的脉冲宽度有要求,必须大于指定的时钟周期,且很难保证复位信号到达各个寄存器的时序;

3)复位信号依赖于时钟,如果电路中的时钟信号出现问题,则无法完成复位。

3、代码设计:

假设外部复位时钟信号为clk_o,复位信号为rst_n_hw。这个复位信号,我们不能直接应用于同步复位寄存器中。需要对其进行处理后,再进行使用。分析如下:

1)先对rst_n_hw同步处理:因为该reset将要引入到clk_o同步时钟域中,而且会当作普通的信号使用,此时必须做跨时钟域处理后,在进行使用:

注意:1.1)可以看出使用同步复位时,需要保证在复位时,需要有时钟的存在而且需要大于时钟周期,否则复位信号无法被捕获到该逻辑中。

          1.2)在时钟存在时,reset才会有作用;在上电复位时,在时钟未开启时,所以的逻辑都处于未知状态;只有时钟到来后,reset才会起作用,最终进入到复位状态;等到复位释放,整个电路逻辑,进入正常工作状态。

reg rst_sync0_n ,rst_sync1_n ,rst_sync1_n ;

asisgn rst_n_sync = rst_sync2_n ;

always @(posedge clk_o)
begin
        rst_sync0_n <= rst_n_hw;
        rst_sync1_n <= rst_sync0_n ;
        rst_sync2_n <= rst_sync1_n ;
end

2、将同步后的reset信号,再作用于各个寄存器,如:

reg [3:0] data_out1 ,data_out2 ;


always @(posedge clk_o)
begin
    if(~rst_n_sync )
        data_out1 <= 4'h0;
    else
        data_out1 <= data_in1[3:0];
end

always @(posedge clk_o)
begin
    if(~rst_n_sync )
        data_out2 <= 4'h0;
    else
        data_out2 <= data_in2[3:0];
end

最后

以上就是爱笑电灯胆为你收集整理的复位策略:同步复位与异步复位的全部内容,希望文章能够帮你解决复位策略:同步复位与异步复位所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部