NavyC

天空没有留下鸟的痕迹 但我已飞过

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关于异步复位与同步复位的实际举例在上篇博文中已经讲述,这里不在讲述。接下来将分享几个常用的异步复位同步释放的方法。

  1. 用最高时钟将复位信号往后打几拍,如下用两个寄存器实现系统复位

module sync_rst(

sys_clk,

ext_rst_n,

sys_rst_n);

 

input sys_clk;//系统时钟50M

input ext_rst_n;//复位信号

output sys_rst_n;//系统复位信号

 

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

//系统复位信号产生,低有效

//异步复位,同步释放

reg rst_nr1,rst_nr2;

always@(posedge sys_clk ornegedge ext_rst_n)

begin

if(!ext_rst_n)

rst_nr1 <=1'b0;

else

rst_nr1 <=1'b1;

end

 

always@(posedge sys_clk ornegedge ext_rst_n)

begin

if(!ext_rst_n)

rst_nr2 <=1'b0;

else

rst_nr2 <= rst_nr1;

end

 

assign sys_rst_n = rst_nr2;

 

endmodule

 

Quartus II 12.0综合出来的RTL图

 

 

Modelsim 6.5仿真图如下:

从仿真图中可以看出系统复位的信号往后打慢了两个时钟周期。

这样一来既解决了同步复位信号带来的逻辑资源消耗的问题,也解决了异步复位信号出现的亚稳态稳定。

 

  1. 当系统采用PLL时,系统复位信号的设计和上面的设计稍有点不同。Verilog 代码为:

module sync_rst(

sys_clk,

ext_rst_n,

sys_rst_n,

pll_rst

);

 

input sys_clk;//系统时钟50M

input ext_rst_n;//复位信号

output sys_rst_n;//系统复位,低电平有效

output pll_rst;//pll复位,高电平有效

 

wire pll_clk0;

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

//PLL复位信号产生,高有效

//异步复位,同步释放

wire pll_rst;//PLL复位信号,高有效

 

reg rst_r1,rst_r2;

 

always@(posedge sys_clk ornegedge ext_rst_n)

begin

if(!ext_rst_n) rst_r1 <=1'b1;

else rst_r1 <=1'b0;

end

 

always@(posedge sys_clk ornegedge ext_rst_n)

begin

if(!ext_rst_n) rst_r2 <=1'b1;

else rst_r2 <= rst_r1;

end

 

assign pll_rst = rst_r2;

 

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

//系统复位信号产生,低有效

//异步复位,同步释放

wire    rst_nr0;

reg    rst_nr1,rst_nr2;

wire    pll_locked;

assign    rst_nr0 = ext_rst_n & pll_locked;

always@(posedge pll_clk0 ornegedge rst_nr0)

begin

    if(!rst_nr0)

        rst_nr1 <=1'b0;

    else

        rst_nr1 <=1'b1;

end

 

always@(posedge pll_clk0 ornegedge rst_nr0)

begin

    if(!rst_nr0)

        rst_nr2 <=1'b0;

    else

        rst_nr2 <= rst_nr1;

end

 

assign    sys_rst_n = rst_nr2;

 

pll    pll_inst (

    .areset ( pll_rst ),

    .inclk0 ( sys_clk ),

    .c0 ( pll_clk0 ),

    .locked ( pll_locked )

    );

 

endmodule

从代码中可以看出pll先复位,复位完成之后产生的pll_locked和ext_rst_n进行与操作,得到最好的系统复位信号。

 

Quatus II 12.0的RTL图

 

Modelsim 6.5仿真图如下:

 

  1. 最佳的异步复位,同步释放的方法

当FPGA在上电的时候,总是需要一些时间给所有逻辑块上电,即使上电时间非常短暂。在一些时序要求不高的场合,我们将其忽略不计似乎也不会对系统设计有什么影响,但是在某些时序要求比较严谨的场合,这几十纳秒和几十微妙的上电,FPGA系统工作其不稳定。因此提出一种有效的解决办法,就是在异步复位,同步释放的时候将系统延时几百微妙或者几毫秒。这样处理的好处是在FPGA上电后内部稳定后在对逻辑进行操作,系统也更加稳定。工程实践中,延时的值根据需求来定。笔者一般采用延时1ms的时间,Verilog代码如下:

module    sync_rst(

                    sys_clk,

                    ext_rst_n,

                    sys_rst_n,

                    pll_rst,

                    pll_clk0,

                    );

 

input    sys_clk;                //系统时钟50M

input    ext_rst_n;            //复位信号

output    sys_rst_n;        //系统复位,低电平有效

output    pll_rst;            //pll复位,高电平有效

output    pll_clk0;

 

//延时一段时间使系统运行稳定

reg    [15:0]    delay_cnt;

always@(posedge sys_clk)

begin

    if(delay_cnt <16'd50_000)            //50000*20ns=1ms        

        delay_cnt <= delay_cnt +16'h1;

    else

        delay_cnt <= delay_cnt;

end

 

assign    delay_flag =(delay_cnt ==16'd50_000)?1'b1:1'b0;

 

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

//PLL复位信号产生,高有效

//异步复位,同步释放

wire pll_rst;    //PLL复位信号,高有效

 

reg rst_r1,rst_r2;

 

always@(posedge sys_clk ornegedge ext_rst_n)

    if(!ext_rst_n) rst_r1 <=1'b1;

    else rst_r1 <=1'b0;

 

always@(posedge sys_clk ornegedge ext_rst_n)

    if(!ext_rst_n) rst_r2 <=1'b1;

    else rst_r2 <= rst_r1;

 

assign pll_rst = rst_r2 &(~delay_flag);

 

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

//系统复位信号产生,低有效

//异步复位,同步释放

wire    rst_nr0;

reg    rst_nr1,rst_nr2;

wire    pll_locked;

assign    rst_nr0 = ext_rst_n & pll_locked & delay_flag;

always@(posedge pll_clk0 ornegedge rst_nr0)

begin

    if(!rst_nr0)

        rst_nr1 <=1'b0;

    else

        rst_nr1 <=1'b1;

end

 

always@(posedge pll_clk0 ornegedge rst_nr0)

begin

    if(!rst_nr0)

        rst_nr2 <=1'b0;

    else

        rst_nr2 <= rst_nr1;

end

 

assign    sys_rst_n = rst_nr2;

 

pll    pll_inst (

    .areset ( pll_rst ),

    .inclk0 ( sys_clk ),

    .c0 ( pll_clk0 ),

    .locked ( pll_locked )

    );

 

endmodule

 

Quartus II 12.0的RTL图

posted on 2013-08-25 23:06  NavyC  阅读(1161)  评论(0编辑  收藏  举报