基于 Xilinx 提供的 BUFGCE 的门控时钟设计

1 BUFGCE 简介

1.1 Xilinx 文档原文

        与 BUFG 不同,BUFGCE 由一个时钟输入、一个时钟输出、一个时钟使能信号构成。这个原语基于 BUFGCTRL 并以一些引脚连接逻辑高电位和低电位。图 2-7 表明了 BUFGCE 和 BUFGCTRL 的关联。LOC 约束可用于手动布置 BUFGCE 和 BUFGCE_1 的位置。

        使能信号线路使用了 BUFGCTRL 的 CE 引脚,使能信号必须满足预设时间的要求。违反此预设时间会产生毛刺。

1.2 BUFGCE 的作用

        BUFGCE 是带有时钟使能信号的全局缓冲。它有一个输入时钟 I 、一个时钟使能信号端 CE 和一个输出时钟 O 。只有当 BUFGCE 的 CE 端有效 ( 高电平 ) 时,BUFGCE 才有输出。

1.3 BUFGCE 的延迟

        从图 2-8 可以看出,在 CE 为高时,O 端的输出信号会跟随 I 端的输入信号变化。

        当 CE 为高。I 端信号上升沿结束到达高电平的时刻,O 端信号的上升沿开始,经过相同的上升沿时间后到达高电平。同样,在 I 端信号下降沿结束到低电平的时刻,O 端信号的下降沿开始,经过相同的下降沿时间后到达低电平。也就是说,O 端信号跟随 I 端信号变化总会落后一个时钟沿的时间。

2 BUFG 设计实例

2.1 实例功能需求

        (1)系统时钟 100MHz ;

        (2)系统每秒进行一次数据的采集和处理,每次维持 10 ms ,其余时间空闲;

        (3)希望系统空闲时,关闭 100MHz 的工作时钟。

2.2 Verilog 代码

`timescale 1ns / 1ps

// 输入时钟频率 100MHz ,时钟周期 10ns 。
// 1s 内有 100_000_000 个输入时钟,计数器设置为 20 位不够,因此设置为 30 位(一般都是整数位)。
// 10ms 内有 1_000_000 个输入时钟,计数器设置为 20 位。


module top(
    input               clk         ,
    input               rst_n       ,

    output      reg     en_10ms     ,
    output              clk_out                                         // 输出波形
    );  

// 设置 1s 和 10ms 的计数器
reg     [19:0]  cnt_10ms   ;                                    // 1s       计数器
reg     [29:0]  cnt_1s     ;                                    // 10ms     计数器

localparam CNT_PERIOD_10ms  =   1_000_000   ;                   // cnt_10ms  的最大值
localparam CNT_PERIOD_1s    = 100_000_000   ;                   // cnt_1s    的最大值

// cnt_10ms 的初始化和赋值
// cnt_10ms 从 0 到 999_999 。到达 999_999 后,在下个时钟复位
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        cnt_10ms = 20'd0;
    else begin
        if(cnt_10ms < CNT_PERIOD_10ms -1)
            cnt_10ms = cnt_10ms + 1'b1;
        else
            cnt_10ms = 20'd0;
    end
end

// cnt_1s 的初始化和赋值
// cnt_1s 从 0 到 99_999_999 。到达 99_999_999 后,在下个时钟复位
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        cnt_1s = 30'd0;
    else begin
        if(cnt_1s < CNT_PERIOD_1s -1)
            cnt_1s = cnt_1s + 1'b1;
        else
            cnt_1s = 30'd0;
    end
end

// 设置使能信号
// 因为只在 10ms 内产生输出波形。所以在 1s 内,使能信号在 10ms 内为高电平有效,剩下的时间均为低电平。
always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        en_10ms = 1'b0;
    else begin
        if(cnt_1s < CNT_PERIOD_10ms)
            en_10ms = 1'b1;
        else
            en_10ms = 1'b0;

    end
end



BUFGCE BUFGCE_inst (
      . O(          clk_out),                // 1-bit output: Clock output                  输出信号
      .CE(          en_10ms),                // 1-bit input: Clock enable input for I0      输入使能信号
      . I(              clk)                 // 1-bit input: Primary clock                  输入信号时钟
);

endmodule

2.3 TestBench 代码

`timescale 1ns / 1ps

module tb_top;

reg         clk ;
reg       rst_n ;
wire    en_10ms ;
wire    clk_out ;

localparam CLK_PERIOD = 10;

top top_1( .clk(clk), .rst_n(rst_n), .en_10ms(en_10ms), .clk_out(clk_out) );

initial begin
    clk = 0;

    rst_n = 1;
    #1;
    rst_n = 0;
    #(CLK_PERIOD*3);
    rst_n = 1; 
end

always #(CLK_PERIOD/2) clk = ~clk;

initial begin
    @(posedge clk);
    @(posedge rst_n);
    
    repeat(100_000_000*3) begin
        @(posedge clk);
    end
end

endmodule

3 出现的问题

        仿真时出现错误,在修改了顶层模块的例化名后仍无法解决。

        目前无法仿真。

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值