对于全局时钟的管理,涉及到关于亚稳态的知识,大家可以上网搜索相关资料,这里不再赘述。亚稳态最简单的理解形式是无法判断是处于高电平状态还是处于低电平状态,这样会导致整个系统不稳定,会出现逻辑上的错误。
任何对时钟的管理形式,都是最大限度避免亚稳态情况的出现,从而提高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 : 770811496@qq.com
//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 : 770811496@qq.com
//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的ar