zoukankan      html  css  js  c++  java
  • 总结“异步复位,同步释放”

      复位的功能是很有必要的,让一切正在处于工作状态的器件的状态恢复到初始态,可以起到重新开始工作的作用。复位有上电复位和按键复位两种常见方式。

      先说一下按键复位

      一开始,我们在设计按键复位的逻辑功能时,第一反应就是利用D触发器的异步清零端(clr端),这种方式称为异步复位,代码和RTL图如下:

    1 always@(posedge clk or negedge rst_n)
    2 begin
    3     if(rst_n == 1'b0)
    4         q <= 1'b0;
    5     else
    6         q <= 1'b1;
    7 end                                                                    

     

      

      采取异步复位的方式的优点是不需要额外的资源,直接使用寄存器自带的异步清零端即可。缺点是存在亚稳态状态。

      1. 当clk上升沿到来时,rst_n正好由高电平变为低电平(处于复位状态),这时rst_n具有优先级,寄存器直接进行初始态。

      2. 当clk上升沿到来时,rst_n正好由低电平变为高电平(处于置位状态),这时寄存器是认为rst_n为1,锁存此刻的值a,输出前一个时钟周期的b呢,还是认为rst_n为0,该开始初始化了呢(打架了,造成了亚稳态)

      那这种方式存在问题,我们再来看看同步复位的方式,代码和RTL图如下:

      

    1 always@(posedge clk)
    2 begin
    3     if(rst_n == 1'b0)
    4         q <= 1'b0;
    5     else
    6         q <= 1'b1;
    7 end

      

      1. 当clk上升沿到来时,rst_n正好由高电平变为低电平(处于复位状态),此刻寄存器仅受clk的控制,认为采样到的是rst_n的高电平,继续输出已存数值,下一个时钟周期才认为rst_n是低电平,进行初始化。

      2. 当clk上升沿到来时,rst_n正好由低电平变为高电平(处于置位状态),此刻寄存器仅受clk的控制,认为采样到的是rst_n的低电平,继续初始化,下一个时钟周期才认为rst_n是高电平,输出响应的值。

       但是采取同步复位的方式的虽然能减小亚稳态的发生,但是需要额外的资源。

      异步复位和同步复位都有优缺点,将两者相互结合,互补一下,便出现了“异步复位,同步释放”的方式,很好的解决了两者的不足。代码和RTL图如下: 

     1 module sys_ctrl(
     2     input                clk,
     3     input         rst_n,
     4     output    reg    sys_rst_n
     5 );
     6 
     7 reg    rst_1;
     8 
     9 always@(posedge clk or negedge rst_n)
    10 begin
    11     if(!rst_n == 1'b0)
    12         rst_1 <= 1'b0;
    13     else
    14         rst_1 <= 1'b1;
    15 end
    16 
    17 always@(posedge clk or negedge rst_n)
    18 begin
    19     if(rst_n == 1'b0)
    20         sys_rst_n <= 1'b0;
    21     else
    22         sys_rst_n <= rst_1;
    23 end
    24 
    25 
    26 endmodule    

      

      这样就既利用了异步复位的清零端进行复位,不需要额外开支资源,又利用了同步复位的释放优点,将异步复位的释放电平延迟1个时钟周期,然后再将延迟后的释放电平信号作为系统复位信号,避免了释放时亚稳态的发生。

      下面说一下上电复位

      系统在每次上电复位初始化时,需要消耗很多方面的时间,大体如下:

      1. 电源等芯片的转换时间

      2. FPGA的启动到稳定的时间

      3. 外围电路的启动时间

      所以,为了保证FPGA上电复位后更加的稳定,可以在上电开始后,进行一定的延迟时间来保证FPGA可以达到稳定的状态。综合以上代码如下:

      

     1 module test(
     2     input      clk,
     3     input      rst_n,
     4     output reg   sys_rst_n
     5 );
     6 
     7 parameter    RST_TIME = 24'd2_500_000;                //50ms
     8 
     9 reg        rst_1;
    10 reg    [23:0]  cnt_rst;
    11 
    12 always@(posedge clk or negedge rst_n)
    13 begin
    14     if(rst_n == 1'b0)
    15         cnt_rst <= 24'd0;
    16     else
    17         if(cnt_rst < RST_TIME)
    18             cnt_rst <= cnt_rst +1'b1;                    
    19         else
    20             cnt_rst <= cnt_rst;
    21 end
    22 
    23 always@(posedge clk or negedge rst_n)
    24 begin
    25     if(rst_n == 1'b0)begin
    26         rst_1 <= 1'b0;
    27         sys_rst_n <= 1'b0;
    28     end
    29     else begin
    30         if(cnt_rst == RST_TIME)begin
    31             rst_1 <= 1'b1;
    32             sys_rst_n <= rst_1;
    33         end
    34         else begin
    35             rst_1 <= 1'b0;
    36             sys_rst_n <= 1'b0;
    37         end
    38     end
    39 end
    40 
    41 endmodule

      

     

  • 相关阅读:
    HDU 4611 Balls Rearrangement 数学
    Educational Codeforces Round 11 D. Number of Parallelograms 暴力
    Knockout.Js官网学习(简介)
    Entity Framework 关系约束配置
    Entity Framework Fluent API
    Entity Framework DataAnnotations
    Entity Framework 系统约定配置
    Entity Framework 自动生成CodeFirst代码
    Entity Framework CodeFirst数据迁移
    Entity Framework CodeFirst尝试
  • 原文地址:https://www.cnblogs.com/jayer/p/12343916.html
Copyright © 2011-2022 走看看