分频时钟、使能时钟、门控时钟的概念和使用

一.概述

        FPGA的时钟和时序以及功能息息相关,下面将介绍分频时钟,使能时钟以及门控时钟。

二.时钟设计介绍

1.分频时钟

        有些时候设计需要将主时钟进行分频以降低频率使用,对于有足够PLL和MMCM资源的FPGA,可以使用PLL或MMCM进行分频,但是没有这些资源的FPGA要想降低时钟频率就得靠逻辑来完成。以下是一个将主时钟4分频的代码。

module clock_div(
    input clk_in,
    input rst,
    output clk_div_out
    );

reg [1:0] cnt;
always @(posedge clk_in or posedge rst) begin
    if (rst) begin
        // reset
        cnt <= 2'b0;
    end
    else if (cnt == 1) begin
        cnt <= 0;
    end
    else cnt <= cnt+1;
end

reg clk_div;
always @(posedge clk_in or posedge rst)begin
    if(rst)begin
        clk_div <= 1'b0;
    end
    else if(cnt == 1)begin
        clk_div <= ~clk_div;
    end
    else clk_div <= clk_div;
end

assign clk_div_out = clk_div;
endmodule

         该代码块会产生一个4分频的时钟,但是不介意产生这样一个时钟给其他模块用。原因有以下两点。

(1)clk_div由逻辑门(反相器)产生,会有毛刺。

(2)clk_div这个触发器在clk_in时钟有效到输出clk_div信号是有着Tco的时间延迟,这样会让clk_div和clk_in产生较大的相移,然后让clk_div去驱动其他模块,这种做法在设计中会产生较大的问题。

(3)引入多时钟域问题。

2.使能时钟

        使能时钟以分频时钟为基础,只不过不产生反相器,生成的信号en不作为时钟去驱动其他模块,而是作为使能信号。如下图:

 

项目中也用到了使能时钟,比如288位的寄存器,由cpu通过localbus总线32位写下来,那么可以通过cnt计数,cnt为9时(288位被写完)产生一个使能信号,将此288位寄存器给到RAM的输入。网上找了个类似的代码如下:

        这是在某系统中,前级数据输入位宽为8位,而后级的数据输出位宽为32,我们需要将8bit数据转换为32bit,由于后级的处理位宽为前级的4倍,因此后级处理的时钟频率也将下降为前级的1/4,若不使用时钟使能,则要将前级的时钟进行4分频来作后级处理的时钟。这种设计方法会引入新的时钟域,处理上需要采取多时钟域处理的方式,因而在设计复杂度提高的同时系统的可靠性也将降低。为了避免以上问题,我们采用了时钟使能以减少设计复杂度。

module clk_en(clk, rst_n, data_in, data_out);  
input clk;  
input rst_n;  
input [7:0] data_in;  
output [31:0] data_out;  
 
reg [31:0] data_out;  
reg [31:0] data_shift;  
reg [1:0] cnt;  
reg clken;  
 
always @(posedge clk or negedge rst_n)  
begin  
 if (!rst_n)  
      cnt <= 0;  
 else 
      cnt <= cnt + 1;  
end  
 
always @(posedge clk or negedge rst_n)  
begin  
 if (!rst_n)  
      clken <= 0;  
 else if (cnt == 2'b01)  
      clken <= 1;  
 else 
      clken <= 0;  
end  
 
always @(posedge clk or negedge rst_n)  
begin  
 if (!rst_n)  
      data_shift <= 0;  
 else 
      data_shift <= {data_shift[23:0],data_in};  
end  
 
always @(posedge clk or negedge rst_n)  
begin  
 if (!rst_n)  
      data_out <= 0;  
 else if (clken == 1'b1)  
      data_out <= data_shift;  
end  
 
endmodule 

        可以看到,在上面代码中,也使用到了计数器,但是仅仅是用于产生一个时钟使能脉冲信号,只持续一个clk。而clk_en也没有直接用于驱动其他电路,在整个系统中,所有的时钟都是clk,这样就不会有相移过大以及多时钟域的问题存在了,而且也不会出现由于毛刺带来的影响。

3.门控时钟

        门控时钟是通过一个控制信号来控制时钟的开和关。

        如果单纯从功能实现来看,使用使能时钟替代门控时钟是一个不错的选择;但是使能时钟在使能信号关闭时,时钟信号仍在工作,它无法像门控时钟那样降低系统功耗。

        这样的门控时钟有两个问题:

        (1)由于门控信号是一个异步信号,会产生亚稳态的问题。具体见亚稳态的跨时钟处理(一)的什么情况下会产生亚稳态。

        (2)一般情况下,门控时钟只需要一个与门,但是如果有附加的组合逻辑,输出信号将会有毛刺。

        用打拍的方式有效的抑制了亚稳态可能产生的危害。而且如果门控信号gating signal有附加的组合逻辑,也会因为D触发器的D输入端对毛刺信号不敏感的特点,将毛刺有效滤除掉。

Note:

        对于输出的时钟信号或复位信号,最好让它走全局时钟网络,从而减小时钟网络延时,提升系统时序性能。

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值