数字电路的复位可分为哪些

描述

1、复位的重要性

数字电路中寄存器和 RAM 在上电之后默认的状态和数据是不确定的,如果有复位,我们可以把寄存器 复位到初始状态 0,RAM 的数据可以通过复位来触发 RAM 初始化到全 0。那可能很多人会问为什么是全 0呢?其实一般逻辑起始都是从 0 开始变化的,这个是根据设计的需要设定的一个值,如果设计需要寄存器 上电复位为 1,也是可以的。还有一种情况是逻辑进入了错误的状态,通过复位可以把所有的逻辑状态恢复 到初始值,如果没有复位,那么逻辑可能永远运行在错误的状态。

因此复位功能是很重要的一个功能。数字电路的复位通常可分为:同步复位与异步复位。

2、同步复位

同步复位:同步复位指的是当时钟上升沿检测(有效沿)到复位信号,执行复位操作,有效的时钟沿是前提。

Verilog代码:

//*******************同步复位模块**************************

//-----------端口定义-------------------------------

modulerst_test(

 inputclk,//工作时钟

 inputrst_n,//复位,低电平有效

 inputin,//输入信号

 outputregout//输出信号

);

//-----------输出模块-------------------------------

always@(posedge clk )begin

 if(!rst_n)

  out <= 1'b0;//复位将输出置零

 else

  out <= in;//其他时候将输入赋值给输出

end 

endmodule

使用Quartus II综合出的RTL如下:

寄存器

可以看到,生成的触发器并没有复位置位端,而是生成了一个选择器,同步复位信号rst_n用作了选择器的使能,从而实现复位清零的作用。

用如下Testbench进行仿真(复位时间不足一个时钟周期、复位时间超过一个时钟周期、一个高频复位毛刺):

//------------------------------------------------

//--同步复位仿真

//------------------------------------------------

`timescale 1ns/1ns//时间单位/精度

//------------<模块及端口声明>----------------------------------------

module tb_rst_test();

reg clk;

reg rst_n;

regin;

wireout;

//------------<例化被测试模块>----------------------------------------

rst_testrst_test_inst(

 .clk(clk),

 .rst_n(rst_n),

 .in(in),

 .out    (out)

);

//------------<设置初始测试条件>----------------------------------------

initial begin

 clk = 1'b0;     

 rst_n <= 1'b0;

 in <= 1'b1;

 #5       

 rst_n <= 1'b1;

 #6       

 rst_n <= 1'b0; 

 #18       

 rst_n <= 1'b1;

 #39       

 rst_n <= 1'b0;

 #21       

 rst_n <= 1'b1;

 #25       

 rst_n <= 1'b0;

 #3       

 rst_n <= 1'b1; 

end

//------------<设置时钟>----------------------------------------------

always #10 clk = ~clk;//系统时钟周期20ns

endmodule

仿真结果如下:

寄存器

 从仿真结果可以看到:

第1个复位时间不足一个时钟周期,导致复位不成功 

第2个复位时间超过一个时钟周期,复位成功

最后一个复位信号上的高频毛刺信号没有对系统造成误复位

输出信号在第一个时钟上升沿到来之前是未知状态 

同步复位电路的优点:

有利于仿真器的仿真

基本上没有亚稳态问题

可以使所设计的系统成为 100%的同步时序电路,有利于时序分析

由于只在时钟有效电平到来时才有效,所以可以滤除高于时钟频率的复位毛刺

同步复位电路的缺点:

复位信号的有效时长必须大于时钟周期,才能真正被系统识别并完成复位任务。同时还要考虑延时因素

大多数的FPGA的DFF都只有异步复位端口,采用同步复位的话,综合器就会在寄存器的数据输入端口插入组合逻辑,这样会耗费逻辑资源

3、异步复位

异步复位:异步复位指的是无论时钟沿是否到来,只要复位信号有效,就对系统进行复位。当时钟上升沿检测到复位信号,执行复位操作。

Verilog代码:

//*******************同步复位模块**************************

//-----------端口定义-------------------------------

modulerst_test(

 inputclk,//工作时钟

 inputrst_n,//复位,低电平有效

 inputin,//输入信号

 outputregout//输出信号

);

//-----------输出模块-------------------------------

always@(posedge clk or negedge rst_n)begin

 if(!rst_n)

  out <= 1'b0;//复位将输出置零

 else

  out <= in;//其他时候将输入赋值给输出

end 

endmodule

使用Quartus II综合出的RTL如下:

寄存器

 可以看到,异步复位信号rst_n直接接入了触发器的异步复位端,从而实现复位清零的作用。

依然使用之前用的Testbench进行仿真,结果如下:

寄存器

从仿真结果可以看到:

只要复位信号被置为低电平,就执行复位操作,与时钟无关

高频毛刺信号会对系统造成误复位

在不考虑亚稳态的前提下,复位时间没有要求 

       a、在复位信号释放(release)的时候容易出现问题。具体就是说:倘若复位释放时恰恰在时钟有效沿附近,就很容易使寄存器输出出现亚稳态,从而导致亚稳态。

       b、复位信号容易受到毛刺的影响

异步复位电路的优点:

大多数目标器件库的dff都有异步复位端口,因此采用异步复位可以节省资源

设计相对简单,异步复位信号识别方便,而且可以很方便的使用FPGA的全局复位端口GSR

异步复位电路的缺点:

复位信号容易受到毛刺的影响

因为是异步逻辑,无法避免地存在亚稳态问题

        关于异步复位还需要考虑:

        恢复时间(Recovery Time)是指异步控制信号(如寄存器的异步清除和置位控制信号)在“下个时钟沿”来临之前变无效的最小时间长度。这个时间的意义是,如果保证不了这个最小恢复时间,也就是说这个异步控制信号的解除与“下个时钟沿”离得太近(但在这个时钟沿之前),没有给寄存器留有足够时间来恢复至正常状态,那么就不能保证“下个时钟沿”能正常作用,也就是说这个“时钟沿”可能会失效。

        去除时间(Removal)是指异步控制信号(如寄存器的异步清除和置位控制信号)在“有效时钟沿”之后变无效的最小时间长度。这个时间的意义是,如果保证不了这个去除时间,也就是说这个异步控制信号的解除与“有效时钟沿”离得太近(但在这个时钟沿之后),那么就不能保证有效地屏蔽这个“时钟沿”,也就是说这个“时钟沿”可能会起作用。

        换句话来说,如果你想让某个时钟沿起作用,那么你就应该在“恢复时间”之前是异步控制信号变无效,如果你想让某个时钟沿不起作用,那么你就应该在“去除时间”过后使控制信号变无效。如果你的控制信号在这两种情况之间,那么就没法确定时钟沿是否起作用或不起作用了,也就是说可能会造成寄存器处于不确定的状态。而这些情况是应该避免的。所以恢复时间和去除时间是应该遵守的。

4、异步复位、同步释放

        结合两种复位的优点,可以使用异步复位、同步释放设计,Verilog代码如下:

//*******************同步复位模块**************************

//-----------端口定义-------------------------------

modulerst_test(

 inputclk,//工作时钟

 inputrst_n,//复位,低电平有效

 inputin,//输入信号

 outputregout//输出信号

);

//-----------reg定义-------------------------------

reg arst_n_r;

reg arst_n;

//-----------复位信号同步模块-------------------------------

always@(posedge clk or negedge rst_n)begin

 if(!rst_n)begin

  arst_n_r <= 1'b0;//复位将输出置零

  arst_n <= 1'b0;//复位将输出置零 

 end

 else begin

  arst_n_r <= 1'b1;//跟接rst_n是一样的,都是逻辑1

  arst_n <= arst_n_r;  

 end

end

//-----------输出模块-------------------------------

always@(posedge clk or negedge arst_n)begin

 if(!arst_n)

  out <= 1'b0;    //复位将输出置零

 else

  out <= in;    //其他时候将输入赋值给输出

end 

endmodule

综合出来的RTL视图:

寄存器

 实际的电路图如下:

寄存器

复位信号 rst_sync_n 由高拉低时实现 y 寄存器的异步复位。同步释放,这个是关键,即当复位信号 rst_async_n 撤除时(由低拉高),由于双缓冲电路(双触发器)的作用,rst_sync_n 不会随着rst_async_n 的 撤除而撤除。假设 rst_async_n 撤除时发生在 clk 上升沿,如果不加此电路则可能发生亚稳态事件,但是加上此电路以后,假设第一级 D 触发器 clk 上升沿时 rst_async_n 正好撤除,(第一个 DFF 此时是处于亚稳态 的;假设此时识别到高电平;若是识别到低电平,则增加一个 Delay)则 DFF1 输出高电平,此时第二级触发器也会更新输出,但是输出值为前一级触发器 clk 来之前时的 Q1 输出状态,显然 Q1 之前为低电平,所以第二级触发器输出保持复位低电平,直到下一个 clk 来之后,才随着变为高电平,即同步释放。 

 使用如下Testbench进行仿真:


//------------------------------------------------
//--同步复位仿真
//------------------------------------------------
`timescale 1ns/1ns//时间单位/精度

//------------<模块及端口声明>----------------------------------------
module tb_rst_test();

reg clk;
reg rst_n;
regin;

wireout;

//------------<例化被测试模块>----------------------------------------
rst_testrst_test_inst(
.clk(clk),
.rst_n(rst_n),
.in(in),

.out    (out)
);

//------------<设置初始测试条件>----------------------------------------
initial begin
clk = 1'b0;
rst_n <= 1'b0;
in <= 1'b1;
#25
rst_n <= 1'b1;
#6
rst_n <= 1'b1;
#18
rst_n <= 1'b1;
#39
rst_n <= 1'b0;
#21
rst_n <= 1'b1;
end
//------------<设置时钟>----------------------------------------------
always #10 clk = ~clk;//系统时钟周期20ns

endmodule
仿真结果如下:

寄存器



可以看到:复位是异步进行的,一旦复位信号为低电平,则输出复位,而复位的撤除则被同步到了时钟域下。如此一来,既解决了同步复位的资源消耗问题,也解决了异步复位的亚稳态问题。其根本思想,也是将异步信号同步化。 

声明:   本文转载自csdn:孤独的单刀,如涉及作品内容、版权和其它问题,请于联系工作人员微(in0723mango),我们将在第一时间和您对接删除处理! 投稿/招聘/广告/课程合作/资源置换 请加微信:13237418207

寄存器

Xilinx FPGA的约束设计和时序分析总结

寄存器

  
      审核编辑:彭静
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分