FPGA内部动态可重置PLL讲解(二)

来源:互联网 时间:2016-01-22

  对于全局时钟的管理,涉及到关于亚稳态的知识,大家可以上网搜索相关资料,这里不再赘述。亚稳态最简单的理解形式是无法判断是处于高电平状态还是处于低电平状态,这样会导致整个系统不稳定,会出现逻辑上的错误。

  任何对时钟的管理形式,都是最大限度避免亚稳态情况的出现,从而提高MTBF(平均无故障时间)。

  对于常用的异步复位形式(之前博客有提及到),如下:

always @(posedge clk or negedge rst_n)

if(!rst_n) begin

......

......

end

else begin

...........

...........

end

  上述得异步复位结构,正常情况下,寄存器的更新会伴随clk的上升沿进行更新,但是rst_n何时结束就不一定了,若是在寄存器的   建立时间 + 保持时间之外,那么输出是稳定的,但是若是在这之内,那么会导致输出的数据不一定正确。

  目前笔者搜索到的资料,较为合适的,能够最大限度降低亚稳态产生的逻辑电路,就是“异步复位,同步释放”。

module rstn_ (clk,rstn,rstn_out);

input clk ;

input rstn;

output rstn_out; //所要输出的复位信号

reg rst_out1,rst_out2;

always@(posedge clk or negedge rstn) begin

if(!rstn) begin

rst_out1 <= 1'b0;

rst_out2 <= 1'b0;

end

else begin

rst_out1 <= 1'b1;

rst_out2 <= rst_out1;

end

assign rstn_out = rst_out2;

endmodule

RTL视图为:

 

 

  通过两级缓存,使得rst_n也是伴随clk时钟下的使能信号。

  实际应用电路

  那么在实际应用中,由于电源等芯片转换需要一定的时间,FPGA稳定启动需要一定的时间,外围电路启动也需要一定的时间,人为的添加50ms的延时电路,使整个系统稳定。

  有PLL参与的时钟电路

  RTL视图

  Verilog 代码

  延时模块:

/*********************************************************

//description : this module will complete function of system init delay when power on

//author : raymon

//address : GDUT university of technology

//e-mail : [email protected]

//contact : 770811496

//time : 2015-1-31

**********************************************************/

`timescale 1ns/1ns

module system_init_delay

#(

parameter SYS_DELAY_TOP = 24'd2500000 //50ms system init delay

)

(

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

//global clock

input clk, //50MHz

input rst_n,

//system interface

output delay_done

);

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

//Delay 50ms for steady state when power on

reg [23:0] delay_cnt = 24'd0;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

delay_cnt <= 0;

else if(delay_cnt < SYS_DELAY_TOP - 1'b1)

delay_cnt <= delay_cnt + 1'b1;

else

delay_cnt <= SYS_DELAY_TOP - 1'b1;

end

assign delay_done = (delay_cnt == SYS_DELAY_TOP - 1'b1)? 1'b1 : 1'b0;

endmodule

  PLL

  此模块是正常的利用quartus II生成的IP核PLL,这里不再讲解。

  顶层模块:

/*********************************************************

//description : this module will complete function of system init delay when power on

//author : raymon

//address : GDUT university of technology

//e-mail : [email protected]

//contact : 770811496

//time : 2015-1-31

**********************************************************/

`timescale 1ns/1ns

module sys_control(clk, rst_n, clk_ref, sys_rst_n);

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

//globol clock

input clk; //50MHz

input rst_n; //reset

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

//synced signal

output clk_ref; //clock output

output sys_rst_n; //system reset

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

//component instantiation for system_delay

wire delay_done; //system init delay has done

system_init_delay

#(

.SYS_DELAY_TOP (24'd2500000)

)

u_system_init_delay

(

//global clock

.clk (clk),

.rst_n (1'b1), //It don't depend on rst_n when power up

//system interface

.delay_done (delay_done)

);

//注意这里因为PLL的areset复位信号是高电平复位,和平常使用的rst_n信号正好相反

wire pll_reset = ~delay_done; //pll of ip needs high level to reset

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

//using IP

wire locked;

sys_pll U1(

.areset(pll_reset),

.inclk0(clk),

.c0(clk_ref), //output 100MHz

.locked(locked)

);

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

//rst_n sync, only controlled by the main clk

reg rst_nr1, rst_nr2;

always @(posedge clk_ref)

begin

if(!rst_n)

begin

rst_nr1 <= 1'b0;

rst_nr2 <= 1'b0;

end

else

begin

rst_nr1 <= 1'b1;

rst_nr2 <= rst_nr1;

end

end

assign sys_rst_n = rst_nr2 & locked; //active low

endmodule

  无PLL参与的时钟电路

  RTL视图

 

  Verilog 代码

/*********************************************************

//description : this module will complete function of system init delay when power on

//author : raymon

//address : GDUT university of technology

//e-mail : [email protected]

//contact : 770811496

//time : 2015-1-31

**********************************************************/

`timescale 1ns/1ns

module system_init_delay

#(

parameter SYS_DELAY_TOP = 24'd2500000 //50ms system init delay

)

(

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

//global clock

input clk, //50MHz

input rst_n,

//system interface

output delay_done

);

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

//Delay 50ms for steady state when power on

reg [23:0] delay_cnt = 24'd0;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

delay_cnt <= 0;

else if(delay_cnt < SYS_DELAY_TOP - 1'b1)

delay_cnt <= delay_cnt + 1'b1;

else

delay_cnt <= SYS_DELAY_TOP - 1'b1;

end

assign delay_done = (delay_cnt == SYS_DELAY_TOP - 1'b1)? 1'b1 : 1'b0;

endmodule

 

  上述是延时部分的代码。

/*********************************************************

//description :this module will complete function of system init delay when power on

//author : raymon

//address : GDUT university of technology

//e-mail : [email protected]

//contact : 770811496

//time : 2015-1-31

**********************************************************/

`timescale 1ns/1ns

module system_ctrl(clk, rst_n, clk_ref, sys_rst_n);

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

//globol clock

input clk;

input rst_n;

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

//synced signal

output clk_ref; //clock output

output sys_rst_n; //system reset

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

//rst_n sync, only controlled by the main clk

reg rst_nr1, rst_nr2;

always @(posedge clk)

begin

if(!rst_n)

begin

rst_nr1 <= 1'b0;

rst_nr2 <= 1'b0;

end

else

begin

rst_nr1 <= 1'b1;

rst_nr2 <= rst_nr1;

end

end

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

//component instantiation for system_delay

wire delay_done; //system init delay has done

system_init_delay

#(

.SYS_DELAY_TOP (24'd2500000)

)

u_system_init_delay

(

//global clock

.clk (clk),

.rst_n (1'b1), //It don't depend on rst_n when power up

//system interface

.delay_done (delay_done)

);

assign clk_ref = clk;

assign sys_rst_n = rst_nr2 & delay_done; //active High

endmodule

 

上述是实现整个模块,可以查看RTL视图。

 

 

上面提到的最大限度降低亚稳态复位电路,在应用时,直接可以调用。目前已在多个工程中使用。

//=======================================================================

更多详细的资料下载可以登录笔者百度网盘:

网址:http://pan.baidu.com/s/1bnwLaqF

密码:fgtb

//=======================================================================

相关阅读:
Top