Fork me on Gitee

(6)同步复位异步释放电路

一、复位电路

  时序电路为双稳态电路,因此必须要有复位信号,而组合电路没有存储功能,因此不需要复位信号

  电路中的复位有两种形式:

  1.同步复位

  敏感列表中只有时钟信号没有复位信号

  2.异步复位

  敏感列表中不仅有时钟而且有复位信号

  为避免在释放时产生亚稳态问题,一般采用同步复位,异步释放的电路

二、同步复位,异步释放电路

  verilog代码如下:

module Rst_gen (
    input      clk,
    input      rst_async_n,
    output reg rst_sync_n
);

reg rst_s1;

always @(posedge clk or negedge rst_async_n) begin
   if(!rst_async_n) begin
       rst_s1     <= 1'b0;
       rst_sync_n <= 1'b0;
   end
   else begin
       rst_s1     <= 1'b1;
       rst_sync_n <= rst_s1;
   end
end

endmodule

  电路图如下:

  异步复位:复位信号不受时钟信号影响,在任意时刻只要低电平就可以复位。在图中第一个方框中,当rst_async_n有效时,第一个D触发器输出的为低电平,第二个D触发器输出的rst_sync_n也是低电平,第二个方框中的异步复位端口有效,输出被复位

  同步释放:让复位信号取消时必须和时钟同步,即和时钟同沿。在上图中假如rst_async_n信号撤销时发生在时钟上升沿,那么不加第一个框中的电路可能发生亚稳态事件,但加上此电路后,假如rst_async_n在时钟上升沿撤销,那么第一个D触发器的输出可能为高电平,可能为亚稳态,也可能为低电平,但此时第二级D触发器不会立刻更新输出的值,保持在之前第一级的输出(即低电平),在下一个时钟上升沿到来时,才随之变为高电平(因为此时第一级的输出已经恢复)

  Q:为什么图中第一级的输入是连接的电源而不是rst_async_n?

  A:如果连接的是rst_async_n,则综合出的电路图如下:

  如果链接的是电源,则电路图如下:

  显然第二种方法好,因为复位信号本身是高扇出信号,采用第二种设计可以减少复位信号的扇出数,同时直接连接电源也可以节省资源,保证电路性能良好

  注意:即使复位信号的脉冲小于一个时钟周期,且在一个时钟周期内完成了异步复位,这种电路还是能正确捕捉复位信号,并且输出一个比时钟周期长的复位信号(图中考虑了触发器的延时)

  如果第一级触发器的复位时钟偏移比第二级大,并且在时钟上升沿附近才释放复位信号(这里感觉图画的有问题),那么在T1时刻第一级的输出可能出现亚稳态、高电平或者低电平,但此时第二级的输出已经复位,为第一级输出复位时的信号(低电平),在T2时刻由于前一级寄存器输出不确定,因此第二级的输出rst_o可能保持有效,也可能撤离,如果T2时刻rst_o还是为复位电平,那么在T3时刻电路输出的复位电平就一定会撤离

  因此,这也就意味着该电路输出的复位信号在撤离时可能会有一个时钟周期的偏差,可能造成时序混乱

  解决:首先用两级寄存器对复位信号进行同步,得到根复位信号后再用复位同步电路进行分发由于同步后的根复位信号不会产生亚稳态问题,因此在分发根同步复位信号后再次分发两级寄存器,这样分发后的子复位网络是相互独立的,且扇出输出比跟复位网络要小很多,

  扩展:多时钟域下的异步复位同步释放电路

  1.非协调的复位撤销

  即使用每个时钟搭建自己的复位同步器

  代码如下:

module CLOCK_RESET(
       input rst_n,
     input aclk,
     input bclk,
     input cclk,
     output reg  arst_n,
     output reg  brst_n,
     output reg  crst_n
       );


reg arst_n0,arst_n1;
reg brst_n0,brst_n1;
reg crst_n0,crst_n1;


always @(posedge aclk or negedge rst_n) 
  if(rst_n==0) begin
    arst_n0<=1'b1;
   arst_n1<=1'b0;
   arst_n<=1'b0;
  end
  else begin
    arst_n<=arst_n1;
    arst_n1<=arst_n0;
  end  
  
always @(posedge bclk or negedge rst_n) 
  if(rst_n==0) begin
    brst_n0<=1'b1;
   brst_n1<=1'b0;
   brst_n<=1'b0;
  end
  else begin
    brst_n<=brst_n1;
    brst_n1<=brst_n0;
  end  
     
    
always @(posedge cclk or negedge rst_n) 
  if(rst_n==0) begin
    crst_n0<=1'b1;
   crst_n1<=1'b0;
   crst_n<=1'b0;
  end
  else begin
    crst_n<=crst_n1;
    crst_n1<=crst_n0;
  end  
   
endmodule

  2.顺序协调的复位撤销

  当多个时钟域对复位释放有顺序要求时,将复位同步器级联起来就可以构成多个时钟域按顺序进行同步释放

  代码如下:

module CLOCK_RESET(
       input rst_n,
     input aclk,
     input bclk,
     input cclk,
     output reg  arst_n,
     output reg  brst_n,
     output reg  crst_n
       );


reg arst_n0,arst_n1;
reg brst_n0,brst_n1;
reg crst_n0,crst_n1;


always @(posedge aclk or negedge rst_n) 
  if(rst_n==0) begin
    arst_n0<=1'b1;
   arst_n1<=1'b0;
   arst_n<=1'b0;
  end
  else begin
    arst_n<=arst_n1;
    arst_n1<=arst_n0;
  end  
  
always @(posedge bclk or negedge rst_n) 
  if(rst_n==0) begin
   brst_n1<=1'b0;
   brst_n<=1'b0;
  end
  else begin
    brst_n<=brst_n1;
    brst_n1<=arst_n;
  end  
     
    
always @(posedge cclk or negedge rst_n) 
  if(rst_n==0) begin
   crst_n1<=1'b0;
   crst_n<=1'b0;
  end
  else begin
    crst_n<=crst_n1;
    crst_n1<=brst_n;
  end  
     
     
endmodule

Reference:

深入理解复位---同步复位,异步复位,异步复位同步释放(含多时钟域)_画出支持异步复位dff的电路图-CSDN博客

数字电路复位信号设计(异步复位、同步释放)笔记详解_异步复位同步释放的高有效原理-CSDN博客

posted @ 2024-06-11 12:36  数字ic新人  阅读(5)  评论(0编辑  收藏  举报