作者:子墨祭,文章来源:CSDN博客
本文来自于《深入浅出玩转FPGA》的读书笔记整理,我只是知识的搬运工。
前言
时钟信号在很大程度上决定了整个设计的性能和可靠性,尽量避免使用FPGA内部逻辑产生的时钟,因为它很容易导致功能或时序出现问题。内部逻辑(组合逻辑)产生的时钟容易出现毛刺,影响设计的功能实现;组合逻辑固有的延时也容易导致时序问题。
一、内部逻辑产生的时钟
若使用组合逻辑的输出作为时钟信号或异步复位信号,设计者必须对有可能出现的问题采取必要的预防措施。我们知道,在正常的同步设计中,一个时钟一个节拍的数据流控制能够保证系统持续稳定的工作。但是,组合逻辑产生的时钟不可避免地会有毛刺出现,如果此时输入端口的数据正处于变化过程,那么它将违反建立和保持时间要求,从而影响后续电路的输出状态,甚至导致整个系统运行失败。
对于必须采用内部逻辑作时钟或者复位信号的应用,也还是有解决办法的。思路并不复杂,和异步复位、同步释放的原理是一样的。在输出时钟或者复位信号之前,再用系统专用时钟信号(通常指外部晶振输入时钟或者PLL处理后的时钟信号)打一拍,从而避免组合逻辑直接输出,达到同步处理的效果。对于输出的时钟信号或复位信号,最好让它走全局时钟网络,从而减小时钟网络延时,提升系统时序性能。
内部逻辑产生的时钟处理如下:
二、分频时钟与使能时钟
设计中往往需要用到主时钟的若干分频信号作为时钟,即分频时钟。可别小看这个所谓的分频时钟,简简单单不加处理的乱用时钟那就叫时钟满天飞,是很不好的设计风格。言归正传,如果设计中确实需要用到系统主时钟的分频信号来降低频率时,该如何处理呢?
对于资源较丰富的FPGA,一般都有内嵌的多个PLL或者DLL专门用于时钟管理,利用它们就可以很容易地达到多个时钟的设计,输出时钟能够配置成设计者期望的不同频率和相位差(相对于输入时钟),这样的时钟分频是最稳定的。但是对于某些无法使用PLL或者DLL资源的器件又该怎么办呢?推荐使用“使能时钟”进行设计,在“使能时钟”设计中只使用原有的时钟,让分频信号作为使能信号来用。
下面举一个实例来说明如何进行使能时钟的设计,该设计需要得到一个50MHz钟的5分频信号即10MHz。
input clk; //50MHz时钟信号
input rst n;
reg[2:0]ent;
wire en; //使能信号,高电平有效
//5分频计数0~4
always@( posedge clk or negedge rst _n)begin
if(!rst _n) ent<=3'd0;
else if(ent<3'd4) ent<=ent+1b1;
else ent<=3'd0;
end
assign en=(cnt==3'd4);//每5个时钟周期产生1个时钟周期高脉冲
//使用使能时钟
always@( posedge clk or negedge rst _n)begin
if(!rst _n)…;
else if(en)…;
...
end
如下图所示,使能信号不直接作为时钟使用,而是作为数据输入端的选择信号,这避免了使用分频时钟。
三、门控时钟
组合逻辑中多用门控时钟,一般驱动门控时钟的逻辑都是只包含一个与门(或门).如其他的附加逻辑,容易因竞争产生不希望的毛刺。如图a所示,门控时钟通过一个使号控制时钟的开或者关。当系统不工作时可以关闭时钟,整个系统就处于非激活状态,这种够在某种程度上降低系统功耗。
图a:门控时钟
然而,使用门控时钟并不符合同步设计的思想,它可能会影响系统设计的实现和验证。单纯从功能实现来看,使用使能时钟替代门控时钟是一个不错的选择;但是使能时钟在使能信号关闭时,时钟信号仍然在工作,它无法像门控时钟那样降低系统功耗。
是否有一种设计方法既可以降低系统功耗,又能够稳定可靠的替代门控时钟呢?Altera就提出了一种解决方案,且待我慢慢道来。如图b所示,对于上升沿有效的系统时钟cì k,它的下降沿先把门控信号(gating signal)打一拍,然后再用这个使能信号(enable)和系统时钟(clk)相与后作为后续电路的门控时钟。
图b:推荐的门控时钟
这样的门控时钟电路很好地解决了组合逻辑常见的一些问题。它避免了毛刺的出现,同时也有效抑制了亚稳态可能带来的危害。但是从另一个方面来说,如果这个设计的系统时钟(clk)占空比不是很稳定,或者输出的使能信号(enable)与时钟信号(clk)的逻辑过于复杂(不止这个例子中一个与门那么简单),那么它也会带来一些功能或时序上的问题。总的来说,只要设计者控制好这个设计中时钟的占空比和门控逻辑复杂度,它还是比图a给出的门控时钟方案更可行。
下一篇,我们聊聊复位设计。异步复位,同步释放大家都很熟悉了,那么xilinx官方推荐的复位是什么样的呢?